From f68b6dfe0824278c6e26527f973406d321ff0492 Mon Sep 17 00:00:00 2001 From: "Jang,Pyohwan" Date: Wed, 26 Apr 2017 23:56:26 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EA=B0=9C=EC=9D=B8=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=EB=B6=81=EC=97=90=EC=84=9C=20=EC=9E=91=EB=91=90?= =?UTF-8?q?=EC=95=B1=EC=97=90=20=EC=9D=B4=EB=A9=94=EC=9D=BC=EC=9D=84=20?= =?UTF-8?q?=EC=A0=9C=EA=B3=B5=EC=95=88=20=ED=95=A0=20=EC=88=98=EB=8F=84=20?= =?UTF-8?q?=EC=9E=88=EB=8B=A4.=20=EC=9D=B4=EB=9F=B4=EB=95=90=20=EC=8B=A0?= =?UTF-8?q?=EA=B7=9C=EA=B0=80=EC=9E=85=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../authentication/SocialDetailService.java | 12 +++---- .../{user => }/AuthRestController.java | 35 +++++++++++-------- .../{user => }/UserRestController.java | 26 +++++++------- .../vo => vo/user}/LoginEmailUserForm.java | 2 +- .../vo => vo/user}/LoginSocialUserForm.java | 3 +- .../user/vo => vo/user}/SocialUserForm.java | 2 +- .../user/vo => vo/user}/UserForm.java | 2 +- .../user/vo => vo/user}/UserPasswordForm.java | 2 +- .../vo => vo/user}/UserProfileEditForm.java | 2 +- .../vo => vo/user}/UserProfileResponse.java | 2 +- .../jakduk/api/user/UserControllerTest.java | 4 +-- .../com/jakduk/core/service/UserService.java | 23 +++++++----- 12 files changed, 64 insertions(+), 51 deletions(-) rename api/src/main/java/com/jakduk/api/restcontroller/{user => }/AuthRestController.java (83%) rename api/src/main/java/com/jakduk/api/restcontroller/{user => }/UserRestController.java (93%) rename api/src/main/java/com/jakduk/api/{restcontroller/user/vo => vo/user}/LoginEmailUserForm.java (91%) rename api/src/main/java/com/jakduk/api/{restcontroller/user/vo => vo/user}/LoginSocialUserForm.java (91%) rename api/src/main/java/com/jakduk/api/{restcontroller/user/vo => vo/user}/SocialUserForm.java (96%) rename api/src/main/java/com/jakduk/api/{restcontroller/user/vo => vo/user}/UserForm.java (97%) rename api/src/main/java/com/jakduk/api/{restcontroller/user/vo => vo/user}/UserPasswordForm.java (95%) rename api/src/main/java/com/jakduk/api/{restcontroller/user/vo => vo/user}/UserProfileEditForm.java (96%) rename api/src/main/java/com/jakduk/api/{restcontroller/user/vo => vo/user}/UserProfileResponse.java (95%) diff --git a/api/src/main/java/com/jakduk/api/configuration/authentication/SocialDetailService.java b/api/src/main/java/com/jakduk/api/configuration/authentication/SocialDetailService.java index d678f630..06f3fcaf 100644 --- a/api/src/main/java/com/jakduk/api/configuration/authentication/SocialDetailService.java +++ b/api/src/main/java/com/jakduk/api/configuration/authentication/SocialDetailService.java @@ -37,16 +37,16 @@ public class SocialDetailService implements UserDetailsService { private UserUtils userUtils; @Override - public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { - if (StringUtils.isBlank(userId)) { - throw new IllegalArgumentException("userId 는 꼭 필요한 값입니다."); + if (StringUtils.isBlank(email)) { + throw new IllegalArgumentException("email 는 꼭 필요한 값입니다."); } else { - User user = userRepository.findOneById(userId) + User user = userRepository.findOneByEmail(email) .orElseThrow(() -> new ServiceException(ServiceError.NOT_FOUND_ACCOUNT, - CoreUtils.getExceptionMessage("exception.not.found.user"))); + CoreUtils.getExceptionMessage("exception.not.found.jakduk.account", email))); - SocialUserDetails socialUserDetails = new SocialUserDetails(user.getId(), user.getEmail(), user.getUsername(), user.getProviderId(), user.getEmail(), + SocialUserDetails socialUserDetails = new SocialUserDetails(user.getId(), email, user.getUsername(), user.getProviderId(), user.getEmail(), true, true, true, true, UserUtils.getAuthorities(user.getRoles())); UserPicture userPicture = user.getUserPicture(); diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/AuthRestController.java b/api/src/main/java/com/jakduk/api/restcontroller/AuthRestController.java similarity index 83% rename from api/src/main/java/com/jakduk/api/restcontroller/user/AuthRestController.java rename to api/src/main/java/com/jakduk/api/restcontroller/AuthRestController.java index 6281db4b..2b859ba7 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/AuthRestController.java +++ b/api/src/main/java/com/jakduk/api/restcontroller/AuthRestController.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user; +package com.jakduk.api.restcontroller; import com.jakduk.api.common.util.JwtTokenUtils; import com.jakduk.api.common.util.UserUtils; @@ -9,8 +9,8 @@ import com.jakduk.api.configuration.authentication.SocialDetailService; import com.jakduk.api.configuration.authentication.user.JakdukUserDetails; import com.jakduk.api.configuration.authentication.user.SocialUserDetails; -import com.jakduk.api.restcontroller.user.vo.LoginEmailUserForm; -import com.jakduk.api.restcontroller.user.vo.LoginSocialUserForm; +import com.jakduk.api.vo.user.LoginEmailUserForm; +import com.jakduk.api.vo.user.LoginSocialUserForm; import com.jakduk.api.restcontroller.vo.EmptyJsonResponse; import com.jakduk.core.common.CoreConst; import com.jakduk.core.exception.ServiceError; @@ -19,6 +19,7 @@ import com.jakduk.core.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -115,12 +116,13 @@ public EmptyJsonResponse refreshAndGetAuthenticationToken(HttpServletRequest req } } - @ApiOperation(value = "SNS 기반 로그인 (존재 하지 않는 회원이면 신규가입 진행)") - @RequestMapping(value = "/login/social/{providerId}", method = RequestMethod.POST) - public EmptyJsonResponse loginSocialUser(@PathVariable String providerId, - @Valid @RequestBody LoginSocialUserForm form, - Device device, - HttpServletResponse response) { + @ApiOperation("SNS 기반 로그인 (존재 하지 않는 회원이면 신규가입 진행)") + @PostMapping("/login/social/{providerId}") + public EmptyJsonResponse loginSocialUser( + @ApiParam(value = "Provider ID", required = true) @PathVariable String providerId, + @ApiParam(value = "SNS 회원 폼", required = true) @Valid @RequestBody LoginSocialUserForm form, + Device device, + HttpServletResponse response) { log.info("accessToken={}", form.getAccessToken()); @@ -136,7 +138,8 @@ public EmptyJsonResponse loginSocialUser(@PathVariable String providerId, break; } - log.info("socialProfile({}, {}) email({})", socialProfile.getId(), socialProfile.getNickname(), socialProfile.getEmail()); + log.info("socialProfile providerId:{} providerUserId:{} nickname:{} email:{}", + convertProviderId.name(), socialProfile.getId(), socialProfile.getNickname(), socialProfile.getEmail()); try { User user = userService.findOneByProviderIdAndProviderUserId(convertProviderId, socialProfile.getId()); @@ -146,11 +149,16 @@ public EmptyJsonResponse loginSocialUser(@PathVariable String providerId, user.setEmail(socialProfile.getEmail()); userService.save(user); - log.info("user({},{}) email({}) has been entered.", user.getId(), user.getUsername(), user.getEmail()); + log.info("user({},{}) email:{} has been entered.", user.getId(), user.getUsername(), user.getEmail()); + } + // User DB 와 SNS Profile 모두에 email이 없을 경우에는 신규 가입으로 진행한다. + // SNS 가입시 이메일 제공 동의를 안해서 그렇다. + else if (StringUtils.isBlank(user.getEmail()) && StringUtils.isBlank(socialProfile.getEmail())) { + throw new ServiceException(ServiceError.NOT_REGISTER_WITH_SNS); } // 토큰 생성 - SocialUserDetails userDetails = (SocialUserDetails) socialDetailService.loadUserByUsername(user.getId()); + SocialUserDetails userDetails = (SocialUserDetails) socialDetailService.loadUserByUsername(user.getEmail()); String token = jwtTokenUtils.generateToken(device, userDetails.getId(), userDetails.getEmail(), userDetails.getUsername(), userDetails.getProviderId().name()); @@ -162,14 +170,13 @@ public EmptyJsonResponse loginSocialUser(@PathVariable String providerId, } catch (ServiceException ignored) { } - // 신규 가입. + // 신규 가입을 위한 토큰 생성 AttemptSocialUser attemptSocialUser = AttemptSocialUser.builder() .username(socialProfile.getNickname()) .providerId(convertProviderId) .providerUserId(socialProfile.getId()) .build(); - // Daum은 이메일을 안 알려준다. if (StringUtils.isNotBlank(socialProfile.getEmail())) attemptSocialUser.setEmail(socialProfile.getEmail()); diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/UserRestController.java b/api/src/main/java/com/jakduk/api/restcontroller/UserRestController.java similarity index 93% rename from api/src/main/java/com/jakduk/api/restcontroller/user/UserRestController.java rename to api/src/main/java/com/jakduk/api/restcontroller/UserRestController.java index ce8ec2fa..b5c90816 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/UserRestController.java +++ b/api/src/main/java/com/jakduk/api/restcontroller/UserRestController.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user; +package com.jakduk.api.restcontroller; import com.jakduk.api.common.constraint.ExistEmail; import com.jakduk.api.common.constraint.ExistEmailOnEdit; @@ -9,7 +9,7 @@ import com.jakduk.api.common.vo.AttemptSocialUser; import com.jakduk.api.common.vo.AuthUserProfile; import com.jakduk.api.restcontroller.vo.EmptyJsonResponse; -import com.jakduk.api.restcontroller.user.vo.*; +import com.jakduk.api.vo.user.*; import com.jakduk.core.common.CoreConst; import com.jakduk.core.common.util.CoreUtils; import com.jakduk.core.exception.ServiceError; @@ -25,6 +25,7 @@ import com.jakduk.core.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import org.apache.commons.lang3.StringUtils; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotEmpty; @@ -95,22 +96,22 @@ public EmptyJsonResponse addJakdukUser(@Valid @RequestBody UserForm form, return EmptyJsonResponse.newInstance(); } - @ApiOperation(value = "SNS 기반 회원 가입") - @RequestMapping(value = "/social", method = RequestMethod.POST) - public EmptyJsonResponse addSocialUser(@RequestHeader(value = "x-attempt-token") String attemptedToken, - @Valid @RequestBody SocialUserForm form, - Device device, - Locale locale, - HttpServletResponse response) { + @ApiOperation("SNS 기반 회원 가입") + @PostMapping("/social") + public EmptyJsonResponse addSocialUser( + @ApiParam(value = "임시 회원 정보 토큰", required = true) @RequestHeader(value = "x-attempt-token") String attemptedToken, + @ApiParam(value = "SNS 회원 폼", required = true) @Valid @RequestBody SocialUserForm form, + Device device, + Locale locale, + HttpServletResponse response) { if (! jwtTokenUtils.isValidateToken(attemptedToken)) throw new ServiceException(ServiceError.EXPIRATION_TOKEN); String largePictureUrl = null; - if (! ObjectUtils.isEmpty(form.getExternalLargePictureUrl())) { + if (StringUtils.isNotBlank(form.getExternalLargePictureUrl())) largePictureUrl = StringUtils.defaultIfBlank(form.getExternalLargePictureUrl(), null); - } AttemptSocialUser attemptSocialUser = jwtTokenUtils.getAttemptedFromToken(attemptedToken); @@ -118,14 +119,13 @@ public EmptyJsonResponse addSocialUser(@RequestHeader(value = "x-attempt-token") attemptSocialUser.getProviderUserId(), form.getFootballClub(), form.getAbout(), form.getUserPictureId(), largePictureUrl); - emailService.sendWelcome(locale, form.getUsername().trim(), form.getEmail().trim()); + emailService.sendWelcome(locale, user.getUsername(), user.getEmail()); String token = jwtTokenUtils.generateToken(device, user.getId(), user.getEmail(), user.getUsername(), user.getProviderId().name()); response.setHeader(tokenHeader, token); return EmptyJsonResponse.newInstance(); - } @ApiOperation(value = "회원 프로필 편집 시 Email 중복 검사") diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/LoginEmailUserForm.java b/api/src/main/java/com/jakduk/api/vo/user/LoginEmailUserForm.java similarity index 91% rename from api/src/main/java/com/jakduk/api/restcontroller/user/vo/LoginEmailUserForm.java rename to api/src/main/java/com/jakduk/api/vo/user/LoginEmailUserForm.java index 4c3601dc..9e635a7a 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/LoginEmailUserForm.java +++ b/api/src/main/java/com/jakduk/api/vo/user/LoginEmailUserForm.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user.vo; +package com.jakduk.api.vo.user; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/LoginSocialUserForm.java b/api/src/main/java/com/jakduk/api/vo/user/LoginSocialUserForm.java similarity index 91% rename from api/src/main/java/com/jakduk/api/restcontroller/user/vo/LoginSocialUserForm.java rename to api/src/main/java/com/jakduk/api/vo/user/LoginSocialUserForm.java index 3de6abdc..e20d22f7 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/LoginSocialUserForm.java +++ b/api/src/main/java/com/jakduk/api/vo/user/LoginSocialUserForm.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user.vo; +package com.jakduk.api.vo.user; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -17,4 +17,5 @@ public class LoginSocialUserForm { @ApiModelProperty(required = true, example = "EAALwXK...", value = "OAuth 인증에서 사용하는 AccessToken") @NotEmpty private String accessToken; + } diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/SocialUserForm.java b/api/src/main/java/com/jakduk/api/vo/user/SocialUserForm.java similarity index 96% rename from api/src/main/java/com/jakduk/api/restcontroller/user/vo/SocialUserForm.java rename to api/src/main/java/com/jakduk/api/vo/user/SocialUserForm.java index ee329e5a..b66fe43c 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/SocialUserForm.java +++ b/api/src/main/java/com/jakduk/api/vo/user/SocialUserForm.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user.vo; +package com.jakduk.api.vo.user; import com.jakduk.api.common.constraint.ExistEmail; import com.jakduk.api.common.constraint.ExistUsername; diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserForm.java b/api/src/main/java/com/jakduk/api/vo/user/UserForm.java similarity index 97% rename from api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserForm.java rename to api/src/main/java/com/jakduk/api/vo/user/UserForm.java index 7785d984..8cd92944 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserForm.java +++ b/api/src/main/java/com/jakduk/api/vo/user/UserForm.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user.vo; +package com.jakduk.api.vo.user; import com.jakduk.api.common.constraint.ExistEmail; import com.jakduk.api.common.constraint.ExistUsername; diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserPasswordForm.java b/api/src/main/java/com/jakduk/api/vo/user/UserPasswordForm.java similarity index 95% rename from api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserPasswordForm.java rename to api/src/main/java/com/jakduk/api/vo/user/UserPasswordForm.java index 8b78fd17..e0172ac9 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserPasswordForm.java +++ b/api/src/main/java/com/jakduk/api/vo/user/UserPasswordForm.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user.vo; +package com.jakduk.api.vo.user; import com.jakduk.api.common.constraint.FieldMatch; import com.jakduk.api.common.constraint.PasswordMatch; diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserProfileEditForm.java b/api/src/main/java/com/jakduk/api/vo/user/UserProfileEditForm.java similarity index 96% rename from api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserProfileEditForm.java rename to api/src/main/java/com/jakduk/api/vo/user/UserProfileEditForm.java index 41a1b351..0748d5bd 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserProfileEditForm.java +++ b/api/src/main/java/com/jakduk/api/vo/user/UserProfileEditForm.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user.vo; +package com.jakduk.api.vo.user; import com.jakduk.api.common.constraint.ExistEmailOnEdit; import com.jakduk.api.common.constraint.ExistUsernameOnEdit; diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserProfileResponse.java b/api/src/main/java/com/jakduk/api/vo/user/UserProfileResponse.java similarity index 95% rename from api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserProfileResponse.java rename to api/src/main/java/com/jakduk/api/vo/user/UserProfileResponse.java index f78685db..c02e3c2c 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/vo/UserProfileResponse.java +++ b/api/src/main/java/com/jakduk/api/vo/user/UserProfileResponse.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user.vo; +package com.jakduk.api.vo.user; import com.jakduk.core.common.CoreConst; import com.jakduk.core.model.embedded.LocalName; diff --git a/api/src/test/java/com/jakduk/api/user/UserControllerTest.java b/api/src/test/java/com/jakduk/api/user/UserControllerTest.java index ae176da0..5348075d 100644 --- a/api/src/test/java/com/jakduk/api/user/UserControllerTest.java +++ b/api/src/test/java/com/jakduk/api/user/UserControllerTest.java @@ -1,7 +1,7 @@ package com.jakduk.api.user; -import com.jakduk.api.restcontroller.user.UserRestController; -import com.jakduk.api.restcontroller.user.vo.SocialUserForm; +import com.jakduk.api.restcontroller.UserRestController; +import com.jakduk.api.vo.user.SocialUserForm; import com.jakduk.api.util.AbstractMvcTest; import org.junit.Before; import org.junit.Ignore; diff --git a/core/src/main/java/com/jakduk/core/service/UserService.java b/core/src/main/java/com/jakduk/core/service/UserService.java index 903afab7..2d769cf8 100644 --- a/core/src/main/java/com/jakduk/core/service/UserService.java +++ b/core/src/main/java/com/jakduk/core/service/UserService.java @@ -145,18 +145,23 @@ public User addJakdukUser(String email, String username, String password, String return user; } + /** + * SNS 회원 가입 + */ public User addSocialUser(String email, String username, CoreConst.ACCOUNT_TYPE providerId, String providerUserId, String footballClub, String about, String userPictureId, String largePictureUrl) { UserPicture userPicture = null; - User user = User.builder() - .email(email.trim()) - .username(username.trim()) - .providerId(providerId) - .providerUserId(providerUserId) - .roles(Collections.singletonList(CommonRole.ROLE_NUMBER_USER_01)) - .build(); + User user = userRepository.findOneByProviderIdAndProviderUserId(providerId, providerUserId) + .orElseGet(() -> User.builder() + .email(email.trim()) + .providerId(providerId) + .providerUserId(providerUserId) + .roles(Collections.singletonList(CommonRole.ROLE_NUMBER_USER_01)) + .build()); + + user.setUsername(username); if (StringUtils.isNotBlank(footballClub)) { FootballClub supportFC = footballClubRepository.findOneById(footballClub) @@ -210,13 +215,13 @@ else if (StringUtils.isNotBlank(largePictureUrl)) { userRepository.save(user); // userImage를 user와 연동 및 활성화 처리 - if (! ObjectUtils.isEmpty(userPicture)) { + if (Objects.nonNull(userPicture)) { userPicture.setUser(user); userPicture.setStatus(CoreConst.GALLERY_STATUS_TYPE.ENABLE); userPictureRepository.save(userPicture); } - log.debug("social user created. user=" + user); + log.debug("social user created.\n{}" + user); return user; } From 803bb0446cbedc9f612866e186e611ec1cd209a1 Mon Sep 17 00:00:00 2001 From: "Jang,Pyohwan" Date: Thu, 27 Apr 2017 00:56:03 +0900 Subject: [PATCH 2/2] =?UTF-8?q?SNS=20=EA=B0=80=EC=9E=85=EC=8B=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9D=B4=20=EB=B3=B5=EC=9E=A1=ED=95=B4?= =?UTF-8?q?=EC=A7=84=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constraint/ExistEmailOnEditValidator.java | 2 +- .../constraint/ExistEmailValidator.java | 2 +- .../ExistUsernameOnEditValidator.java | 2 +- .../constraint/ExistUsernameValidator.java | 2 +- .../constraint/PasswordMatchValidator.java | 2 +- .../jakduk/api/common/util/JwtTokenUtils.java | 21 ++++-- .../api/common/vo/AttemptSocialUser.java | 1 + .../restcontroller/AuthRestController.java | 67 +++++++++---------- .../{user => }/PasswordRestController.java | 4 +- .../restcontroller/UserRestController.java | 22 +++--- .../com/jakduk/api}/service/UserService.java | 39 +++++++++-- .../jakduk/api/vo/user/SocialUserForm.java | 4 ++ build.gradle | 1 + 13 files changed, 102 insertions(+), 67 deletions(-) rename api/src/main/java/com/jakduk/api/restcontroller/{user => }/PasswordRestController.java (97%) rename {core/src/main/java/com/jakduk/core => api/src/main/java/com/jakduk/api}/service/UserService.java (88%) diff --git a/api/src/main/java/com/jakduk/api/common/constraint/ExistEmailOnEditValidator.java b/api/src/main/java/com/jakduk/api/common/constraint/ExistEmailOnEditValidator.java index 6ac8b781..09ca0358 100644 --- a/api/src/main/java/com/jakduk/api/common/constraint/ExistEmailOnEditValidator.java +++ b/api/src/main/java/com/jakduk/api/common/constraint/ExistEmailOnEditValidator.java @@ -3,7 +3,7 @@ import com.jakduk.api.common.util.UserUtils; import com.jakduk.api.common.vo.AuthUserProfile; import com.jakduk.core.model.simple.UserProfile; -import com.jakduk.core.service.UserService; +import com.jakduk.api.service.UserService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.ObjectUtils; diff --git a/api/src/main/java/com/jakduk/api/common/constraint/ExistEmailValidator.java b/api/src/main/java/com/jakduk/api/common/constraint/ExistEmailValidator.java index 1e4a389e..c18a49b4 100644 --- a/api/src/main/java/com/jakduk/api/common/constraint/ExistEmailValidator.java +++ b/api/src/main/java/com/jakduk/api/common/constraint/ExistEmailValidator.java @@ -1,7 +1,7 @@ package com.jakduk.api.common.constraint; import com.jakduk.core.model.simple.UserProfile; -import com.jakduk.core.service.UserService; +import com.jakduk.api.service.UserService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.ObjectUtils; diff --git a/api/src/main/java/com/jakduk/api/common/constraint/ExistUsernameOnEditValidator.java b/api/src/main/java/com/jakduk/api/common/constraint/ExistUsernameOnEditValidator.java index fb1db7d1..73ccfb0a 100644 --- a/api/src/main/java/com/jakduk/api/common/constraint/ExistUsernameOnEditValidator.java +++ b/api/src/main/java/com/jakduk/api/common/constraint/ExistUsernameOnEditValidator.java @@ -5,7 +5,7 @@ import com.jakduk.core.exception.ServiceError; import com.jakduk.core.exception.ServiceException; import com.jakduk.core.model.simple.UserProfile; -import com.jakduk.core.service.UserService; +import com.jakduk.api.service.UserService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.ObjectUtils; diff --git a/api/src/main/java/com/jakduk/api/common/constraint/ExistUsernameValidator.java b/api/src/main/java/com/jakduk/api/common/constraint/ExistUsernameValidator.java index 24098b54..08ce86c3 100644 --- a/api/src/main/java/com/jakduk/api/common/constraint/ExistUsernameValidator.java +++ b/api/src/main/java/com/jakduk/api/common/constraint/ExistUsernameValidator.java @@ -1,7 +1,7 @@ package com.jakduk.api.common.constraint; import com.jakduk.core.model.simple.UserProfile; -import com.jakduk.core.service.UserService; +import com.jakduk.api.service.UserService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.ObjectUtils; diff --git a/api/src/main/java/com/jakduk/api/common/constraint/PasswordMatchValidator.java b/api/src/main/java/com/jakduk/api/common/constraint/PasswordMatchValidator.java index 0499b88d..f47409c5 100644 --- a/api/src/main/java/com/jakduk/api/common/constraint/PasswordMatchValidator.java +++ b/api/src/main/java/com/jakduk/api/common/constraint/PasswordMatchValidator.java @@ -3,7 +3,7 @@ import com.jakduk.api.common.util.UserUtils; import com.jakduk.api.common.vo.AuthUserProfile; import com.jakduk.core.model.simple.UserOnPasswordUpdate; -import com.jakduk.core.service.UserService; +import com.jakduk.api.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.StandardPasswordEncoder; diff --git a/api/src/main/java/com/jakduk/api/common/util/JwtTokenUtils.java b/api/src/main/java/com/jakduk/api/common/util/JwtTokenUtils.java index 18cfd1d8..1d4fd8f1 100644 --- a/api/src/main/java/com/jakduk/api/common/util/JwtTokenUtils.java +++ b/api/src/main/java/com/jakduk/api/common/util/JwtTokenUtils.java @@ -5,16 +5,17 @@ import com.jakduk.core.exception.ServiceError; import com.jakduk.core.exception.ServiceException; import io.jsonwebtoken.*; +import org.apache.commons.lang3.StringUtils; import org.springframework.aop.AopInvocationException; import org.springframework.beans.factory.annotation.Value; import org.springframework.mobile.device.Device; import org.springframework.stereotype.Component; -import org.springframework.util.ObjectUtils; import java.io.Serializable; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.Objects; @Component public class JwtTokenUtils implements Serializable { @@ -67,6 +68,9 @@ public AttemptSocialUser getAttemptedFromToken(String token) { try { final Claims claims = getClaimsFromToken(token); + if (claims.containsKey("id")) + attemptSocialUser.setId(claims.get("id", String.class)); + if (claims.containsKey("email")) attemptSocialUser.setEmail(claims.get("email", String.class)); @@ -220,22 +224,25 @@ public Boolean isValidateToken(String token) { private Map convertAttemptedSocialUserToMap(AttemptSocialUser attemptSocialUser) { Map attempted = new HashMap<>(); - if (! ObjectUtils.isEmpty(attemptSocialUser.getEmail())) + if (StringUtils.isNotBlank(attemptSocialUser.getId())) + attempted.put("id", attemptSocialUser.getId()); + + if (StringUtils.isNotBlank(attemptSocialUser.getEmail())) attempted.put("email", attemptSocialUser.getEmail()); - if (! ObjectUtils.isEmpty(attemptSocialUser.getUsername())) + if (StringUtils.isNotBlank(attemptSocialUser.getUsername())) attempted.put("username", attemptSocialUser.getUsername()); - if (! ObjectUtils.isEmpty(attemptSocialUser.getProviderId())) + if (Objects.nonNull(attemptSocialUser.getProviderId())) attempted.put("providerId", attemptSocialUser.getProviderId()); - if (! ObjectUtils.isEmpty(attemptSocialUser.getProviderUserId())) + if (StringUtils.isNotBlank(attemptSocialUser.getProviderUserId())) attempted.put("providerUserId", attemptSocialUser.getProviderUserId()); - if (! ObjectUtils.isEmpty(attemptSocialUser.getExternalSmallPictureUrl())) + if (StringUtils.isNotBlank(attemptSocialUser.getExternalSmallPictureUrl())) attempted.put("externalSmallPictureUrl", attemptSocialUser.getExternalSmallPictureUrl()); - if (! ObjectUtils.isEmpty(attemptSocialUser.getExternalLargePictureUrl())) + if (StringUtils.isNotBlank(attemptSocialUser.getExternalLargePictureUrl())) attempted.put("externalLargePictureUrl", attemptSocialUser.getExternalLargePictureUrl()); return attempted; diff --git a/api/src/main/java/com/jakduk/api/common/vo/AttemptSocialUser.java b/api/src/main/java/com/jakduk/api/common/vo/AttemptSocialUser.java index 579d043e..2ac39be6 100644 --- a/api/src/main/java/com/jakduk/api/common/vo/AttemptSocialUser.java +++ b/api/src/main/java/com/jakduk/api/common/vo/AttemptSocialUser.java @@ -17,6 +17,7 @@ @Setter public class AttemptSocialUser { + private String id; private String email; private String username; private CoreConst.ACCOUNT_TYPE providerId; diff --git a/api/src/main/java/com/jakduk/api/restcontroller/AuthRestController.java b/api/src/main/java/com/jakduk/api/restcontroller/AuthRestController.java index 2b859ba7..5fa2154b 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/AuthRestController.java +++ b/api/src/main/java/com/jakduk/api/restcontroller/AuthRestController.java @@ -8,15 +8,14 @@ import com.jakduk.api.configuration.authentication.JakdukDetailsService; import com.jakduk.api.configuration.authentication.SocialDetailService; import com.jakduk.api.configuration.authentication.user.JakdukUserDetails; -import com.jakduk.api.configuration.authentication.user.SocialUserDetails; +import com.jakduk.api.restcontroller.vo.EmptyJsonResponse; +import com.jakduk.api.service.UserService; import com.jakduk.api.vo.user.LoginEmailUserForm; import com.jakduk.api.vo.user.LoginSocialUserForm; -import com.jakduk.api.restcontroller.vo.EmptyJsonResponse; import com.jakduk.core.common.CoreConst; import com.jakduk.core.exception.ServiceError; import com.jakduk.core.exception.ServiceException; import com.jakduk.core.model.db.User; -import com.jakduk.core.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -36,6 +35,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; +import java.util.Optional; /** * @author pyohwan @@ -66,9 +66,6 @@ public class AuthRestController { @Autowired private JakdukDetailsService jakdukDetailsService; - @Autowired - private SocialDetailService socialDetailService; - @Autowired private UserService userService; @@ -128,6 +125,7 @@ public EmptyJsonResponse loginSocialUser( CoreConst.ACCOUNT_TYPE convertProviderId = CoreConst.ACCOUNT_TYPE.valueOf(providerId.toUpperCase()); SocialProfile socialProfile = null; + AttemptSocialUser attemptSocialUser = null; switch (convertProviderId) { case DAUM: @@ -141,44 +139,40 @@ public EmptyJsonResponse loginSocialUser( log.info("socialProfile providerId:{} providerUserId:{} nickname:{} email:{}", convertProviderId.name(), socialProfile.getId(), socialProfile.getNickname(), socialProfile.getEmail()); - try { - User user = userService.findOneByProviderIdAndProviderUserId(convertProviderId, socialProfile.getId()); - - // 과거에 SNS 가입 회원들은 email이 없는 경우가 있음. 이메일을 DB에 저장 - if (StringUtils.isBlank(user.getEmail()) && StringUtils.isNotBlank(socialProfile.getEmail())) { - user.setEmail(socialProfile.getEmail()); - userService.save(user); + Optional oUser = userService.findOneByProviderIdAndProviderUserId(convertProviderId, socialProfile.getId()); - log.info("user({},{}) email:{} has been entered.", user.getId(), user.getUsername(), user.getEmail()); - } - // User DB 와 SNS Profile 모두에 email이 없을 경우에는 신규 가입으로 진행한다. - // SNS 가입시 이메일 제공 동의를 안해서 그렇다. - else if (StringUtils.isBlank(user.getEmail()) && StringUtils.isBlank(socialProfile.getEmail())) { - throw new ServiceException(ServiceError.NOT_REGISTER_WITH_SNS); - } + // User DB 와 SNS Profile 모두에 email이 없을 경우에는 신규 가입으로 진행한다. + // SNS 가입시 이메일 제공 동의를 안해서 그렇다. + if (oUser.isPresent() && StringUtils.isBlank(oUser.get().getEmail()) && StringUtils.isBlank(socialProfile.getEmail())) { - // 토큰 생성 - SocialUserDetails userDetails = (SocialUserDetails) socialDetailService.loadUserByUsername(user.getEmail()); + User user = oUser.get(); - String token = jwtTokenUtils.generateToken(device, userDetails.getId(), userDetails.getEmail(), userDetails.getUsername(), - userDetails.getProviderId().name()); + attemptSocialUser = AttemptSocialUser.builder() + .id(user.getId()) + .username(user.getUsername()) + .providerId(convertProviderId) + .providerUserId(socialProfile.getId()) + .build(); + } + // 가입 회원이라 로그인 + else if (oUser.isPresent()) { + String token = userService.loginSnsUser(device, socialProfile.getEmail(), oUser.get()); response.setHeader(tokenHeader, token); return EmptyJsonResponse.newInstance(); - - } catch (ServiceException ignored) { } - - // 신규 가입을 위한 토큰 생성 - AttemptSocialUser attemptSocialUser = AttemptSocialUser.builder() - .username(socialProfile.getNickname()) - .providerId(convertProviderId) - .providerUserId(socialProfile.getId()) - .build(); - - if (StringUtils.isNotBlank(socialProfile.getEmail())) - attemptSocialUser.setEmail(socialProfile.getEmail()); + // 그냥 신규 가입 + else { + attemptSocialUser = AttemptSocialUser.builder() + .username(socialProfile.getNickname()) + .providerId(convertProviderId) + .providerUserId(socialProfile.getId()) + .build(); + + if (StringUtils.isNotBlank(socialProfile.getEmail())) + attemptSocialUser.setEmail(socialProfile.getEmail()); + } if (StringUtils.isNotBlank(socialProfile.getLargePictureUrl())) attemptSocialUser.setExternalLargePictureUrl(socialProfile.getLargePictureUrl()); @@ -214,4 +208,5 @@ public AuthUserProfile getMyProfile() { return authUserProfile; } + } diff --git a/api/src/main/java/com/jakduk/api/restcontroller/user/PasswordRestController.java b/api/src/main/java/com/jakduk/api/restcontroller/PasswordRestController.java similarity index 97% rename from api/src/main/java/com/jakduk/api/restcontroller/user/PasswordRestController.java rename to api/src/main/java/com/jakduk/api/restcontroller/PasswordRestController.java index 51cf88c5..ed7a5040 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/user/PasswordRestController.java +++ b/api/src/main/java/com/jakduk/api/restcontroller/PasswordRestController.java @@ -1,4 +1,4 @@ -package com.jakduk.api.restcontroller.user; +package com.jakduk.api.restcontroller; import com.jakduk.core.common.CoreConst; import com.jakduk.core.common.util.CoreUtils; @@ -9,7 +9,7 @@ import com.jakduk.core.repository.TokenRepository; import com.jakduk.core.service.CommonService; import com.jakduk.core.service.EmailService; -import com.jakduk.core.service.UserService; +import com.jakduk.api.service.UserService; import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; diff --git a/api/src/main/java/com/jakduk/api/restcontroller/UserRestController.java b/api/src/main/java/com/jakduk/api/restcontroller/UserRestController.java index b5c90816..2d343ef8 100644 --- a/api/src/main/java/com/jakduk/api/restcontroller/UserRestController.java +++ b/api/src/main/java/com/jakduk/api/restcontroller/UserRestController.java @@ -9,6 +9,7 @@ import com.jakduk.api.common.vo.AttemptSocialUser; import com.jakduk.api.common.vo.AuthUserProfile; import com.jakduk.api.restcontroller.vo.EmptyJsonResponse; +import com.jakduk.api.service.UserService; import com.jakduk.api.vo.user.*; import com.jakduk.core.common.CoreConst; import com.jakduk.core.common.util.CoreUtils; @@ -22,7 +23,6 @@ import com.jakduk.core.model.simple.UserProfile; import com.jakduk.core.service.EmailService; import com.jakduk.core.service.FootballService; -import com.jakduk.core.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -115,7 +115,7 @@ public EmptyJsonResponse addSocialUser( AttemptSocialUser attemptSocialUser = jwtTokenUtils.getAttemptedFromToken(attemptedToken); - User user = userService.addSocialUser(form.getEmail(), form.getUsername(), attemptSocialUser.getProviderId(), + User user = userService.addSocialUser(form.getId(), form.getEmail(), form.getUsername(), attemptSocialUser.getProviderId(), attemptSocialUser.getProviderUserId(), form.getFootballClub(), form.getAbout(), form.getUserPictureId(), largePictureUrl); @@ -128,6 +128,15 @@ public EmptyJsonResponse addSocialUser( return EmptyJsonResponse.newInstance(); } + @ApiOperation(value = "이메일 중복 검사") + @RequestMapping(value = "/exist/email", method = RequestMethod.GET) + public EmptyJsonResponse existEmail(@NotEmpty @Email @ExistEmail @RequestParam String email) { + + userService.existEmail(StringUtils.trim(email)); + + return EmptyJsonResponse.newInstance(); + } + @ApiOperation(value = "회원 프로필 편집 시 Email 중복 검사") @RequestMapping(value = "/exist/email/edit", method = RequestMethod.GET) public EmptyJsonResponse existEmailOnEdit(@NotEmpty @Email @ExistEmailOnEdit @RequestParam String email) { @@ -170,15 +179,6 @@ public EmptyJsonResponse existUsernameOnAnonymous(@NotEmpty @RequestParam String return EmptyJsonResponse.newInstance(); } - @ApiOperation(value = "이메일 중복 검사") - @RequestMapping(value = "/exist/email", method = RequestMethod.GET) - public EmptyJsonResponse existEmail(@NotEmpty @Email @ExistEmail @RequestParam String email) { - - userService.existEmail(StringUtils.trim(email)); - - return EmptyJsonResponse.newInstance(); - } - @ApiOperation(value = "별명 중복 검사") @RequestMapping(value = "/exist/username", method = RequestMethod.GET) public EmptyJsonResponse existUsername(@NotEmpty @ExistUsername @RequestParam String username) { diff --git a/core/src/main/java/com/jakduk/core/service/UserService.java b/api/src/main/java/com/jakduk/api/service/UserService.java similarity index 88% rename from core/src/main/java/com/jakduk/core/service/UserService.java rename to api/src/main/java/com/jakduk/api/service/UserService.java index 2d769cf8..b0d17983 100644 --- a/core/src/main/java/com/jakduk/core/service/UserService.java +++ b/api/src/main/java/com/jakduk/api/service/UserService.java @@ -1,6 +1,9 @@ -package com.jakduk.core.service; +package com.jakduk.api.service; +import com.jakduk.api.common.util.JwtTokenUtils; +import com.jakduk.api.configuration.authentication.SocialDetailService; +import com.jakduk.api.configuration.authentication.user.SocialUserDetails; import com.jakduk.core.common.CommonRole; import com.jakduk.core.common.CoreConst; import com.jakduk.core.common.util.FileUtils; @@ -20,6 +23,7 @@ import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.mobile.device.Device; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; @@ -46,6 +50,12 @@ public class UserService { @Autowired private UserPictureRepository userPictureRepository; + @Autowired + private SocialDetailService socialDetailService; + + @Autowired + private JwtTokenUtils jwtTokenUtils; + @Value("${core.storage.user.picture.large.path}") private String storageUserPictureLargePath; @@ -62,9 +72,8 @@ public UserProfile findUserProfileById(String id) { .orElseThrow(() -> new ServiceException(ServiceError.NOT_FOUND_USER)); } - public User findOneByProviderIdAndProviderUserId(CoreConst.ACCOUNT_TYPE providerId, String providerUserId) { - return userRepository.findOneByProviderIdAndProviderUserId(providerId, providerUserId) - .orElseThrow(() -> new ServiceException(ServiceError.NOT_FOUND_USER)); + public Optional findOneByProviderIdAndProviderUserId(CoreConst.ACCOUNT_TYPE providerId, String providerUserId) { + return userRepository.findOneByProviderIdAndProviderUserId(providerId, providerUserId); } // email과 일치하는 회원 찾기. @@ -98,6 +107,24 @@ public UserOnPasswordUpdate findUserOnPasswordUpdateById(String id){ return userRepository.findUserOnPasswordUpdateById(id); } + public String loginSnsUser(Device device, String snsEmail, User user) { + // 과거 SNS 가입 회원들은 email이 없는 경우가 있음. 이메일을 DB에 저장 + if (StringUtils.isBlank(user.getEmail()) && StringUtils.isNotBlank(snsEmail)) { + user.setEmail(snsEmail); + userRepository.save(user); + + log.info("user({},{}) email:{} has been entered.", user.getId(), user.getUsername(), user.getEmail()); + } + + SocialUserDetails userDetails = (SocialUserDetails) socialDetailService.loadUserByUsername(user.getEmail()); + + // 토큰 생성 + String token = jwtTokenUtils.generateToken(device, userDetails.getId(), userDetails.getEmail(), userDetails.getUsername(), + userDetails.getProviderId().name()); + + return token; + } + // 회원 정보 저장. public void save(User user) { userRepository.save(user); @@ -148,12 +175,12 @@ public User addJakdukUser(String email, String username, String password, String /** * SNS 회원 가입 */ - public User addSocialUser(String email, String username, CoreConst.ACCOUNT_TYPE providerId, String providerUserId, + public User addSocialUser(String id, String email, String username, CoreConst.ACCOUNT_TYPE providerId, String providerUserId, String footballClub, String about, String userPictureId, String largePictureUrl) { UserPicture userPicture = null; - User user = userRepository.findOneByProviderIdAndProviderUserId(providerId, providerUserId) + User user = userRepository.findOneById(id) .orElseGet(() -> User.builder() .email(email.trim()) .providerId(providerId) diff --git a/api/src/main/java/com/jakduk/api/vo/user/SocialUserForm.java b/api/src/main/java/com/jakduk/api/vo/user/SocialUserForm.java index b66fe43c..46f5f2c9 100644 --- a/api/src/main/java/com/jakduk/api/vo/user/SocialUserForm.java +++ b/api/src/main/java/com/jakduk/api/vo/user/SocialUserForm.java @@ -21,6 +21,9 @@ @Getter public class SocialUserForm { + @ApiModelProperty(example = "58ad9b35a0c73a045d45979a", value = "회원 ID") + private String id; + @ApiModelProperty(required = true, example = "example@jakduk.com") @Size(min = 6, max=30) @NotEmpty @@ -45,4 +48,5 @@ public class SocialUserForm { @ApiModelProperty(example = "https://img1.daumcdn.net/thumb/R158x158/?fname=http%3A%2F%2Ftwg.tset.daumcdn.net%2Fprofile%2FSjuNejHmr8o0&t=1488000722876", value = "SNS계정의 회원 큰 사진") private String externalLargePictureUrl; + } diff --git a/build.gradle b/build.gradle index 465d5f91..fb46e3d8 100644 --- a/build.gradle +++ b/build.gradle @@ -50,6 +50,7 @@ subprojects { compile 'org.apache.httpcomponents:httpclient:4.5.2' compile 'org.apache.commons:commons-lang3:3.5' compile 'org.apache.commons:commons-collections4:4.1' + compile 'org.apache.commons:commons-io:1.3.2' compile 'commons-beanutils:commons-beanutils:1.9.3' compile 'com.rometools:rome:1.7.0' compile group: 'net.gpedro.integrations.slack', name: 'slack-webhook', version:'1.2.1'