From a06815111594d4e3e85d81de420d3babd7486a09 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:59:47 +0900 Subject: [PATCH 01/30] =?UTF-8?q?feat:=20sign=20up=20dto=20->=20phone=20ve?= =?UTF-8?q?rification=20dto=20from=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java index 989a6e0ad..91054a52c 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java @@ -56,6 +56,9 @@ public record VerifyCodeReq( @Pattern(regexp = "^\\d{6}$", message = "인증번호는 6자리 숫자여야 합니다.") String code ) { + public static VerifyCodeReq from(SignUpReq.General request) { + return new VerifyCodeReq(request.phone(), request.code()); + } } @Schema(title = "인증번호 검증 응답 DTO") From 46a7f941cd8b365352acc957d17533c29aa5a677 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:05:59 +0900 Subject: [PATCH 02/30] =?UTF-8?q?fix:=20helper=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B1=85=EC=9E=84=EA=B3=BC=20=EC=97=AD=ED=95=A0=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apis/auth/helper/UserSignInHelper.java | 41 +++++++++++++++++++ .../api/apis/auth/helper/UserSyncHelper.java | 28 ++----------- 2 files changed, 44 insertions(+), 25 deletions(-) create mode 100644 pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSignInHelper.java diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSignInHelper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSignInHelper.java new file mode 100644 index 000000000..edbe87c37 --- /dev/null +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSignInHelper.java @@ -0,0 +1,41 @@ +package kr.co.pennyway.api.apis.auth.helper; + +import kr.co.pennyway.common.annotation.Helper; +import kr.co.pennyway.domain.domains.user.domain.User; +import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; +import kr.co.pennyway.domain.domains.user.exception.UserErrorException; +import kr.co.pennyway.domain.domains.user.service.UserService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Helper +@RequiredArgsConstructor +public class UserSignInHelper { + private final UserService userService; + + private final PasswordEncoder bCryptPasswordEncoder; + + /** + * 로그인 시 유저가 존재하고 비밀번호가 일치하는지 확인 + */ + @Transactional(readOnly = true) + public User readUserIfValid(String username, String password) { + User user; + + try { + user = userService.readUserByUsername(username); + + if (!bCryptPasswordEncoder.matches(password, user.getPassword())) { + throw new UserErrorException(UserErrorCode.NOT_MATCHED_PASSWORD); + } + } catch (UserErrorException e) { + log.warn("request not valid : {} : {}", username, e.getExplainError()); + throw new UserErrorException(UserErrorCode.INVALID_USERNAME_OR_PASSWORD); + } + + return user; + } +} diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java index 7778f4fff..81b32c8ed 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java @@ -9,17 +9,16 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.transaction.annotation.Transactional; +/** + * 일반 회원가입, Oauth 회원가입 시나리오를 제어하여 유저 정보를 동기화하는 Helper + */ @Slf4j @Helper @RequiredArgsConstructor public class UserSyncHelper { private final UserService userService; - private final PasswordEncoder bCryptPasswordEncoder; - /** * 일반 회원가입 시 이미 가입된 회원인지 확인 * @@ -44,25 +43,4 @@ public Pair isSignedUserWhenGeneral(String phone) { return Pair.of(Boolean.TRUE, user.getUsername()); } - - /** - * 로그인 시 유저가 존재하고 비밀번호가 일치하는지 확인 - */ - @Transactional(readOnly = true) - public User readUserIfValid(String username, String password) { - User user; - - try { - user = userService.readUserByUsername(username); - - if (!bCryptPasswordEncoder.matches(password, user.getPassword())) { - throw new UserErrorException(UserErrorCode.NOT_MATCHED_PASSWORD); - } - } catch (UserErrorException e) { - log.warn("request not valid : {} : {}", username, e.getExplainError()); - throw new UserErrorException(UserErrorCode.INVALID_USERNAME_OR_PASSWORD); - } - - return user; - } } From b9201ba2a3784f5b989b8341d275e5332004d538 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:39:20 +0900 Subject: [PATCH 03/30] =?UTF-8?q?rename:=20user=20sync=20helper=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=AA=85=EC=8B=9C?= =?UTF-8?q?=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java | 4 ++-- .../pennyway/api/apis/auth/helper/UserSyncHelperTest.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java index 81b32c8ed..641f10ad3 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java @@ -20,14 +20,14 @@ public class UserSyncHelper { private final UserService userService; /** - * 일반 회원가입 시 이미 가입된 회원인지 확인 + * 일반 회원가입이 가능한 유저인지 확인 * * @param phone String : 전화번호 * @return Pair : 이미 가입된 회원인지 여부 (TRUE: 가입되지 않은 회원, FALSE: 가입된 회원), 가입된 회원인 경우 회원 * ID 반환 * @throws UserErrorException : 이미 일반 회원가입을 한 유저인 경우 */ - public Pair isSignedUserWhenGeneral(String phone) { + public Pair isGeneralSignUpAllowed(String phone) { User user; try { user = userService.readUserByPhone(phone); diff --git a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelperTest.java b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelperTest.java index 4e28c2cfe..5724560fb 100644 --- a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelperTest.java +++ b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelperTest.java @@ -38,7 +38,7 @@ void isSignedUserWhenGeneralReturnFalse() { new UserErrorException(UserErrorCode.NOT_FOUND)); // when - Boolean result = userSyncHelper.isSignedUserWhenGeneral(phone).getKey(); + Boolean result = userSyncHelper.isGeneralSignUpAllowed(phone).getKey(); // then assertEquals(result, Boolean.FALSE); @@ -51,7 +51,7 @@ void isSignedUserWhenGeneralReturnTrue() { given(userService.readUserByPhone(phone)).willReturn(User.builder().password(null).build()); // when - Boolean result = userSyncHelper.isSignedUserWhenGeneral(phone).getKey(); + Boolean result = userSyncHelper.isGeneralSignUpAllowed(phone).getKey(); // then assertEquals(result, Boolean.TRUE); @@ -66,7 +66,7 @@ void isSignedUserWhenGeneralThrowUserErrorException() { // when - then UserErrorException exception = org.junit.jupiter.api.Assertions.assertThrows( - UserErrorException.class, () -> userSyncHelper.isSignedUserWhenGeneral(phone)); + UserErrorException.class, () -> userSyncHelper.isGeneralSignUpAllowed(phone)); System.out.println(exception.getExplainError()); } From e2c68ec783389c892a0eb880054a6a6fa5490766 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:40:31 +0900 Subject: [PATCH 04/30] =?UTF-8?q?fix:=20sign=20up=20dto=20password=20?= =?UTF-8?q?=EC=95=94=ED=98=B8=ED=99=94=20=ED=9B=84=20entity=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java index 8fe879f90..7be5be444 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java @@ -7,6 +7,7 @@ import kr.co.pennyway.domain.domains.user.domain.User; import kr.co.pennyway.domain.domains.user.type.ProfileVisibility; import kr.co.pennyway.domain.domains.user.type.Role; +import org.springframework.security.crypto.password.PasswordEncoder; /** * 회원가입 요청 Dto @@ -37,11 +38,11 @@ public record General( @Pattern(regexp = "^\\d{6}$", message = "인증번호는 6자리 숫자여야 합니다.") String code ) { - public User toEntity() { + public User toEntity(PasswordEncoder bCryptPasswordEncoder) { return User.builder() .username(username) .name(name) - .password(password) + .password(bCryptPasswordEncoder.encode(password)) .phone(phone) .role(Role.USER) .profileVisibility(ProfileVisibility.PUBLIC) From 213d5490e096bee7858f1714ea3ce8dc923a20ff Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:44:16 +0900 Subject: [PATCH 05/30] =?UTF-8?q?fix:=20=EC=9D=BC=EB=B0=98=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85,=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=9C=EB=82=98=EB=A6=AC=EC=98=A4=20helper=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ignInHelper.java => UserGeneralSignHelper.java} | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) rename pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/{UserSignInHelper.java => UserGeneralSignHelper.java} (78%) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSignInHelper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java similarity index 78% rename from pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSignInHelper.java rename to pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java index edbe87c37..82f8af0e7 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSignInHelper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java @@ -1,5 +1,6 @@ package kr.co.pennyway.api.apis.auth.helper; +import kr.co.pennyway.api.apis.auth.dto.SignUpReq; import kr.co.pennyway.common.annotation.Helper; import kr.co.pennyway.domain.domains.user.domain.User; import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; @@ -10,14 +11,25 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.transaction.annotation.Transactional; +/** + * 일반 회원가입, 로그인 시나리오 도우미 클래스 + * + * @author YANG JAESEO + */ @Slf4j @Helper @RequiredArgsConstructor -public class UserSignInHelper { +public class UserGeneralSignHelper { private final UserService userService; private final PasswordEncoder bCryptPasswordEncoder; + @Transactional + public User createUserWithEncryptedPassword(SignUpReq.General request) { + User user = request.toEntity(bCryptPasswordEncoder); + return userService.createUser(user); + } + /** * 로그인 시 유저가 존재하고 비밀번호가 일치하는지 확인 */ From 3d246a8f05283b00df7029edc09a7fa9ec3501fb Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:02:35 +0900 Subject: [PATCH 06/30] =?UTF-8?q?fix:=20=EC=9D=BC=EB=B0=98=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85,=20oauth=20=EA=B3=84=EC=A0=95=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=20=EC=8B=9C=EB=82=98=EB=A6=AC=EC=98=A4?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EA=B2=8C=20dto=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?=ED=9B=84=20info=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20?= =?UTF-8?q?=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pennyway/api/apis/auth/dto/SignUpReq.java | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java index 7be5be444..15b071a9e 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java @@ -15,6 +15,28 @@ * 일반 회원가입 시엔 General, 소셜 회원가입 시엔 Oauth를 사용합니다. */ public class SignUpReq { + public record Info(String username, String name, String password, String phone, String code) { + public String password(PasswordEncoder passwordEncoder) { + return passwordEncoder.encode(password); + } + + public User toEntity(PasswordEncoder bCryptPasswordEncoder) { + return User.builder() + .username(username) + .name(name) + .password(bCryptPasswordEncoder.encode(password)) + .phone(phone) + .role(Role.USER) + .profileVisibility(ProfileVisibility.PUBLIC) + .build(); + } + + @Override + public String password() { + throw new UnsupportedOperationException("Not supported yet."); + } + } + @Schema(title = "일반 회원가입 요청 DTO") public record General( @Schema(description = "아이디", example = "pennyway") @@ -38,17 +60,21 @@ public record General( @Pattern(regexp = "^\\d{6}$", message = "인증번호는 6자리 숫자여야 합니다.") String code ) { - public User toEntity(PasswordEncoder bCryptPasswordEncoder) { - return User.builder() - .username(username) - .name(name) - .password(bCryptPasswordEncoder.encode(password)) - .phone(phone) - .role(Role.USER) - .profileVisibility(ProfileVisibility.PUBLIC) - .build(); + public Info toInfo() { + return new Info(username, name, password, phone, code); } + } + @Schema(title = "일반 회원가입(소셜 계정 존재) 요청 DTO") + public record SyncWithOauth( + @Schema(description = "비밀번호", example = "pennyway1234") + @NotBlank(message = "비밀번호를 입력해주세요") + @Password(message = "8~16자의 영문 대/소문자, 숫자, 특수문자를 사용해주세요. (적어도 하나의 영문 소문자, 숫자 포함)") + String password + ) { + public Info toInfo(String username, String name, String phone, String code) { + return new Info(null, null, password, null, null); + } } @Schema(title = "소셜 회원가입 요청 DTO") From 1a6c61b77ce35597800cf91343eabc8cd61147e0 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:04:32 +0900 Subject: [PATCH 07/30] =?UTF-8?q?fix:=20oauth=20=EC=97=B0=EB=8F=99=20dto?= =?UTF-8?q?=20->=20phone,=20code=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/pennyway/api/apis/auth/dto/SignUpReq.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java index 15b071a9e..dd764ff67 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java @@ -70,10 +70,18 @@ public record SyncWithOauth( @Schema(description = "비밀번호", example = "pennyway1234") @NotBlank(message = "비밀번호를 입력해주세요") @Password(message = "8~16자의 영문 대/소문자, 숫자, 특수문자를 사용해주세요. (적어도 하나의 영문 소문자, 숫자 포함)") - String password + String password, + @Schema(description = "전화번호", example = "010-1234-5678") + @NotBlank(message = "전화번호를 입력해주세요") + @Pattern(regexp = "^01[01]-\\d{4}-\\d{4}$", message = "전화번호 형식이 올바르지 않습니다.") + String phone, + @Schema(description = "6자리 정수 인증번호", example = "123456") + @NotBlank(message = "인증번호는 필수입니다.") + @Pattern(regexp = "^\\d{6}$", message = "인증번호는 6자리 숫자여야 합니다.") + String code ) { public Info toInfo(String username, String name, String phone, String code) { - return new Info(null, null, password, null, null); + return new Info(null, null, password, phone, code); } } From 1832507e2ae196b597e46c08de040a9be642a9a8 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:05:13 +0900 Subject: [PATCH 08/30] =?UTF-8?q?fix:=20sign=20up=20api=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85=20=EC=9A=94=EC=B2=AD=20=EC=9D=B8?= =?UTF-8?q?=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/pennyway/api/apis/auth/controller/AuthController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/controller/AuthController.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/controller/AuthController.java index 7d96501b5..170285fba 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/controller/AuthController.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/controller/AuthController.java @@ -52,7 +52,7 @@ public ResponseEntity verifyCode(@RequestBody @Validated PhoneVerificationDto @PostMapping("/sign-up") @PreAuthorize("isAnonymous()") public ResponseEntity signUp(@RequestBody @Validated SignUpReq.General request) { - Pair jwts = authUseCase.signUp(request); + Pair jwts = authUseCase.signUp(request.toInfo()); ResponseCookie cookie = cookieUtil.createCookie("refreshToken", jwts.getValue().refreshToken(), Duration.ofDays(7).toSeconds()); return ResponseEntity.ok() From 544c71c57b552c6f8935ce1e4a62c8d95819d900 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:06:35 +0900 Subject: [PATCH 09/30] =?UTF-8?q?fix:=20=EC=84=9C=EB=AA=85=20=ED=97=AC?= =?UTF-8?q?=ED=8D=BC=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=A7=A4=EA=B0=9C?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java index 82f8af0e7..6b0ea022a 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java @@ -25,7 +25,7 @@ public class UserGeneralSignHelper { private final PasswordEncoder bCryptPasswordEncoder; @Transactional - public User createUserWithEncryptedPassword(SignUpReq.General request) { + public User createUserWithEncryptedPassword(SignUpReq.Info request) { User user = request.toEntity(bCryptPasswordEncoder); return userService.createUser(user); } From a56c837b24827d6a7a5680836fd3fe2c5755c8b2 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:10:20 +0900 Subject: [PATCH 10/30] =?UTF-8?q?feat:=20user=20domain=20=EB=B9=84?= =?UTF-8?q?=EB=B0=80=EB=B2=88=ED=98=B8=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/pennyway/domain/domains/user/domain/User.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/domains/user/domain/User.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/domains/user/domain/User.java index 41d4a6a25..e3afcc2b4 100644 --- a/pennyway-domain/src/main/java/kr/co/pennyway/domain/domains/user/domain/User.java +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/domains/user/domain/User.java @@ -29,7 +29,6 @@ public class User extends DateAuditable { private String name; @ColumnDefault("NULL") private String password; - @ColumnDefault("NULL") private LocalDateTime passwordUpdatedAt; @ColumnDefault("NULL") private String profileImageUrl; @@ -59,4 +58,9 @@ private User(String username, String name, String password, LocalDateTime passwo this.locked = locked; this.deletedAt = deletedAt; } + + public void updatePassword(String password) { + this.password = password; + this.passwordUpdatedAt = LocalDateTime.now(); + } } From 988004a0357a3d18e47f4951b0b0c912562c7fab Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:11:28 +0900 Subject: [PATCH 11/30] =?UTF-8?q?fix:=20dto=EC=97=90=EC=84=9C=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=EC=83=9D=EC=84=B1=20=EC=8B=9C,=20password=20update?= =?UTF-8?q?=20at=20=EA=B0=B1=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java index dd764ff67..e7febacca 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java @@ -9,6 +9,8 @@ import kr.co.pennyway.domain.domains.user.type.Role; import org.springframework.security.crypto.password.PasswordEncoder; +import java.time.LocalDateTime; + /** * 회원가입 요청 Dto *
@@ -25,6 +27,7 @@ public User toEntity(PasswordEncoder bCryptPasswordEncoder) { .username(username) .name(name) .password(bCryptPasswordEncoder.encode(password)) + .passwordUpdatedAt(LocalDateTime.now()) .phone(phone) .role(Role.USER) .profileVisibility(ProfileVisibility.PUBLIC) From d087f8979d510e9fd964331245d6d23cb3e65cb7 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:15:58 +0900 Subject: [PATCH 12/30] =?UTF-8?q?feat:=20=EC=9D=BC=EB=B0=98=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85=20=EB=8F=84=EC=9A=B0=EB=AF=B8=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84=EA=B8=B0=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/helper/UserGeneralSignHelper.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java index 6b0ea022a..befec10ab 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java @@ -8,6 +8,7 @@ import kr.co.pennyway.domain.domains.user.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.transaction.annotation.Transactional; @@ -24,10 +25,23 @@ public class UserGeneralSignHelper { private final PasswordEncoder bCryptPasswordEncoder; + /** + * 일반 회원가입이라면 새롭게 유저를 생성하고, 기존 Oauth 유저라면 비밀번호를 업데이트한다. + * + * @param request {@link SignUpReq.Info} + */ @Transactional - public User createUserWithEncryptedPassword(SignUpReq.Info request) { - User user = request.toEntity(bCryptPasswordEncoder); - return userService.createUser(user); + public User createUserWithEncryptedPassword(SignUpReq.Info request, Pair isOauthUser) { + User user; + + if (isOauthUser.getLeft().equals(Boolean.TRUE)) { + user = userService.readUserByUsername(isOauthUser.getRight()); + user.updatePassword(request.password(bCryptPasswordEncoder)); + } else { + user = userService.createUser(request.toEntity(bCryptPasswordEncoder)); + } + + return user; } /** From 10ec483ccde38da31e0a759e24415405c569003c Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:21:12 +0900 Subject: [PATCH 13/30] =?UTF-8?q?rename:=20helper,=20mapper=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=9E=AC=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JwtAuthHelper.java} | 10 +++++----- .../UserGeneralSignMapper.java} | 8 ++++---- .../UserSyncMapper.java} | 8 ++++---- ...elperTest.java => UserSyncMapperTest.java} | 19 ++++++++++--------- 4 files changed, 23 insertions(+), 22 deletions(-) rename pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/{mapper/JwtAuthMapper.java => helper/JwtAuthHelper.java} (92%) rename pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/{helper/UserGeneralSignHelper.java => mapper/UserGeneralSignMapper.java} (94%) rename pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/{helper/UserSyncHelper.java => mapper/UserSyncMapper.java} (92%) rename pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/{UserSyncHelperTest.java => UserSyncMapperTest.java} (87%) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/JwtAuthMapper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/JwtAuthHelper.java similarity index 92% rename from pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/JwtAuthMapper.java rename to pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/JwtAuthHelper.java index 4d1ab9fbf..2cbd4fbdf 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/JwtAuthMapper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/JwtAuthHelper.java @@ -1,11 +1,11 @@ -package kr.co.pennyway.api.apis.auth.mapper; +package kr.co.pennyway.api.apis.auth.helper; import kr.co.pennyway.api.common.annotation.AccessTokenStrategy; import kr.co.pennyway.api.common.annotation.RefreshTokenStrategy; import kr.co.pennyway.api.common.security.jwt.Jwts; import kr.co.pennyway.api.common.security.jwt.access.AccessTokenClaim; import kr.co.pennyway.api.common.security.jwt.refresh.RefreshTokenClaim; -import kr.co.pennyway.common.annotation.Mapper; +import kr.co.pennyway.common.annotation.Helper; import kr.co.pennyway.domain.common.redis.refresh.RefreshToken; import kr.co.pennyway.domain.common.redis.refresh.RefreshTokenService; import kr.co.pennyway.domain.domains.user.domain.User; @@ -16,13 +16,13 @@ import java.time.LocalDateTime; @Slf4j -@Mapper -public class JwtAuthMapper { +@Helper +public class JwtAuthHelper { private final JwtProvider accessTokenProvider; private final JwtProvider refreshTokenProvider; private final RefreshTokenService refreshTokenService; - public JwtAuthMapper( + public JwtAuthHelper( @AccessTokenStrategy JwtProvider accessTokenProvider, @RefreshTokenStrategy JwtProvider refreshTokenProvider, RefreshTokenService refreshTokenService diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java similarity index 94% rename from pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java rename to pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java index befec10ab..46bca30ad 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserGeneralSignHelper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java @@ -1,7 +1,7 @@ -package kr.co.pennyway.api.apis.auth.helper; +package kr.co.pennyway.api.apis.auth.mapper; import kr.co.pennyway.api.apis.auth.dto.SignUpReq; -import kr.co.pennyway.common.annotation.Helper; +import kr.co.pennyway.common.annotation.Mapper; import kr.co.pennyway.domain.domains.user.domain.User; import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; import kr.co.pennyway.domain.domains.user.exception.UserErrorException; @@ -18,9 +18,9 @@ * @author YANG JAESEO */ @Slf4j -@Helper +@Mapper @RequiredArgsConstructor -public class UserGeneralSignHelper { +public class UserGeneralSignMapper { private final UserService userService; private final PasswordEncoder bCryptPasswordEncoder; diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java similarity index 92% rename from pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java rename to pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java index 641f10ad3..b59aeb899 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java @@ -1,6 +1,6 @@ -package kr.co.pennyway.api.apis.auth.helper; +package kr.co.pennyway.api.apis.auth.mapper; -import kr.co.pennyway.common.annotation.Helper; +import kr.co.pennyway.common.annotation.Mapper; import kr.co.pennyway.common.exception.GlobalErrorException; import kr.co.pennyway.domain.domains.user.domain.User; import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; @@ -14,9 +14,9 @@ * 일반 회원가입, Oauth 회원가입 시나리오를 제어하여 유저 정보를 동기화하는 Helper */ @Slf4j -@Helper +@Mapper @RequiredArgsConstructor -public class UserSyncHelper { +public class UserSyncMapper { private final UserService userService; /** diff --git a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelperTest.java b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncMapperTest.java similarity index 87% rename from pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelperTest.java rename to pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncMapperTest.java index 5724560fb..d79cb982c 100644 --- a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncHelperTest.java +++ b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncMapperTest.java @@ -1,5 +1,6 @@ package kr.co.pennyway.api.apis.auth.helper; +import kr.co.pennyway.api.apis.auth.mapper.UserSyncMapper; import kr.co.pennyway.domain.domains.user.domain.User; import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; import kr.co.pennyway.domain.domains.user.exception.UserErrorException; @@ -17,9 +18,9 @@ import static org.mockito.BDDMockito.given; @ExtendWith(MockitoExtension.class) -public class UserSyncHelperTest { +public class UserSyncMapperTest { private final String phone = "010-1234-5678"; - private UserSyncHelper userSyncHelper; + private UserSyncMapper userSyncMapper; @Mock private UserService userService; @Mock @@ -27,7 +28,7 @@ public class UserSyncHelperTest { @BeforeEach void setUp() { - userSyncHelper = new UserSyncHelper(userService, bCryptPasswordEncoder); + userSyncMapper = new UserSyncMapper(userService, bCryptPasswordEncoder); } @DisplayName("일반 회원가입 시, 회원 정보가 없으면 FALSE를 반환한다.") @@ -38,7 +39,7 @@ void isSignedUserWhenGeneralReturnFalse() { new UserErrorException(UserErrorCode.NOT_FOUND)); // when - Boolean result = userSyncHelper.isGeneralSignUpAllowed(phone).getKey(); + Boolean result = userSyncMapper.isGeneralSignUpAllowed(phone).getKey(); // then assertEquals(result, Boolean.FALSE); @@ -51,7 +52,7 @@ void isSignedUserWhenGeneralReturnTrue() { given(userService.readUserByPhone(phone)).willReturn(User.builder().password(null).build()); // when - Boolean result = userSyncHelper.isGeneralSignUpAllowed(phone).getKey(); + Boolean result = userSyncMapper.isGeneralSignUpAllowed(phone).getKey(); // then assertEquals(result, Boolean.TRUE); @@ -66,7 +67,7 @@ void isSignedUserWhenGeneralThrowUserErrorException() { // when - then UserErrorException exception = org.junit.jupiter.api.Assertions.assertThrows( - UserErrorException.class, () -> userSyncHelper.isGeneralSignUpAllowed(phone)); + UserErrorException.class, () -> userSyncMapper.isGeneralSignUpAllowed(phone)); System.out.println(exception.getExplainError()); } @@ -79,7 +80,7 @@ void readUserIfValidReturnUser() { given(bCryptPasswordEncoder.matches("password", user.getPassword())).willReturn(true); // when - User result = userSyncHelper.readUserIfValid("pennyway", "password"); + User result = userSyncMapper.readUserIfValid("pennyway", "password"); // then assertEquals(result, user); @@ -94,7 +95,7 @@ void readUserIfNotFound() { new UserErrorException(UserErrorCode.NOT_FOUND)); // when - then - UserErrorException exception = assertThrows(UserErrorException.class, () -> userSyncHelper.readUserIfValid("pennyway", "password")); + UserErrorException exception = assertThrows(UserErrorException.class, () -> userSyncMapper.readUserIfValid("pennyway", "password")); System.out.println(exception.getExplainError()); } @@ -107,7 +108,7 @@ void readUserIfNotMatchedPassword() { given(bCryptPasswordEncoder.matches("password", user.getPassword())).willReturn(false); // when - then - UserErrorException exception = assertThrows(UserErrorException.class, () -> userSyncHelper.readUserIfValid("pennyway", "password")); + UserErrorException exception = assertThrows(UserErrorException.class, () -> userSyncMapper.readUserIfValid("pennyway", "password")); System.out.println(exception.getExplainError()); } } From d3128dd3a20dee28cf3c9f12645846a6b2fd2d5d Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:23:32 +0900 Subject: [PATCH 14/30] =?UTF-8?q?fix:=20=EC=A0=84=ED=99=94=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=9A=94=EC=B2=AD=20=EC=BD=94=EB=93=9C=20=EC=A0=95?= =?UTF-8?q?=EC=A0=81=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=A7=A4=EA=B0=9C?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java index 91054a52c..08975e749 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/PhoneVerificationDto.java @@ -56,7 +56,7 @@ public record VerifyCodeReq( @Pattern(regexp = "^\\d{6}$", message = "인증번호는 6자리 숫자여야 합니다.") String code ) { - public static VerifyCodeReq from(SignUpReq.General request) { + public static VerifyCodeReq from(SignUpReq.Info request) { return new VerifyCodeReq(request.phone(), request.code()); } } From 18f2dc10f555d88d552db10f2fba92fa951bef63 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:24:48 +0900 Subject: [PATCH 15/30] =?UTF-8?q?rename:=20user=20general=20sign=20mapper?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20create=20->=20save(=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=ED=98=B9=EC=9D=80=20=EC=88=98=EC=A0=95=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java index 46bca30ad..e9e0eac83 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java @@ -31,7 +31,7 @@ public class UserGeneralSignMapper { * @param request {@link SignUpReq.Info} */ @Transactional - public User createUserWithEncryptedPassword(SignUpReq.Info request, Pair isOauthUser) { + public User saveUserWithEncryptedPassword(SignUpReq.Info request, Pair isOauthUser) { User user; if (isOauthUser.getLeft().equals(Boolean.TRUE)) { From 2ceae9d53efa292721267cd77d63c546df0146a4 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:39:48 +0900 Subject: [PATCH 16/30] =?UTF-8?q?fix:=20sync=20with=20oauth=20dto=EC=9D=98?= =?UTF-8?q?=20to=20info=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=9D=B8=EC=9E=90?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java index e7febacca..fe234eddf 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/dto/SignUpReq.java @@ -83,7 +83,7 @@ public record SyncWithOauth( @Pattern(regexp = "^\\d{6}$", message = "인증번호는 6자리 숫자여야 합니다.") String code ) { - public Info toInfo(String username, String name, String phone, String code) { + public Info toInfo() { return new Info(null, null, password, phone, code); } } From dcb63391cead3a7447d2c3dc987a588aded8f4d3 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:42:54 +0900 Subject: [PATCH 17/30] =?UTF-8?q?feat:=20=EA=B8=B0=EC=A1=B4=20=EC=86=8C?= =?UTF-8?q?=EC=85=9C=20=EA=B3=84=EC=A0=95=20=EC=97=B0=EB=8F=99=20api=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20&&=20=EC=9D=B8=EC=A6=9D=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20=EC=83=9D=EC=84=B1=20=EB=8F=84=EC=9A=B0=EB=AF=B8=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apis/auth/controller/AuthController.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/controller/AuthController.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/controller/AuthController.java index 170285fba..e88c90981 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/controller/AuthController.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/controller/AuthController.java @@ -52,27 +52,29 @@ public ResponseEntity verifyCode(@RequestBody @Validated PhoneVerificationDto @PostMapping("/sign-up") @PreAuthorize("isAnonymous()") public ResponseEntity signUp(@RequestBody @Validated SignUpReq.General request) { - Pair jwts = authUseCase.signUp(request.toInfo()); - ResponseCookie cookie = cookieUtil.createCookie("refreshToken", jwts.getValue().refreshToken(), Duration.ofDays(7).toSeconds()); + return createAuthenticatedResponse(authUseCase.signUp(request.toInfo())); + } - return ResponseEntity.ok() - .header(HttpHeaders.SET_COOKIE, cookie.toString()) - .header(HttpHeaders.AUTHORIZATION, jwts.getValue().accessToken()) - .body(SuccessResponse.from("user", Map.of("id", jwts.getKey()))) - ; + @Operation(summary = "기존 소셜 계정에 일반 계정을 연동하는 회원가입") + @PostMapping("/link-oauth") + @PreAuthorize("isAnonymous()") + public ResponseEntity linkOauth(@RequestBody @Validated SignUpReq.SyncWithOauth request) { + return createAuthenticatedResponse(authUseCase.signUp(request.toInfo())); } @Operation(summary = "일반 로그인") @PostMapping("/sign-in") @PreAuthorize("isAnonymous()") public ResponseEntity signIn(@RequestBody @Validated SignInReq.General request) { - Pair jwts = authUseCase.signIn(request); - ResponseCookie cookie = cookieUtil.createCookie("refreshToken", jwts.getValue().refreshToken(), Duration.ofDays(7).toSeconds()); + return createAuthenticatedResponse(authUseCase.signIn(request)); + } + private ResponseEntity createAuthenticatedResponse(Pair userInfo) { + ResponseCookie cookie = cookieUtil.createCookie("refreshToken", userInfo.getValue().refreshToken(), Duration.ofDays(7).toSeconds()); return ResponseEntity.ok() .header(HttpHeaders.SET_COOKIE, cookie.toString()) - .header(HttpHeaders.AUTHORIZATION, jwts.getValue().accessToken()) - .body(SuccessResponse.from("user", Map.of("id", jwts.getKey()))) + .header(HttpHeaders.AUTHORIZATION, userInfo.getValue().accessToken()) + .body(SuccessResponse.from("user", Map.of("id", userInfo.getKey()))) ; } } From 850fdc068cbba16b76fa6a3b00d4db8069ea3efe Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:45:32 +0900 Subject: [PATCH 18/30] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=8B=9C=EB=82=98=EB=A6=AC=EC=98=A4=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/apis/auth/usecase/AuthUseCase.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/usecase/AuthUseCase.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/usecase/AuthUseCase.java index a1693ef5b..4a0e0efaf 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/usecase/AuthUseCase.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/usecase/AuthUseCase.java @@ -3,16 +3,16 @@ import kr.co.pennyway.api.apis.auth.dto.PhoneVerificationDto; import kr.co.pennyway.api.apis.auth.dto.SignInReq; import kr.co.pennyway.api.apis.auth.dto.SignUpReq; -import kr.co.pennyway.api.apis.auth.helper.UserSyncHelper; -import kr.co.pennyway.api.apis.auth.mapper.JwtAuthMapper; +import kr.co.pennyway.api.apis.auth.helper.JwtAuthHelper; import kr.co.pennyway.api.apis.auth.mapper.PhoneVerificationMapper; +import kr.co.pennyway.api.apis.auth.mapper.UserGeneralSignMapper; +import kr.co.pennyway.api.apis.auth.mapper.UserSyncMapper; import kr.co.pennyway.api.common.security.jwt.Jwts; import kr.co.pennyway.common.annotation.UseCase; import kr.co.pennyway.domain.common.redis.phone.PhoneVerificationService; import kr.co.pennyway.domain.common.redis.phone.PhoneVerificationType; import kr.co.pennyway.domain.domains.user.domain.User; import kr.co.pennyway.domain.domains.user.exception.UserErrorException; -import kr.co.pennyway.domain.domains.user.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; @@ -22,47 +22,47 @@ @UseCase @RequiredArgsConstructor public class AuthUseCase { - private final UserService userService; - private final UserSyncHelper userSyncHelper; + private final UserSyncMapper userSyncMapper; + private final UserGeneralSignMapper userGeneralSignMapper; - private final JwtAuthMapper jwtAuthMapper; + private final JwtAuthHelper jwtAuthHelper; private final PhoneVerificationMapper phoneVerificationMapper; private final PhoneVerificationService phoneVerificationService; - public PhoneVerificationDto.PushCodeRes sendCode(PhoneVerificationDto.PushCodeReq request) { return phoneVerificationMapper.sendCode(request, PhoneVerificationType.SIGN_UP); } public PhoneVerificationDto.VerifyCodeRes verifyCode(PhoneVerificationDto.VerifyCodeReq request) { Boolean isValidCode = phoneVerificationMapper.isValidCode(request, PhoneVerificationType.SIGN_UP); - Pair isOauthUser = checkOauthUser(request.phone()); + Pair isOauthUser = checkOauthUserNotGeneralSignUp(request.phone()); phoneVerificationService.extendTimeToLeave(request.phone(), PhoneVerificationType.SIGN_UP); - return PhoneVerificationDto.VerifyCodeRes.valueOf(isValidCode, isOauthUser.getKey(), isOauthUser.getValue()); + return PhoneVerificationDto.VerifyCodeRes.valueOf(isValidCode, isOauthUser.getLeft(), isOauthUser.getRight()); } @Transactional - public Pair signUp(SignUpReq.General request) { - // TODO: 인증 번호 확인 로직 추가 - // phoneVerificationHelper.verify(request.phone(), request.code()); + public Pair signUp(SignUpReq.Info request) { + phoneVerificationMapper.isValidCode(PhoneVerificationDto.VerifyCodeReq.from(request), PhoneVerificationType.SIGN_UP); + Pair isOauthUser = checkOauthUserNotGeneralSignUp(request.phone()); - User user = userService.createUser(request.toEntity()); + User user = userGeneralSignMapper.saveUserWithEncryptedPassword(request, isOauthUser); + phoneVerificationService.delete(request.phone(), PhoneVerificationType.SIGN_UP); - return Pair.of(user.getId(), jwtAuthMapper.createToken(user)); + return Pair.of(user.getId(), jwtAuthHelper.createToken(user)); } @Transactional(readOnly = true) public Pair signIn(SignInReq.General request) { - User user = userSyncHelper.readUserIfValid(request.username(), request.password()); + User user = userGeneralSignMapper.readUserIfValid(request.username(), request.password()); - return Pair.of(user.getId(), jwtAuthMapper.createToken(user)); + return Pair.of(user.getId(), jwtAuthHelper.createToken(user)); } - private Pair checkOauthUser(String phone) { + private Pair checkOauthUserNotGeneralSignUp(String phone) { try { - return userSyncHelper.isSignedUserWhenGeneral(phone); + return userSyncMapper.isGeneralSignUpAllowed(phone); } catch (UserErrorException e) { phoneVerificationService.delete(phone, PhoneVerificationType.SIGN_UP); throw e; From 849a4eb16675fb0f968bb8f4ddca7ff849650be4 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:08:55 +0900 Subject: [PATCH 19/30] =?UTF-8?q?test:=20user=20sync=20mapper=20test=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UserSyncMapperTest.java | 50 +------------------ 1 file changed, 2 insertions(+), 48 deletions(-) rename pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/{helper => mapper}/UserSyncMapperTest.java (51%) diff --git a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncMapperTest.java b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapperTest.java similarity index 51% rename from pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncMapperTest.java rename to pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapperTest.java index d79cb982c..b7cf2641a 100644 --- a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/helper/UserSyncMapperTest.java +++ b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapperTest.java @@ -1,6 +1,5 @@ -package kr.co.pennyway.api.apis.auth.helper; +package kr.co.pennyway.api.apis.auth.mapper; -import kr.co.pennyway.api.apis.auth.mapper.UserSyncMapper; import kr.co.pennyway.domain.domains.user.domain.User; import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; import kr.co.pennyway.domain.domains.user.exception.UserErrorException; @@ -11,10 +10,8 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.BDDMockito.given; @ExtendWith(MockitoExtension.class) @@ -23,12 +20,10 @@ public class UserSyncMapperTest { private UserSyncMapper userSyncMapper; @Mock private UserService userService; - @Mock - private BCryptPasswordEncoder bCryptPasswordEncoder; @BeforeEach void setUp() { - userSyncMapper = new UserSyncMapper(userService, bCryptPasswordEncoder); + userSyncMapper = new UserSyncMapper(userService); } @DisplayName("일반 회원가입 시, 회원 정보가 없으면 FALSE를 반환한다.") @@ -70,45 +65,4 @@ void isSignedUserWhenGeneralThrowUserErrorException() { UserErrorException.class, () -> userSyncMapper.isGeneralSignUpAllowed(phone)); System.out.println(exception.getExplainError()); } - - @DisplayName("로그인 시, 유저가 존재하고 비밀번호가 일치하면 User를 반환한다.") - @Test - void readUserIfValidReturnUser() { - // given - User user = User.builder().username("pennyway").password("password").build(); - given(userService.readUserByUsername("pennyway")).willReturn(user); - given(bCryptPasswordEncoder.matches("password", user.getPassword())).willReturn(true); - - // when - User result = userSyncMapper.readUserIfValid("pennyway", "password"); - - // then - assertEquals(result, user); - } - - @DisplayName("로그인 시, username에 해당하는 유저가 존재하지 않으면 UserErrorException을 발생시킨다.") - @Test - void readUserIfNotFound() { - // given - User user = User.builder().username("pennyway").password("password").build(); - given(userService.readUserByUsername("pennyway")).willThrow( - new UserErrorException(UserErrorCode.NOT_FOUND)); - - // when - then - UserErrorException exception = assertThrows(UserErrorException.class, () -> userSyncMapper.readUserIfValid("pennyway", "password")); - System.out.println(exception.getExplainError()); - } - - @DisplayName("로그인 시, 비밀번호가 일치하지 않으면 UserErrorException을 발생시킨다.") - @Test - void readUserIfNotMatchedPassword() { - // given - User user = User.builder().username("pennyway").password("password").build(); - given(userService.readUserByUsername("pennyway")).willReturn(user); - given(bCryptPasswordEncoder.matches("password", user.getPassword())).willReturn(false); - - // when - then - UserErrorException exception = assertThrows(UserErrorException.class, () -> userSyncMapper.readUserIfValid("pennyway", "password")); - System.out.println(exception.getExplainError()); - } } From a483fa93282b524fea6010675ff4ff9f8d52ffeb Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:11:29 +0900 Subject: [PATCH 20/30] =?UTF-8?q?test:=20auth=20controller=20validation=20?= =?UTF-8?q?test=20=EB=B3=80=EA=B2=BD=20=EC=82=AC=ED=95=AD=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/apis/auth/controller/AuthControllerValidationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/controller/AuthControllerValidationTest.java b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/controller/AuthControllerValidationTest.java index 0447af6cb..e6f92458c 100644 --- a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/controller/AuthControllerValidationTest.java +++ b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/controller/AuthControllerValidationTest.java @@ -214,7 +214,7 @@ void signUp() throws Exception { ResponseCookie expectedCookie = ResponseCookie.from("refreshToken", "refreshToken") .maxAge(Duration.ofDays(7).toSeconds()).httpOnly(true).path("/").build(); - given(authUseCase.signUp(request)) + given(authUseCase.signUp(request.toInfo())) .willReturn(Pair.of(1L, Jwts.of("accessToken", "refreshToken"))); given(cookieUtil.createCookie("refreshToken", "refreshToken", Duration.ofDays(7).toSeconds())) .willReturn(expectedCookie); From ef3e5c10aed7aeac2873235ee9d7a6ca2051fdcc Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:11:54 +0900 Subject: [PATCH 21/30] =?UTF-8?q?test:=20user=20general=20sign=20mapper=20?= =?UTF-8?q?test=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/UserGeneralSignMapperTest.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapperTest.java diff --git a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapperTest.java b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapperTest.java new file mode 100644 index 000000000..9c5f29020 --- /dev/null +++ b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapperTest.java @@ -0,0 +1,71 @@ +package kr.co.pennyway.api.apis.auth.mapper; + +import kr.co.pennyway.domain.domains.user.domain.User; +import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; +import kr.co.pennyway.domain.domains.user.exception.UserErrorException; +import kr.co.pennyway.domain.domains.user.service.UserService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.security.crypto.password.PasswordEncoder; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.BDDMockito.given; + +@ExtendWith(MockitoExtension.class) +public class UserGeneralSignMapperTest { + private UserGeneralSignMapper userGeneralSignMapper; + @Mock + private UserService userService; + @Mock + private PasswordEncoder passwordEncoder; + + @BeforeEach + void setUp() { + userGeneralSignMapper = new UserGeneralSignMapper(userService, passwordEncoder); + } + + @DisplayName("로그인 시, 유저가 존재하고 비밀번호가 일치하면 User를 반환한다.") + @Test + void readUserIfValidReturnUser() { + // given + User user = User.builder().username("pennyway").password("password").build(); + given(userService.readUserByUsername("pennyway")).willReturn(user); + given(passwordEncoder.matches("password", user.getPassword())).willReturn(true); + + // when + User result = userGeneralSignMapper.readUserIfValid("pennyway", "password"); + + // then + assertEquals(result, user); + } + + @DisplayName("로그인 시, username에 해당하는 유저가 존재하지 않으면 UserErrorException을 발생시킨다.") + @Test + void readUserIfNotFound() { + // given + given(userService.readUserByUsername("pennyway")).willThrow( + new UserErrorException(UserErrorCode.NOT_FOUND)); + + // when - then + UserErrorException exception = assertThrows(UserErrorException.class, () -> userGeneralSignMapper.readUserIfValid("pennyway", "password")); + System.out.println(exception.getExplainError()); + } + + @DisplayName("로그인 시, 비밀번호가 일치하지 않으면 UserErrorException을 발생시킨다.") + @Test + void readUserIfNotMatchedPassword() { + // given + User user = User.builder().username("pennyway").password("password").build(); + given(userService.readUserByUsername("pennyway")).willReturn(user); + given(passwordEncoder.matches("password", user.getPassword())).willReturn(false); + + // when - then + UserErrorException exception = assertThrows(UserErrorException.class, () -> userGeneralSignMapper.readUserIfValid("pennyway", "password")); + System.out.println(exception.getExplainError()); + } +} From e4265510f03a65048ad73f3269258b3170b963e6 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:18:53 +0900 Subject: [PATCH 22/30] =?UTF-8?q?fix:=20domain=20service=20layer=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/domains/user/service/UserService.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pennyway-domain/src/main/java/kr/co/pennyway/domain/domains/user/service/UserService.java b/pennyway-domain/src/main/java/kr/co/pennyway/domain/domains/user/service/UserService.java index 91a991df2..27ee12580 100644 --- a/pennyway-domain/src/main/java/kr/co/pennyway/domain/domains/user/service/UserService.java +++ b/pennyway-domain/src/main/java/kr/co/pennyway/domain/domains/user/service/UserService.java @@ -2,12 +2,12 @@ import kr.co.pennyway.common.annotation.DomainService; import kr.co.pennyway.domain.domains.user.domain.User; -import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; -import kr.co.pennyway.domain.domains.user.exception.UserErrorException; import kr.co.pennyway.domain.domains.user.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + @DomainService @RequiredArgsConstructor public class UserService { @@ -19,18 +19,18 @@ public User createUser(User user) { } @Transactional(readOnly = true) - public User readUser(Long id) { - return userRepository.findById(id).orElseThrow(() -> new UserErrorException(UserErrorCode.NOT_FOUND)); + public Optional readUser(Long id) { + return userRepository.findById(id); } @Transactional(readOnly = true) - public User readUserByPhone(String phone) { - return userRepository.findByPhone(phone).orElseThrow(() -> new UserErrorException(UserErrorCode.NOT_FOUND)); + public Optional readUserByPhone(String phone) { + return userRepository.findByPhone(phone); } @Transactional(readOnly = true) - public User readUserByUsername(String username) { - return userRepository.findByUsername(username).orElseThrow(() -> new UserErrorException(UserErrorCode.NOT_FOUND)); + public Optional readUserByUsername(String username) { + return userRepository.findByUsername(username); } @Transactional(readOnly = true) From 431362f9a5bf83b3b6d3e7c57576807aacc17c31 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Thu, 28 Mar 2024 00:08:58 +0900 Subject: [PATCH 23/30] =?UTF-8?q?refactor:=20user=20sync=20mapper=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/apis/auth/mapper/UserSyncMapper.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java index b59aeb899..deba2f536 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java @@ -1,7 +1,6 @@ package kr.co.pennyway.api.apis.auth.mapper; import kr.co.pennyway.common.annotation.Mapper; -import kr.co.pennyway.common.exception.GlobalErrorException; import kr.co.pennyway.domain.domains.user.domain.User; import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; import kr.co.pennyway.domain.domains.user.exception.UserErrorException; @@ -10,6 +9,8 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; +import java.util.Optional; + /** * 일반 회원가입, Oauth 회원가입 시나리오를 제어하여 유저 정보를 동기화하는 Helper */ @@ -28,19 +29,18 @@ public class UserSyncMapper { * @throws UserErrorException : 이미 일반 회원가입을 한 유저인 경우 */ public Pair isGeneralSignUpAllowed(String phone) { - User user; - try { - user = userService.readUserByPhone(phone); - } catch (GlobalErrorException e) { - log.info("User not found. phone: {}", phone); + Optional user = userService.readUserByPhone(phone); + + if (user.isEmpty()) { + log.info("회원가입 이력이 없는 사용자입니다. phone: {}", phone); return Pair.of(Boolean.FALSE, null); } - if (user.getPassword() != null) { - log.warn("User already exists. phone: {}", phone); + if (user.get().getPassword() != null) { + log.warn("이미 회원가입된 사용자입니다. phone: {}", phone); throw new UserErrorException(UserErrorCode.ALREADY_SIGNUP); } - return Pair.of(Boolean.TRUE, user.getUsername()); + return Pair.of(Boolean.TRUE, user.get().getUsername()); } } From d2856fd97130986b8cdc88b1701a4ab786065984 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Thu, 28 Mar 2024 00:10:22 +0900 Subject: [PATCH 24/30] =?UTF-8?q?refactor:=20user=20details=20service=20im?= =?UTF-8?q?ple=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/authentication/UserDetailServiceImpl.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/common/security/authentication/UserDetailServiceImpl.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/common/security/authentication/UserDetailServiceImpl.java index 463fe4b8f..659145ebc 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/common/security/authentication/UserDetailServiceImpl.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/common/security/authentication/UserDetailServiceImpl.java @@ -16,10 +16,8 @@ public class UserDetailServiceImpl implements UserDetailsService { @Override @Cacheable(value = "securityUser", key = "#userId", unless = "#result == null", cacheManager = "securityUserCacheManager") public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { - try { - return SecurityUserDetails.from(userService.readUser(Long.parseLong(userId))); - } catch (Exception e) { - return null; - } + return userService.readUser(Long.parseLong(userId)) + .map(SecurityUserDetails::from) + .orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다.")); } } From 948eb58a2e1e988b925b06ca2617536ded1457d9 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Thu, 28 Mar 2024 00:21:04 +0900 Subject: [PATCH 25/30] =?UTF-8?q?refactor:=20user=20general=20sign=20mappe?= =?UTF-8?q?r=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/mapper/UserGeneralSignMapper.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java index e9e0eac83..0ac3ea083 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapper.java @@ -12,6 +12,8 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + /** * 일반 회원가입, 로그인 시나리오 도우미 클래스 * @@ -35,7 +37,8 @@ public User saveUserWithEncryptedPassword(SignUpReq.Info request, Pair new UserErrorException(UserErrorCode.NOT_FOUND)); user.updatePassword(request.password(bCryptPasswordEncoder)); } else { user = userService.createUser(request.toEntity(bCryptPasswordEncoder)); @@ -46,22 +49,23 @@ public User saveUserWithEncryptedPassword(SignUpReq.Info request, Pair user = userService.readUserByUsername(username); - try { - user = userService.readUserByUsername(username); + if (user.isEmpty()) { + log.warn("해당 유저가 존재하지 않습니다. username: {}", username); + throw new UserErrorException(UserErrorCode.INVALID_USERNAME_OR_PASSWORD); + } - if (!bCryptPasswordEncoder.matches(password, user.getPassword())) { - throw new UserErrorException(UserErrorCode.NOT_MATCHED_PASSWORD); - } - } catch (UserErrorException e) { - log.warn("request not valid : {} : {}", username, e.getExplainError()); + if (!bCryptPasswordEncoder.matches(password, user.get().getPassword())) { + log.warn("비밀번호가 일치하지 않습니다. username: {}", username); throw new UserErrorException(UserErrorCode.INVALID_USERNAME_OR_PASSWORD); } - return user; + return user.get(); } } From f8bcdc0b1d28b6fef9c0240ab3fd38db37f7e2af Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Thu, 28 Mar 2024 00:22:36 +0900 Subject: [PATCH 26/30] =?UTF-8?q?refactor:=20user=20sync=20mapper=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=B9=84=EA=B2=80=EC=82=AC=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java index deba2f536..692829281 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java @@ -2,7 +2,6 @@ import kr.co.pennyway.common.annotation.Mapper; import kr.co.pennyway.domain.domains.user.domain.User; -import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; import kr.co.pennyway.domain.domains.user.exception.UserErrorException; import kr.co.pennyway.domain.domains.user.service.UserService; import lombok.RequiredArgsConstructor; @@ -38,7 +37,7 @@ public Pair isGeneralSignUpAllowed(String phone) { if (user.get().getPassword() != null) { log.warn("이미 회원가입된 사용자입니다. phone: {}", phone); - throw new UserErrorException(UserErrorCode.ALREADY_SIGNUP); + return null; } return Pair.of(Boolean.TRUE, user.get().getUsername()); From ecc5706572c515e45dd91a3aff8d34e47b0ba1f5 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Thu, 28 Mar 2024 00:25:08 +0900 Subject: [PATCH 27/30] =?UTF-8?q?fix:=20user=20sync=20mapper=20=EC=84=A0?= =?UTF-8?q?=EC=96=B8=EC=A0=81=20transaction=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java index 692829281..5dc1f453c 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java @@ -2,11 +2,11 @@ import kr.co.pennyway.common.annotation.Mapper; import kr.co.pennyway.domain.domains.user.domain.User; -import kr.co.pennyway.domain.domains.user.exception.UserErrorException; import kr.co.pennyway.domain.domains.user.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; +import org.springframework.transaction.annotation.Transactional; import java.util.Optional; @@ -24,9 +24,9 @@ public class UserSyncMapper { * * @param phone String : 전화번호 * @return Pair : 이미 가입된 회원인지 여부 (TRUE: 가입되지 않은 회원, FALSE: 가입된 회원), 가입된 회원인 경우 회원 - * ID 반환 - * @throws UserErrorException : 이미 일반 회원가입을 한 유저인 경우 + * ID 반환. 단, 이미 일반 회원가입을 한 유저인 경우에는 null을 반환한다. */ + @Transactional(readOnly = true) public Pair isGeneralSignUpAllowed(String phone) { Optional user = userService.readUserByPhone(phone); From 43ebba0e6f8a06b2490063e072ef9deedd20ee69 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Thu, 28 Mar 2024 00:25:36 +0900 Subject: [PATCH 28/30] =?UTF-8?q?refactor:=20auth=20use=20case=20=EB=B9=84?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EC=98=88=EC=99=B8=20=ED=95=B8=EB=93=A4?= =?UTF-8?q?=EB=A7=81=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pennyway/api/apis/auth/usecase/AuthUseCase.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/usecase/AuthUseCase.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/usecase/AuthUseCase.java index 4a0e0efaf..2086c3bed 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/usecase/AuthUseCase.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/usecase/AuthUseCase.java @@ -12,6 +12,7 @@ import kr.co.pennyway.domain.common.redis.phone.PhoneVerificationService; import kr.co.pennyway.domain.common.redis.phone.PhoneVerificationType; import kr.co.pennyway.domain.domains.user.domain.User; +import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; import kr.co.pennyway.domain.domains.user.exception.UserErrorException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -61,11 +62,13 @@ public Pair signIn(SignInReq.General request) { } private Pair checkOauthUserNotGeneralSignUp(String phone) { - try { - return userSyncMapper.isGeneralSignUpAllowed(phone); - } catch (UserErrorException e) { + Pair isGeneralSignUpAllowed = userSyncMapper.isGeneralSignUpAllowed(phone); + + if (isGeneralSignUpAllowed == null) { phoneVerificationService.delete(phone, PhoneVerificationType.SIGN_UP); - throw e; + throw new UserErrorException(UserErrorCode.ALREADY_SIGNUP); } + + return isGeneralSignUpAllowed; } } From c3dc075b0cde4e34e77b38546b9c9baa78275133 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Thu, 28 Mar 2024 00:38:29 +0900 Subject: [PATCH 29/30] =?UTF-8?q?test:=20test=20optional=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/UserGeneralSignMapperTest.java | 6 +++-- .../apis/auth/mapper/UserSyncMapperTest.java | 24 +++++++++---------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapperTest.java b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapperTest.java index 9c5f29020..f59202b2a 100644 --- a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapperTest.java +++ b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserGeneralSignMapperTest.java @@ -12,6 +12,8 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.security.crypto.password.PasswordEncoder; +import java.util.Optional; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.BDDMockito.given; @@ -34,7 +36,7 @@ void setUp() { void readUserIfValidReturnUser() { // given User user = User.builder().username("pennyway").password("password").build(); - given(userService.readUserByUsername("pennyway")).willReturn(user); + given(userService.readUserByUsername("pennyway")).willReturn(Optional.of(user)); given(passwordEncoder.matches("password", user.getPassword())).willReturn(true); // when @@ -61,7 +63,7 @@ void readUserIfNotFound() { void readUserIfNotMatchedPassword() { // given User user = User.builder().username("pennyway").password("password").build(); - given(userService.readUserByUsername("pennyway")).willReturn(user); + given(userService.readUserByUsername("pennyway")).willReturn(Optional.of(user)); given(passwordEncoder.matches("password", user.getPassword())).willReturn(false); // when - then diff --git a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapperTest.java b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapperTest.java index b7cf2641a..c67630530 100644 --- a/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapperTest.java +++ b/pennyway-app-external-api/src/test/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapperTest.java @@ -1,9 +1,8 @@ package kr.co.pennyway.api.apis.auth.mapper; import kr.co.pennyway.domain.domains.user.domain.User; -import kr.co.pennyway.domain.domains.user.exception.UserErrorCode; -import kr.co.pennyway.domain.domains.user.exception.UserErrorException; import kr.co.pennyway.domain.domains.user.service.UserService; +import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -11,7 +10,10 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.Optional; + import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.BDDMockito.given; @ExtendWith(MockitoExtension.class) @@ -30,8 +32,7 @@ void setUp() { @Test void isSignedUserWhenGeneralReturnFalse() { // given - given(userService.readUserByPhone(phone)).willThrow( - new UserErrorException(UserErrorCode.NOT_FOUND)); + given(userService.readUserByPhone(phone)).willReturn(Optional.empty()); // when Boolean result = userSyncMapper.isGeneralSignUpAllowed(phone).getKey(); @@ -44,25 +45,24 @@ void isSignedUserWhenGeneralReturnFalse() { @Test void isSignedUserWhenGeneralReturnTrue() { // given - given(userService.readUserByPhone(phone)).willReturn(User.builder().password(null).build()); + given(userService.readUserByPhone(phone)).willReturn(Optional.of(User.builder().username("pennyway").password(null).build())); // when - Boolean result = userSyncMapper.isGeneralSignUpAllowed(phone).getKey(); + Pair result = userSyncMapper.isGeneralSignUpAllowed(phone); // then - assertEquals(result, Boolean.TRUE); + assertEquals(result.getLeft(), Boolean.TRUE); + assertEquals(result.getRight(), "pennyway"); } - @DisplayName("일반 회원가입 시, 이미 일반회원 가입된 회원인 경우 UserErrorException을 발생시킨다.") + @DisplayName("일반 회원가입 시, 이미 일반회원 가입된 회원인 경우 null을 반환한다.") @Test void isSignedUserWhenGeneralThrowUserErrorException() { // given given(userService.readUserByPhone(phone)).willReturn( - User.builder().password("password").build()); + Optional.of(User.builder().password("password").build())); // when - then - UserErrorException exception = org.junit.jupiter.api.Assertions.assertThrows( - UserErrorException.class, () -> userSyncMapper.isGeneralSignUpAllowed(phone)); - System.out.println(exception.getExplainError()); + assertNull(userSyncMapper.isGeneralSignUpAllowed(phone)); } } From 09990910a07a238716889592c3b8ccbca3177e30 Mon Sep 17 00:00:00 2001 From: JaeSeo Yang <96044622+psychology50@users.noreply.github.com> Date: Thu, 28 Mar 2024 01:11:37 +0900 Subject: [PATCH 30/30] =?UTF-8?q?rename:=20user=20sync=20mapper=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java index 5dc1f453c..e04b9a551 100644 --- a/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java +++ b/pennyway-app-external-api/src/main/java/kr/co/pennyway/api/apis/auth/mapper/UserSyncMapper.java @@ -11,7 +11,9 @@ import java.util.Optional; /** - * 일반 회원가입, Oauth 회원가입 시나리오를 제어하여 유저 정보를 동기화하는 Helper + * 일반 회원가입, Oauth 회원가입 시나리오를 제어하여 유저 정보를 동기화하는 클래스 + * + * @author YANG JAESEO */ @Slf4j @Mapper