diff --git a/pom.xml b/pom.xml
index af74d5a..36ff7da 100644
--- a/pom.xml
+++ b/pom.xml
@@ -102,7 +102,12 @@
junit
test
-
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/security/SecurityConfig.java b/src/main/java/com/hideyoshi/backendportfolio/base/security/config/SecurityConfig.java
similarity index 98%
rename from src/main/java/com/hideyoshi/backendportfolio/base/security/SecurityConfig.java
rename to src/main/java/com/hideyoshi/backendportfolio/base/security/config/SecurityConfig.java
index 1e7196e..655d51f 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/security/SecurityConfig.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/security/config/SecurityConfig.java
@@ -1,4 +1,4 @@
-package com.hideyoshi.backendportfolio.base.security;
+package com.hideyoshi.backendportfolio.base.security.config;
import com.hideyoshi.backendportfolio.base.config.RestAuthenticationEntryPointConfig;
import com.hideyoshi.backendportfolio.base.security.filter.CustomAuthenticationFilter;
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/security/model/AuthDTO.java b/src/main/java/com/hideyoshi/backendportfolio/base/security/model/AuthDTO.java
new file mode 100644
index 0000000..710ae06
--- /dev/null
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/security/model/AuthDTO.java
@@ -0,0 +1,55 @@
+package com.hideyoshi.backendportfolio.base.security.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.hideyoshi.backendportfolio.base.user.entity.Provider;
+import com.hideyoshi.backendportfolio.base.user.entity.Role;
+import com.hideyoshi.backendportfolio.base.user.model.TokenDTO;
+import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@Builder
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class AuthDTO implements Serializable {
+
+ private Long id;
+
+ private String name;
+
+ private String email;
+
+ private String username;
+
+ private String profilePictureUrl;
+
+ private List roles;
+
+ private Provider provider;
+
+ private TokenDTO accessToken;
+
+ private TokenDTO refreshToken;
+
+ public AuthDTO(UserDTO user, TokenDTO accessToken, TokenDTO refreshToken) {
+ this.id = user.getId();
+ this.name = user.getName();
+ this.email = user.getEmail();
+ this.username = user.getUsername();
+ this.roles = user.getRoles();
+ this.provider = user.getProvider();
+ this.profilePictureUrl = user.getProfilePictureUrl();
+
+ this.accessToken = accessToken;
+ this.refreshToken = refreshToken;
+ }
+
+}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/GithubOAuthMap.java b/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/GithubOAuthMap.java
index 7f27aa4..e83095a 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/GithubOAuthMap.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/GithubOAuthMap.java
@@ -15,6 +15,11 @@ public class GithubOAuthMap implements OAuthMap {
return oAuth2User.getAttribute("login");
}
+ @Override
+ public String getProfilePicture() {
+ return this.oAuth2User.getAttribute("avatar_url");
+ }
+
@Override
public Provider getProvider() {
return Provider.GITHUB;
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/GoogleOAuthMap.java b/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/GoogleOAuthMap.java
index 9aa4ffe..5f90fdb 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/GoogleOAuthMap.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/GoogleOAuthMap.java
@@ -8,11 +8,16 @@ import org.springframework.security.oauth2.core.user.OAuth2User;
@AllArgsConstructor
public class GoogleOAuthMap implements OAuthMap {
- private OAuth2User oauthUser;
+ private OAuth2User oAuth2User;
@Override
public String getPrincipal() {
- return this.oauthUser.getAttribute("given_name");
+ return this.oAuth2User.getAttribute("given_name");
+ }
+
+ @Override
+ public String getProfilePicture() {
+ return this.oAuth2User.getAttribute("picture");
}
@Override
@@ -20,5 +25,4 @@ public class GoogleOAuthMap implements OAuthMap {
return Provider.GOOGLE;
}
-
}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMap.java b/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMap.java
index ff607c3..9a770b6 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMap.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMap.java
@@ -7,6 +7,8 @@ public interface OAuthMap {
String getPrincipal();
+ String getProfilePicture();
+
Provider getProvider();
}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMapEnum.java b/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMapper.java
similarity index 71%
rename from src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMapEnum.java
rename to src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMapper.java
index 6e63b00..7a0db8d 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMapEnum.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/security/oauth/mapper/OAuthMapper.java
@@ -1,8 +1,9 @@
package com.hideyoshi.backendportfolio.base.security.oauth.mapper;
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
+import lombok.Getter;
-public enum OAuthMapEnum {
+public enum OAuthMapper {
GOOGLE(GoogleOAuthMap.class, Provider.GOOGLE),
@@ -10,9 +11,10 @@ public enum OAuthMapEnum {
private final Class oAuthMap;
+ @Getter
private final Provider provider;
- private OAuthMapEnum(Class oAuthMap, Provider provider) {
+ private OAuthMapper(Class oAuthMap, Provider provider) {
this.oAuthMap = oAuthMap;
this.provider = provider;
}
@@ -21,12 +23,8 @@ public enum OAuthMapEnum {
return oAuthMap;
}
- public Provider getProvider() {
- return provider;
- }
-
- public static OAuthMapEnum byValue(String name) {
- for (OAuthMapEnum e : values()) {
+ public static OAuthMapper byValue(String name) {
+ for (OAuthMapper e : values()) {
if (e.getProvider().getName().equals(name)) {
return e;
}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthService.java b/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthService.java
index 5a8561c..4f11ecb 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthService.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthService.java
@@ -1,6 +1,7 @@
package com.hideyoshi.backendportfolio.base.security.service;
import com.auth0.jwt.algorithms.Algorithm;
+import com.hideyoshi.backendportfolio.base.security.model.AuthDTO;
import com.hideyoshi.backendportfolio.base.user.model.TokenDTO;
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -22,16 +23,18 @@ public interface AuthService {
UsernamePasswordAuthenticationToken verifyAccessToken(String authorizationHeader);
- UserDTO refreshAccessToken(String refreshToken, HttpServletRequest request, HttpServletResponse response);
+ AuthDTO refreshAccessToken(String refreshToken, HttpServletRequest request, HttpServletResponse response);
- UserDTO signupUser(@Valid UserDTO user, HttpServletRequest request);
+ AuthDTO signupUser(@Valid UserDTO user, HttpServletRequest request);
- UserDTO generateUserWithTokens(UserDTO user, HttpServletRequest request);
+ AuthDTO generateUserWithTokens(UserDTO user, HttpServletRequest request);
- UserDTO processOAuthPostLogin(@Valid UserDTO user, HttpServletRequest request);
+ AuthDTO processOAuthPostLogin(@Valid UserDTO user, HttpServletRequest request);
void loginUser(HttpServletRequest request, HttpServletResponse response, @Valid UserDTO user) throws IOException;
void loginOAuthUser(HttpServletRequest request, HttpServletResponse response, OAuth2User user) throws IOException;
+ UserDTO getLoggedUser();
+
}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthServiceImpl.java b/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthServiceImpl.java
index 1d0bcd6..9b8cd41 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthServiceImpl.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthServiceImpl.java
@@ -5,13 +5,15 @@ import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.hideyoshi.backendportfolio.base.security.model.AuthDTO;
import com.hideyoshi.backendportfolio.base.security.oauth.mapper.OAuthMap;
-import com.hideyoshi.backendportfolio.base.security.oauth.mapper.OAuthMapEnum;
+import com.hideyoshi.backendportfolio.base.security.oauth.mapper.OAuthMapper;
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
import com.hideyoshi.backendportfolio.base.user.entity.Role;
import com.hideyoshi.backendportfolio.base.user.model.TokenDTO;
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
import com.hideyoshi.backendportfolio.base.user.service.UserService;
+import com.hideyoshi.backendportfolio.microservice.storageService.service.StorageService;
import com.hideyoshi.backendportfolio.util.exception.BadRequestException;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
@@ -21,6 +23,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerExceptionResolver;
@@ -55,6 +58,8 @@ public class AuthServiceImpl implements AuthService {
private final UserService userService;
+ private final StorageService storageService;
+
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@@ -98,7 +103,7 @@ public class AuthServiceImpl implements AuthService {
TokenDTO accessToken = generateAccessToken(user, algorithm, request);
TokenDTO refreshToken = generateRefreshToken(user, algorithm, request);
- HashMap tokens = new HashMap<>();
+ HashMap tokens = new HashMap<>();
tokens.put("accessToken", accessToken);
tokens.put("refreshToken", refreshToken);
@@ -108,54 +113,81 @@ public class AuthServiceImpl implements AuthService {
@Override
public UsernamePasswordAuthenticationToken verifyAccessToken(String authorizationHeader) {
- if (authorizationHeader.startsWith(AUTHORIZATION_TYPE_STRING)) {
-
- String authorizationToken = authorizationHeader.substring(AUTHORIZATION_TYPE_STRING.length());
- Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET.getBytes());
-
- JWTVerifier verifier = JWT.require(algorithm).build();
- DecodedJWT decodedJWT = verifier.verify(authorizationToken);
-
- String username = decodedJWT.getSubject();
- String[] roles = decodedJWT.getClaim("roles").asArray(String.class);
-
- Collection authorities = new ArrayList<>();
- stream(roles).forEach(role -> {
- authorities.add(new SimpleGrantedAuthority(role));
- });
- return new UsernamePasswordAuthenticationToken(username, null, authorities);
+ if (!authorizationHeader.startsWith(AUTHORIZATION_TYPE_STRING)) {
+ return null;
}
- return null;
+
+ String authorizationToken = authorizationHeader.substring(AUTHORIZATION_TYPE_STRING.length());
+ Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET.getBytes());
+
+ JWTVerifier verifier = JWT.require(algorithm).build();
+ DecodedJWT decodedJWT = verifier.verify(authorizationToken);
+
+ String username = decodedJWT.getSubject();
+ String[] roles = decodedJWT.getClaim("roles").asArray(String.class);
+
+ Collection authorities = new ArrayList<>();
+ stream(roles).forEach(role -> {
+ authorities.add(new SimpleGrantedAuthority(role));
+ });
+
+ return new UsernamePasswordAuthenticationToken(username, null, authorities);
}
@Override
- public UserDTO refreshAccessToken(String refreshToken, HttpServletRequest request, HttpServletResponse response) {
+ public AuthDTO generateUserWithTokens(UserDTO user, HttpServletRequest request) {
- if (Objects.nonNull(refreshToken)) {
+ Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET.getBytes());
- Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET.getBytes());
+ HashMap tokens = this.generateTokens(user, algorithm, request);
- JWTVerifier verifier = JWT.require(algorithm).build();
- DecodedJWT decodedJWT = verifier.verify(refreshToken);
+ HttpSession httpSession = request.getSession();
+ AuthDTO authObject = new AuthDTO(user, tokens.get("accessToken"), tokens.get("refreshToken"));
- UserDTO user = this.userService.getUser(decodedJWT.getSubject());
+ httpSession.setAttribute("user", authObject);
- if (Objects.nonNull(user)) {
+ return authObject;
+ }
- HttpSession httpSession = request.getSession();
- UserDTO authenticatedUser = user.toResponse(
- this.generateAccessToken(user, algorithm, request),
- new TokenDTO(
- refreshToken,
- decodedJWT.getExpiresAt()
- )
- );
- httpSession.setAttribute("user", authenticatedUser);
+ @Override
+ public AuthDTO signupUser(@Valid UserDTO user, HttpServletRequest request) {
- return authenticatedUser;
- }
+ user.setProvider(Provider.LOCAL);
- } else {
+ UserDTO authenticatedUser = this.userService.saveUser(user);
+ authenticatedUser.setProfilePictureUrl(
+ this.storageService.getFileUrl(authenticatedUser.getUsername(), "profile")
+ .getPresignedUrl()
+ );
+
+ return this.generateUserWithTokens(
+ authenticatedUser,
+ request
+ );
+
+ }
+
+ @Override
+ public void loginUser(HttpServletRequest request, HttpServletResponse response, @Valid UserDTO user) throws IOException {
+ user.setProfilePictureUrl(
+ this.storageService.getFileUrl(user.getUsername(), "profile")
+ .getPresignedUrl()
+ );
+
+ AuthDTO authObject = this.generateUserWithTokens(
+ user,
+ request
+ );
+
+ response.setContentType(APPLICATION_JSON_VALUE);
+ new ObjectMapper()
+ .writeValue(response.getOutputStream(), authObject);
+ }
+
+ @Override
+ public AuthDTO refreshAccessToken(String refreshToken, HttpServletRequest request, HttpServletResponse response) {
+
+ if (!Objects.nonNull(refreshToken)) {
resolver.resolveException(
request,
response,
@@ -163,38 +195,35 @@ public class AuthServiceImpl implements AuthService {
new BadRequestException("Invalid Refresh Token. Please authenticate first.")
);
}
- return null;
- }
-
- @Override
- public UserDTO signupUser(@Valid UserDTO user, HttpServletRequest request) {
-
- user.setProvider(Provider.LOCAL);
-
- return this.generateUserWithTokens(
- this.userService.saveUser(user),
- request
- );
-
- }
-
- @Override
- public UserDTO generateUserWithTokens(UserDTO user, HttpServletRequest request) {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET.getBytes());
- HashMap tokens = this.generateTokens(user, algorithm, request);
+ JWTVerifier verifier = JWT.require(algorithm).build();
+ DecodedJWT decodedJWT = verifier.verify(refreshToken);
+
+ UserDTO user = this.userService.getUser(decodedJWT.getSubject());
+ user.setProfilePictureUrl(
+ this.storageService.getFileUrl(user.getUsername(), "profile")
+ .getPresignedUrl()
+ );
HttpSession httpSession = request.getSession();
- UserDTO userAuthenticated = user.toResponse(tokens.get("accessToken"), tokens.get("refreshToken"));
+ AuthDTO authenticatedUser = new AuthDTO(
+ user,
+ this.generateAccessToken(user, algorithm, request),
+ new TokenDTO(
+ refreshToken,
+ decodedJWT.getExpiresAt()
+ )
+ );
+ httpSession.setAttribute("user", authenticatedUser);
- httpSession.setAttribute("user", userAuthenticated);
+ return authenticatedUser;
- return userAuthenticated;
}
@Override
- public UserDTO processOAuthPostLogin(@Valid UserDTO user, HttpServletRequest request) {
+ public AuthDTO processOAuthPostLogin(@Valid UserDTO user, HttpServletRequest request) {
if (Objects.nonNull(user.getId())) {
this.userService.alterUser(user.getId(), user);
@@ -203,37 +232,48 @@ public class AuthServiceImpl implements AuthService {
}
return this.generateUserWithTokens(user, request);
-
}
@Override
- public void loginUser(HttpServletRequest request, HttpServletResponse response, @Valid UserDTO user) throws IOException {
+ public void loginOAuthUser(HttpServletRequest request,
+ HttpServletResponse response,
+ OAuth2User oauthUser) throws IOException {
- UserDTO authenticatedUser = this.generateUserWithTokens(
- user,
+ String clientId = this.getClientFromUrl(request.getRequestURL().toString());
+
+ OAuthMap oauthMap = this.generateOAuthMap(clientId, oauthUser);
+
+ AuthDTO authObject = this.processOAuthPostLogin(
+ this.generateUserFromAuthUser(oauthMap, oauthUser),
request
);
response.setContentType(APPLICATION_JSON_VALUE);
new ObjectMapper()
- .writeValue(response.getOutputStream(), authenticatedUser);
+ .writeValue(response.getOutputStream(), authObject);
}
- public void loginOAuthUser(HttpServletRequest request,
- HttpServletResponse response,
- OAuth2User oauthUser) throws IOException {
+ @Override
+ public UserDTO getLoggedUser() {
+ String username = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ return userService.getUser(username);
+ }
- String[] url = request.getRequestURL().toString().split("/");
- String clientId = url[url.length-1];
+ private String getClientFromUrl(String url) {
+ String[] urlPartition = url.split("/");
+ return urlPartition[urlPartition.length - 1];
+ }
- OAuthMap oauthMap = null;
+ private OAuthMap generateOAuthMap(String clientId, OAuth2User oauthUser) {
try {
- oauthMap = (OAuthMap) OAuthMapEnum.byValue(clientId).getMap()
+ return (OAuthMap) OAuthMapper.byValue(clientId).getMap()
.getDeclaredConstructor(OAuth2User.class).newInstance(oauthUser);
} catch (Exception e) {
- throw new BadRequestException("No Such Provider");
+ throw new BadRequestException("Unsupported OAuth Client.");
}
+ }
+ private UserDTO generateUserFromAuthUser(OAuthMap oauthMap, OAuth2User oauthUser) {
UserDTO user = null;
try {
user = this.userService.getUser(oauthMap.getPrincipal());
@@ -246,16 +286,9 @@ public class AuthServiceImpl implements AuthService {
.provider(oauthMap.getProvider())
.build();
}
+ user.setProfilePictureUrl(oauthMap.getProfilePicture());
- UserDTO authenticatedUser = this.processOAuthPostLogin(
- user,
- request
- );
-
- response.setContentType(APPLICATION_JSON_VALUE);
- new ObjectMapper()
- .writeValue(response.getOutputStream(), authenticatedUser);
-
+ return user;
}
}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/session/api/SessionController.java b/src/main/java/com/hideyoshi/backendportfolio/base/session/api/SessionController.java
index 580c864..f856a80 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/session/api/SessionController.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/session/api/SessionController.java
@@ -1,5 +1,6 @@
package com.hideyoshi.backendportfolio.base.session.api;
+import com.hideyoshi.backendportfolio.base.security.model.AuthDTO;
import com.hideyoshi.backendportfolio.base.session.service.SessionManagerService;
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
import lombok.RequiredArgsConstructor;
@@ -19,7 +20,7 @@ public class SessionController {
private final SessionManagerService sessionManagerService;
@GetMapping(path = "/validate")
- public ResponseEntity validateCurrentSession(HttpSession session) {
+ public ResponseEntity validateCurrentSession(HttpSession session) {
return ResponseEntity.ok(this.sessionManagerService.validateSession(session));
}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/session/service/SessionManagerService.java b/src/main/java/com/hideyoshi/backendportfolio/base/session/service/SessionManagerService.java
index 6136149..add7bac 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/session/service/SessionManagerService.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/session/service/SessionManagerService.java
@@ -1,12 +1,12 @@
package com.hideyoshi.backendportfolio.base.session.service;
-import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
+import com.hideyoshi.backendportfolio.base.security.model.AuthDTO;
import javax.servlet.http.HttpSession;
public interface SessionManagerService {
- UserDTO validateSession(HttpSession session);
+ AuthDTO validateSession(HttpSession session);
void destroySession(HttpSession session);
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/session/service/SessionManagerServiceImpl.java b/src/main/java/com/hideyoshi/backendportfolio/base/session/service/SessionManagerServiceImpl.java
index 36d8542..c21ee03 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/session/service/SessionManagerServiceImpl.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/session/service/SessionManagerServiceImpl.java
@@ -1,30 +1,19 @@
package com.hideyoshi.backendportfolio.base.session.service;
-import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
+import com.hideyoshi.backendportfolio.base.security.model.AuthDTO;
import com.hideyoshi.backendportfolio.base.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpSession;
-import java.util.Objects;
@Service
@RequiredArgsConstructor
public class SessionManagerServiceImpl implements SessionManagerService {
- private final UserService userService;
-
@Override
- public UserDTO validateSession(HttpSession session) {
-
- UserDTO sessionObjects = (UserDTO) session.getAttribute("user");
-
- if (Objects.nonNull(sessionObjects)) {
- return this.userService.getUser(sessionObjects.getUsername())
- .toResponse(sessionObjects.getAccessToken(), sessionObjects.getRefreshToken());
- }
-
- return null;
+ public AuthDTO validateSession(HttpSession session) {
+ return (AuthDTO) session.getAttribute("user");
}
@Override
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/user/api/UserController.java b/src/main/java/com/hideyoshi/backendportfolio/base/user/api/UserController.java
index ef5f90c..e95c29a 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/user/api/UserController.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/user/api/UserController.java
@@ -1,28 +1,28 @@
package com.hideyoshi.backendportfolio.base.user.api;
+import com.hideyoshi.backendportfolio.base.security.model.AuthDTO;
import com.hideyoshi.backendportfolio.base.security.service.AuthService;
import com.hideyoshi.backendportfolio.base.user.model.TokenDTO;
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
import com.hideyoshi.backendportfolio.base.user.service.UserService;
+import com.hideyoshi.backendportfolio.microservice.storageService.enums.FileTypeEnum;
+import com.hideyoshi.backendportfolio.microservice.storageService.model.StorageServiceDownloadResponse;
+import com.hideyoshi.backendportfolio.microservice.storageService.model.StorageServiceUploadResponse;
+import com.hideyoshi.backendportfolio.microservice.storageService.service.StorageService;
import com.hideyoshi.backendportfolio.util.guard.UserResourceGuard;
import com.hideyoshi.backendportfolio.util.guard.UserResourceGuardEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
-import java.io.IOException;
import java.net.URI;
-import java.security.Provider;
import java.util.List;
@Log4j2
@@ -36,6 +36,8 @@ public class UserController {
private final AuthService authService;
+ private final StorageService storageService;
+
@GetMapping
@UserResourceGuard(accessType = UserResourceGuardEnum.ADMIN_USER)
public ResponseEntity> getUsers() {
@@ -44,7 +46,7 @@ public class UserController {
@PostMapping("/signup")
@UserResourceGuard(accessType = UserResourceGuardEnum.OPEN)
- public ResponseEntity signupUser(@RequestBody @Valid UserDTO user, HttpServletRequest request) {
+ public ResponseEntity signupUser(@RequestBody @Valid UserDTO user, HttpServletRequest request) {
URI uri = URI.create(
ServletUriComponentsBuilder
.fromCurrentContextPath()
@@ -55,20 +57,13 @@ public class UserController {
@PostMapping("/login/refresh")
@UserResourceGuard(accessType = UserResourceGuardEnum.OPEN)
- public ResponseEntity refreshAccessToken(
+ public ResponseEntity refreshAccessToken(
@RequestBody @Valid TokenDTO refreshToken,
HttpServletRequest request,
HttpServletResponse response) {
return ResponseEntity.ok(this.authService.refreshAccessToken(refreshToken.getToken(), request, response));
}
- @GetMapping("/login/callback")
- @UserResourceGuard(accessType = UserResourceGuardEnum.OPEN)
- public void oauthCallback(HttpServletResponse response) throws IOException {
- log.info("Teste");
- response.sendRedirect("http://localhost:4200");
- }
-
@DeleteMapping("/delete/{id}")
@UserResourceGuard(accessType = UserResourceGuardEnum.SAME_USER)
public ResponseEntity deleteUser(@PathVariable("id") Long id) {
@@ -76,4 +71,27 @@ public class UserController {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
+ @PostMapping("/profile-picture")
+ @UserResourceGuard(accessType = UserResourceGuardEnum.USER)
+ public StorageServiceUploadResponse addProfilePicture(
+ @RequestParam FileTypeEnum fileType
+ ) {
+ UserDTO user = this.authService.getLoggedUser();
+ return this.storageService.getNewFileUrl(
+ user.getUsername(),
+ "profile",
+ fileType
+ );
+ }
+
+ @PostMapping("/profile-picture/proccess")
+ @UserResourceGuard(accessType = UserResourceGuardEnum.USER)
+ public void processProfilePicture() {
+ UserDTO user = this.authService.getLoggedUser();
+ this.storageService.processFile(
+ user.getUsername(),
+ "profile"
+ );
+ }
+
}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/user/model/TokenDTO.java b/src/main/java/com/hideyoshi/backendportfolio/base/user/model/TokenDTO.java
index c293e12..e290f56 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/user/model/TokenDTO.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/user/model/TokenDTO.java
@@ -1,6 +1,8 @@
package com.hideyoshi.backendportfolio.base.user.model;
import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.*;
import javax.validation.constraints.NotNull;
@@ -10,6 +12,8 @@ import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
public class TokenDTO implements Serializable {
@NotNull(message = "Invalid AccessToken. Please Authenticate first.")
diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/user/model/UserDTO.java b/src/main/java/com/hideyoshi/backendportfolio/base/user/model/UserDTO.java
index 53d7ffc..9e4ce86 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/base/user/model/UserDTO.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/base/user/model/UserDTO.java
@@ -53,9 +53,7 @@ public class UserDTO implements UserDetails {
@Size(min=1)
private List roles;
- private TokenDTO accessToken;
-
- private TokenDTO refreshToken;
+ private String profilePictureUrl;
private Provider provider;
@@ -116,24 +114,13 @@ public class UserDTO implements UserDetails {
}
public UserDTO toResponse() {
- return UserDTO.builder()
- .name(this.name)
- .email(this.email)
- .username(this.username)
- .provider(this.provider)
- .build();
- }
-
- public UserDTO toResponse(TokenDTO accessToken, TokenDTO refreshToken) {
return UserDTO.builder()
.id(this.id)
.name(this.name)
.email(this.email)
.username(this.username)
.provider(this.provider)
- .roles(this.roles)
- .accessToken(accessToken)
- .refreshToken(refreshToken)
+ .profilePictureUrl(this.profilePictureUrl)
.build();
}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/config/StorageServiceConfig.java b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/config/StorageServiceConfig.java
new file mode 100644
index 0000000..4e5a9ca
--- /dev/null
+++ b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/config/StorageServiceConfig.java
@@ -0,0 +1,13 @@
+package com.hideyoshi.backendportfolio.microservice.storageService.config;
+
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+
+@Getter
+@Configuration
+public class StorageServiceConfig {
+ @Value("${com.hideyoshi.microservice.storageServicePath}")
+ private String fileServicePath;
+}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/enums/FileTypeEnum.java b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/enums/FileTypeEnum.java
new file mode 100644
index 0000000..62f6606
--- /dev/null
+++ b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/enums/FileTypeEnum.java
@@ -0,0 +1,30 @@
+package com.hideyoshi.backendportfolio.microservice.storageService.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.hideyoshi.backendportfolio.util.exception.BadRequestException;
+import lombok.Getter;
+
+@Getter
+@JsonFormat(shape = JsonFormat.Shape.STRING)
+public enum FileTypeEnum {
+ PNG("png"),
+
+ JPEG("jpeg");
+
+
+ private final String fileExtension;
+
+ FileTypeEnum(String fileExtension) {
+ this.fileExtension = fileExtension;
+ }
+
+ public static FileTypeEnum fromValue(String value) {
+ for (FileTypeEnum e: FileTypeEnum.values()) {
+ if (e.getFileExtension().equals(value)) {
+ return e;
+ }
+ }
+ throw new BadRequestException("Invalid FileType.");
+ }
+
+}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/enums/FileTypeEnumConverter.java b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/enums/FileTypeEnumConverter.java
new file mode 100644
index 0000000..49f2365
--- /dev/null
+++ b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/enums/FileTypeEnumConverter.java
@@ -0,0 +1,12 @@
+package com.hideyoshi.backendportfolio.microservice.storageService.enums;
+
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+@Component
+public class FileTypeEnumConverter implements Converter {
+ @Override
+ public FileTypeEnum convert(String value) {
+ return FileTypeEnum.fromValue(value);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceDownloadResponse.java b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceDownloadResponse.java
new file mode 100644
index 0000000..1ff869b
--- /dev/null
+++ b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceDownloadResponse.java
@@ -0,0 +1,15 @@
+package com.hideyoshi.backendportfolio.microservice.storageService.model;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.*;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public class StorageServiceDownloadResponse {
+
+ @JsonProperty("presigned_url")
+ private String presignedUrl;
+
+}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceUploadResponse.java b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceUploadResponse.java
new file mode 100644
index 0000000..6044aa6
--- /dev/null
+++ b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceUploadResponse.java
@@ -0,0 +1,20 @@
+package com.hideyoshi.backendportfolio.microservice.storageService.model;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NonNull;
+
+@Getter
+@AllArgsConstructor
+public class StorageServiceUploadResponse {
+
+ @JsonProperty("presigned_url")
+ private String presignedUrl;
+
+ @JsonProperty("file_key")
+ private String fileKey;
+
+}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java
new file mode 100644
index 0000000..075d27e
--- /dev/null
+++ b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java
@@ -0,0 +1,166 @@
+package com.hideyoshi.backendportfolio.microservice.storageService.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.hideyoshi.backendportfolio.microservice.storageService.config.StorageServiceConfig;
+import com.hideyoshi.backendportfolio.microservice.storageService.enums.FileTypeEnum;
+import com.hideyoshi.backendportfolio.microservice.storageService.model.StorageServiceDownloadResponse;
+import com.hideyoshi.backendportfolio.microservice.storageService.model.StorageServiceUploadResponse;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.DefaultRedirectStrategy;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.LaxRedirectStrategy;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+@Log4j2
+@Service
+@RequiredArgsConstructor
+public class StorageService {
+
+ private final ObjectMapper objectMapper;
+
+ private final StorageServiceConfig storageServiceConfig;
+
+ private final String PARAMETER_USERNAME = "username";
+
+ private final String PARAMETER_FILE_POSTFIX = "file_postfix";
+
+ private final String PARAMETER_FILE_TYPE = "file_type";
+
+ private final String PARAMETER_KEY_STRING = "string_url";
+
+ public StorageServiceUploadResponse getNewFileUrl(String username, String filePostfix, FileTypeEnum fileTypeEnum) {
+ HashMap values = new HashMap<>() {{
+ put(PARAMETER_USERNAME, username);
+ put(PARAMETER_FILE_POSTFIX, filePostfix);
+ put(PARAMETER_FILE_TYPE, fileTypeEnum.getFileExtension());
+ }};
+
+ String requestBody = null;
+ try {
+ requestBody = objectMapper
+ .writeValueAsString(values);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+
+ HttpPost request = new HttpPost(URI.create(storageServiceConfig.getFileServicePath() + "/new_file_url"));
+ request.setHeader("Content-Type", "application/json");
+
+ try {
+ request.setEntity(new ByteArrayEntity(requestBody.getBytes("UTF-8")));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ CloseableHttpClient httpClient = HttpClientBuilder.create()
+ .setRedirectStrategy(new LaxRedirectStrategy()).build();
+
+ try {
+ return httpClient.execute(
+ request,
+ response -> {
+ String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
+ return objectMapper.readValue(responseString, StorageServiceUploadResponse.class);
+ }
+ );
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public StorageServiceDownloadResponse getFileUrl(String username, String filePostfix) {
+ URI uri = null;
+ try {
+ uri = new URIBuilder(storageServiceConfig.getFileServicePath() + "/file_url")
+ .addParameter(PARAMETER_USERNAME, username)
+ .addParameter(PARAMETER_FILE_POSTFIX, filePostfix)
+ .build();
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+
+ HttpGet request = new HttpGet(uri);
+ request.setHeader("Content-Type", "application/json");
+
+ CloseableHttpClient httpClient = HttpClientBuilder.create()
+ .setRedirectStrategy(new LaxRedirectStrategy()).build();
+
+ try {
+ return httpClient.execute(
+ request,
+ response -> {
+ String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
+ return objectMapper.readValue(responseString, StorageServiceDownloadResponse.class);
+ }
+ );
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void processFile(String username, String filePostfix) {
+ HashMap values = new HashMap<>() {{
+ put(PARAMETER_USERNAME, username);
+ put(PARAMETER_FILE_POSTFIX, filePostfix);
+ }};
+
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ String requestBody = null;
+ try {
+ requestBody = objectMapper
+ .writeValueAsString(values);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+
+ HttpPost request = new HttpPost(URI.create(storageServiceConfig.getFileServicePath() + "/process_file"));
+ request.setHeader("Content-Type", "application/json");
+
+ try {
+ request.setEntity(new ByteArrayEntity(requestBody.getBytes("UTF-8")));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ CloseableHttpClient httpClient = HttpClientBuilder.create()
+ .setRedirectStrategy(new LaxRedirectStrategy()).build();
+
+ try {
+ httpClient.execute(
+ request,
+ response -> {
+ String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
+ return objectMapper.readValue(responseString, StorageServiceUploadResponse.class);
+ }
+ );
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/src/main/java/com/hideyoshi/backendportfolio/util/guard/UserResourceGuardEnum.java b/src/main/java/com/hideyoshi/backendportfolio/util/guard/UserResourceGuardEnum.java
index 1cc77e1..ce08014 100644
--- a/src/main/java/com/hideyoshi/backendportfolio/util/guard/UserResourceGuardEnum.java
+++ b/src/main/java/com/hideyoshi/backendportfolio/util/guard/UserResourceGuardEnum.java
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.hideyoshi.backendportfolio.base.user.entity.Role;
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
import com.hideyoshi.backendportfolio.base.user.service.UserService;
+import lombok.Getter;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.servlet.HandlerMapping;
@@ -11,6 +12,7 @@ import org.springframework.web.servlet.HandlerMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
+@Getter
public enum UserResourceGuardEnum {
USER("user") {
@@ -64,10 +66,6 @@ public enum UserResourceGuardEnum {
ObjectMapper objectMapper,
HttpServletRequest request);
- public String getAccessType() {
- return this.accessType;
- }
-
public static UserResourceGuardEnum byValue(String accessType) {
for (UserResourceGuardEnum o : values()) {
if (o.getAccessType().equals(accessType)) {
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index ffe8e02..2df6c08 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -10,6 +10,9 @@ com:
username: ${DEFAULT_USER_USERNAME}
password: ${DEFAULT_USER_PASSWORD}
+ microservice:
+ storageServicePath: ${STORAGE_SERVICE_PATH}
+
server:
servlet:
diff --git a/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java b/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java
index 5d18242..03ad33c 100644
--- a/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java
+++ b/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java
@@ -40,8 +40,6 @@ class UserServiceImplTest {
private PasswordEncoder passwordEncoder;
- private AuthService authService;
-
@BeforeEach
void setUp() {