From 443a56f58fc783e4dc558ed45708c3658fd5db9b Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:16:46 +0900 Subject: [PATCH 01/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EC=A0=80=EC=9E=A5=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20Admin=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/atwoz/admin/domain/admin/Admin.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/domain/admin/Admin.java diff --git a/src/main/java/com/atwoz/admin/domain/admin/Admin.java b/src/main/java/com/atwoz/admin/domain/admin/Admin.java new file mode 100644 index 00000000..8be1adac --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/Admin.java @@ -0,0 +1,87 @@ +package com.atwoz.admin.domain.admin; + +import com.atwoz.admin.domain.admin.vo.AdminStatus; +import com.atwoz.admin.domain.admin.vo.Authority; +import com.atwoz.admin.domain.admin.vo.Department; +import com.atwoz.admin.exception.exceptions.InvalidPasswordException; +import com.atwoz.admin.exception.exceptions.PasswordMismatchException; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@EqualsAndHashCode(of = "id", callSuper = false) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class Admin { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(unique = true, nullable = false) + private String email; + + @Column(nullable = false) + private String password; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String phoneNumber; + + @Enumerated(value = EnumType.STRING) + @Column(nullable = false) + private Authority authority; + + @Enumerated(value = EnumType.STRING) + @Column(nullable = false) + private Department department; + + @Enumerated(value = EnumType.STRING) + @Column(nullable = false) + private AdminStatus adminStatus; + + public static Admin createWith(final String email, + final String password, + final String confirmPassword, + final String name, + final String phoneNumber) { + validatePasswordsMatch(password, confirmPassword); + return Admin.builder() + .email(email) + .password(password) + .name(name) + .phoneNumber(phoneNumber) + .authority(Authority.ADMIN) + .department(Department.OPERATION) + .adminStatus(AdminStatus.PENDING) + .build(); + } + + private static void validatePasswordsMatch(final String password, + final String confirmPassword) { + if (!password.equals(confirmPassword)) { + throw new PasswordMismatchException(); + } + } + + public void validatePassword(final String password) { + if (!password.equals(this.password)) { + throw new InvalidPasswordException(); + } + } +} From e554ca13293cd6d49fd6628c6a48e6101f69f8e2 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:18:49 +0900 Subject: [PATCH 02/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=EC=9D=91=EB=8B=B5=20dto=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 - AdminAccessTokenResponse - AdminTokenResponse --- .../application/auth/dto/AdminAccessTokenResponse.java | 6 ++++++ .../admin/application/auth/dto/AdminTokenResponse.java | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminAccessTokenResponse.java create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminTokenResponse.java diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminAccessTokenResponse.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminAccessTokenResponse.java new file mode 100644 index 00000000..c0c7bbea --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminAccessTokenResponse.java @@ -0,0 +1,6 @@ +package com.atwoz.admin.application.auth.dto; + +public record AdminAccessTokenResponse( + String accessToken +) { +} diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminTokenResponse.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminTokenResponse.java new file mode 100644 index 00000000..0b2a69cb --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminTokenResponse.java @@ -0,0 +1,7 @@ +package com.atwoz.admin.application.auth.dto; + +public record AdminTokenResponse( + String accessToken, + String refreshToken +) { +} From 0a3a8131cc5265823e812fafdfd8c0342a6b185a Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:23:43 +0900 Subject: [PATCH 03/66] =?UTF-8?q?feat:=20=ED=8A=B9=EC=A0=95=20uri=EB=A5=BC?= =?UTF-8?q?=20=EA=B4=80=EB=A6=AC=EC=9E=90=EC=97=90=EA=B2=8C=EB=A7=8C=20?= =?UTF-8?q?=ED=97=88=EC=9A=A9=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminAuthArgumentResolver - AdminAuthConfig - AdminAuthenticationContext - AdminAuthenticationContext - AdminLoginValidCheckerInterceptor - AdminRefreshTokenExtractionArgumentResolver --- .../atwoz/admin/config/AdminAuthConfig.java | 40 ++++++++++++ .../AdminLoginValidCheckerInterceptor.java | 42 +++++++++++++ .../support/AdminAuthenticationContext.java | 25 ++++++++ .../support/AdminAuthenticationExtractor.java | 36 +++++++++++ .../resolver/AdminAuthArgumentResolver.java | 32 ++++++++++ ...efreshTokenExtractionArgumentResolver.java | 61 +++++++++++++++++++ 6 files changed, 236 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/config/AdminAuthConfig.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptor.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContext.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractor.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminAuthArgumentResolver.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminRefreshTokenExtractionArgumentResolver.java diff --git a/src/main/java/com/atwoz/admin/config/AdminAuthConfig.java b/src/main/java/com/atwoz/admin/config/AdminAuthConfig.java new file mode 100644 index 00000000..97388421 --- /dev/null +++ b/src/main/java/com/atwoz/admin/config/AdminAuthConfig.java @@ -0,0 +1,40 @@ +package com.atwoz.admin.config; + +import com.atwoz.admin.ui.auth.interceptor.AdminLoginValidCheckerInterceptor; +import com.atwoz.admin.ui.auth.support.resolver.AdminAuthArgumentResolver; +import com.atwoz.admin.ui.auth.support.resolver.AdminRefreshTokenExtractionArgumentResolver; +import com.atwoz.global.config.interceptor.PathMatcherInterceptor; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import static com.atwoz.global.config.interceptor.support.HttpMethod.OPTIONS; + +@RequiredArgsConstructor +@Configuration +public class AdminAuthConfig implements WebMvcConfigurer { + + private final AdminAuthArgumentResolver adminAuthArgumentResolver; + private final AdminRefreshTokenExtractionArgumentResolver adminRefreshTokenExtractionArgumentResolver; + private final AdminLoginValidCheckerInterceptor adminLoginValidCheckerInterceptor; + + @Override + public void addInterceptors(final InterceptorRegistry registry) { + registry.addInterceptor(adminLoginValidCheckerInterceptor()); + } + + private HandlerInterceptor adminLoginValidCheckerInterceptor() { + return new PathMatcherInterceptor(adminLoginValidCheckerInterceptor) + .excludePathPattern("/**", OPTIONS); + } + + @Override + public void addArgumentResolvers(final List resolvers) { + resolvers.add(adminAuthArgumentResolver); + resolvers.add(adminRefreshTokenExtractionArgumentResolver); + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptor.java b/src/main/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptor.java new file mode 100644 index 00000000..d8785050 --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptor.java @@ -0,0 +1,42 @@ +package com.atwoz.admin.ui.auth.interceptor; + +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import com.atwoz.admin.exception.exceptions.UnauthorizedAccessToAdminException; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationContext; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationExtractor; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +@RequiredArgsConstructor +@Component +public class AdminLoginValidCheckerInterceptor implements HandlerInterceptor { + + private static final String ADMIN_ID = "id"; + private static final String ROLE = "role"; + private static final String ADMIN = "admin"; + + private final AdminAuthenticationContext adminAuthenticationContext; + private final AdminAuthenticationExtractor adminAuthenticationExtractor; + private final AdminTokenProvider adminTokenProvider; + + @Override + public boolean preHandle(final HttpServletRequest request, + final HttpServletResponse response, + final Object handler) throws Exception { + String token = adminAuthenticationExtractor.extractFromRequest(request) + .orElseThrow(AdminLoginInvalidException::new); + String extractedRole = adminTokenProvider.extract(token, ROLE, String.class); + if (!extractedRole.equals(ADMIN)) { + throw new UnauthorizedAccessToAdminException(); + } + + Long extractedId = adminTokenProvider.extract(token, ADMIN_ID, Long.class); + adminAuthenticationContext.setAuthentication(extractedId); + + return true; + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContext.java b/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContext.java new file mode 100644 index 00000000..efd4f4b5 --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContext.java @@ -0,0 +1,25 @@ +package com.atwoz.admin.ui.auth.support; + +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import java.util.Objects; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +@RequestScope +@Component +public class AdminAuthenticationContext { + + private Long memberId; + + public void setAuthentication(final Long memberId) { + this.memberId = memberId; + } + + public Long getPrincipal() { + if (Objects.isNull(this.memberId)) { + throw new AdminLoginInvalidException(); + } + + return memberId; + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractor.java b/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractor.java new file mode 100644 index 00000000..3a7d77ac --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractor.java @@ -0,0 +1,36 @@ +package com.atwoz.admin.ui.auth.support; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Optional; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +@Component +public class AdminAuthenticationExtractor { + + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String BEARER = "Bearer"; + private static final String HEADER_SPLIT_DELIMITER = " "; + private static final int TOKEN_TYPE_INDEX = 0; + private static final int TOKEN_VALUE_INDEX = 1; + private static final int VALID_HEADER_SPLIT_LENGTH = 2; + + public Optional extractFromRequest(final HttpServletRequest request) { + String header = request.getHeader(AUTHORIZATION_HEADER); + + if (!StringUtils.hasText(header)) { + return Optional.empty(); + } + + return extractFromHeader(header.split(HEADER_SPLIT_DELIMITER)); + } + + private Optional extractFromHeader(final String[] headerParts) { + if (headerParts.length == VALID_HEADER_SPLIT_LENGTH && + headerParts[TOKEN_TYPE_INDEX].equals(BEARER)) { + return Optional.ofNullable(headerParts[TOKEN_VALUE_INDEX]); + } + + return Optional.empty(); + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminAuthArgumentResolver.java b/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminAuthArgumentResolver.java new file mode 100644 index 00000000..4d2a53bc --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminAuthArgumentResolver.java @@ -0,0 +1,32 @@ +package com.atwoz.admin.ui.auth.support.resolver; + +import com.atwoz.admin.ui.auth.support.AdminAuthenticationContext; +import com.atwoz.admin.ui.auth.support.AuthAdmin; +import lombok.RequiredArgsConstructor; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@RequiredArgsConstructor +@Component +public class AdminAuthArgumentResolver implements HandlerMethodArgumentResolver { + + private final AdminAuthenticationContext adminAuthenticationContext; + + @Override + public boolean supportsParameter(final MethodParameter parameter) { + return parameter.hasParameterAnnotation(AuthAdmin.class) && + parameter.getParameterType().equals(Long.class); + } + + @Override + public Object resolveArgument(final MethodParameter parameter, + final ModelAndViewContainer mavContainer, + final NativeWebRequest webRequest, + final WebDataBinderFactory binderFactory) throws Exception { + return adminAuthenticationContext.getPrincipal(); + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminRefreshTokenExtractionArgumentResolver.java b/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminRefreshTokenExtractionArgumentResolver.java new file mode 100644 index 00000000..e137c71e --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminRefreshTokenExtractionArgumentResolver.java @@ -0,0 +1,61 @@ +package com.atwoz.admin.ui.auth.support.resolver; + +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import com.atwoz.admin.exception.exceptions.UnauthorizedAccessToAdminException; +import com.atwoz.admin.ui.auth.support.AdminRefreshToken; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@RequiredArgsConstructor +@Component +public class AdminRefreshTokenExtractionArgumentResolver implements HandlerMethodArgumentResolver { + + private static final String REFRESH_TOKEN = "refreshToken"; + private static final String ROLE = "role"; + private static final String ADMIN = "admin"; + + private final AdminTokenProvider adminTokenProvider; + + @Override + public boolean supportsParameter(final MethodParameter parameter) { + return parameter.hasParameterAnnotation(AdminRefreshToken.class) && + parameter.getParameterType().equals(String.class); + } + + @Override + public Object resolveArgument(final MethodParameter parameter, + final ModelAndViewContainer mavContainer, + final NativeWebRequest webRequest, + final WebDataBinderFactory binderFactory) throws Exception { + HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); + if (request == null) { + throw new AdminLoginInvalidException(); + } + + String refreshToken = findRefreshToken(request.getCookies()); + String role = adminTokenProvider.extract(refreshToken, ROLE, String.class); + if (!Objects.equals(role, ADMIN)) { + throw new UnauthorizedAccessToAdminException(); + } + + return refreshToken; + } + + private String findRefreshToken(final Cookie[] cookies) { + return Arrays.stream(cookies) + .filter(cookie -> REFRESH_TOKEN.equals(cookie.getName())) + .findAny() + .orElseThrow(AdminLoginInvalidException::new) + .getValue(); + } +} From ab4b26f97d72a5cb1ce59964d6e6766832270302 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:26:14 +0900 Subject: [PATCH 04/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=EC=8B=9C=20=EB=B0=9C=EC=83=9D=ED=95=A0=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8A=94=20=EC=98=88=EC=99=B8=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminExceptionHandler - AdminLoginInvalidException - AdminNotFoundException - InvalidPasswordException - PasswordMismatchException - UnauthorizedAccessToAdminException --- .../exception/AdminExceptionHandler.java | 61 +++++++++++++++++++ .../AdminLoginInvalidException.java | 8 +++ .../exceptions/AdminNotFoundException.java | 8 +++ .../exceptions/InvalidPasswordException.java | 8 +++ .../exceptions/PasswordMismatchException.java | 8 +++ .../UnauthorizedAccessToAdminException.java | 8 +++ 6 files changed, 101 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/exception/AdminExceptionHandler.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/AdminLoginInvalidException.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/AdminNotFoundException.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/InvalidPasswordException.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/PasswordMismatchException.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/UnauthorizedAccessToAdminException.java diff --git a/src/main/java/com/atwoz/admin/exception/AdminExceptionHandler.java b/src/main/java/com/atwoz/admin/exception/AdminExceptionHandler.java new file mode 100644 index 00000000..29f8bd93 --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/AdminExceptionHandler.java @@ -0,0 +1,61 @@ +package com.atwoz.admin.exception; + +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import com.atwoz.admin.exception.exceptions.AdminNotFoundException; +import com.atwoz.admin.exception.exceptions.InvalidPasswordException; +import com.atwoz.admin.exception.exceptions.PasswordMismatchException; +import com.atwoz.admin.exception.exceptions.UnauthorizedAccessToAdminException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class AdminExceptionHandler { + + @ExceptionHandler(PasswordMismatchException.class) + public ResponseEntity handlePasswordMismatchException(final PasswordMismatchException e) { + return getBadRequest(e); + } + + @ExceptionHandler(AdminNotFoundException.class) + public ResponseEntity handleAdminNotFoundException(final AdminNotFoundException e) { + return getNotFoundResponse(e); + } + + @ExceptionHandler(InvalidPasswordException.class) + public ResponseEntity handlePasswordInvalidException(final InvalidPasswordException e) { + return getBadRequest(e); + } + + @ExceptionHandler(UnauthorizedAccessToAdminException.class) + public ResponseEntity handleUnauthorizedAccessToAdminException(final UnauthorizedAccessToAdminException e) { + return getUnauthorized(e); + } + + @ExceptionHandler(AdminLoginInvalidException.class) + public ResponseEntity handleAdminLoginInvalidException(final AdminLoginInvalidException e) { + return getUnauthorized(e); + } + + private ResponseEntity getNotFoundResponse(final Exception e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(e.getMessage()); + } + + private ResponseEntity getUnauthorized(final Exception e) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(e.getMessage()); + } + + private ResponseEntity getConflicted(final Exception e) { + return ResponseEntity.status(HttpStatus.CONFLICT) + .body(e.getMessage()); + } + + private ResponseEntity getBadRequest(final Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(e.getMessage()); + } +} + diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/AdminLoginInvalidException.java b/src/main/java/com/atwoz/admin/exception/exceptions/AdminLoginInvalidException.java new file mode 100644 index 00000000..031ab33f --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/AdminLoginInvalidException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class AdminLoginInvalidException extends RuntimeException { + + public AdminLoginInvalidException() { + super("관리자 로그인이 유효하지 않습니다"); + } +} diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/AdminNotFoundException.java b/src/main/java/com/atwoz/admin/exception/exceptions/AdminNotFoundException.java new file mode 100644 index 00000000..c0a27b90 --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/AdminNotFoundException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class AdminNotFoundException extends RuntimeException { + + public AdminNotFoundException() { + super("관리자를 찾을 수 없습니다."); + } +} diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/InvalidPasswordException.java b/src/main/java/com/atwoz/admin/exception/exceptions/InvalidPasswordException.java new file mode 100644 index 00000000..c9549806 --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/InvalidPasswordException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class InvalidPasswordException extends RuntimeException { + + public InvalidPasswordException() { + super("잘못된 이메일/비밀번호 입력입니다. 다시 입력해주세요"); + } +} diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/PasswordMismatchException.java b/src/main/java/com/atwoz/admin/exception/exceptions/PasswordMismatchException.java new file mode 100644 index 00000000..fa51bc6f --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/PasswordMismatchException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class PasswordMismatchException extends RuntimeException { + + public PasswordMismatchException() { + super("비밀번호가 일치하지 않습니다."); + } +} diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/UnauthorizedAccessToAdminException.java b/src/main/java/com/atwoz/admin/exception/exceptions/UnauthorizedAccessToAdminException.java new file mode 100644 index 00000000..fe196384 --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/UnauthorizedAccessToAdminException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class UnauthorizedAccessToAdminException extends RuntimeException { + + public UnauthorizedAccessToAdminException() { + super("권한이 없습니다."); + } +} From 6d66b4aff18df89bf046af2e98f4cf3eb082a8fe Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:27:56 +0900 Subject: [PATCH 05/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20rep?= =?UTF-8?q?ository=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminRepository - AdminJpaRepository - AdminRepositoryImpl --- .../admin/domain/admin/AdminRepository.java | 12 ++++++++ .../admin/AdminJpaRepository.java | 10 +++++++ .../admin/AdminRepositoryImpl.java | 29 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/domain/admin/AdminRepository.java create mode 100644 src/main/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepository.java create mode 100644 src/main/java/com/atwoz/admin/infrastructure/admin/AdminRepositoryImpl.java diff --git a/src/main/java/com/atwoz/admin/domain/admin/AdminRepository.java b/src/main/java/com/atwoz/admin/domain/admin/AdminRepository.java new file mode 100644 index 00000000..8cc4830d --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/AdminRepository.java @@ -0,0 +1,12 @@ +package com.atwoz.admin.domain.admin; + +import java.util.Optional; + +public interface AdminRepository { + + Admin save(Admin admin); + + Optional findAdminById(Long id); + + Optional findAdminByEmail(String email); +} diff --git a/src/main/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepository.java b/src/main/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepository.java new file mode 100644 index 00000000..d305fcac --- /dev/null +++ b/src/main/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepository.java @@ -0,0 +1,10 @@ +package com.atwoz.admin.infrastructure.admin; + +import com.atwoz.admin.domain.admin.Admin; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AdminJpaRepository extends JpaRepository { + + Optional findAdminByEmail(String email); +} diff --git a/src/main/java/com/atwoz/admin/infrastructure/admin/AdminRepositoryImpl.java b/src/main/java/com/atwoz/admin/infrastructure/admin/AdminRepositoryImpl.java new file mode 100644 index 00000000..62b717b1 --- /dev/null +++ b/src/main/java/com/atwoz/admin/infrastructure/admin/AdminRepositoryImpl.java @@ -0,0 +1,29 @@ +package com.atwoz.admin.infrastructure.admin; + +import com.atwoz.admin.domain.admin.Admin; +import com.atwoz.admin.domain.admin.AdminRepository; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@RequiredArgsConstructor +@Repository +public class AdminRepositoryImpl implements AdminRepository { + + private final AdminJpaRepository adminJpaRepository; + + @Override + public Admin save(final Admin admin) { + return adminJpaRepository.save(admin); + } + + @Override + public Optional findAdminById(final Long id) { + return adminJpaRepository.findById(id); + } + + @Override + public Optional findAdminByEmail(final String email) { + return adminJpaRepository.findAdminByEmail(email); + } +} From 2c9eef7fbc1db16f9449ea03c7f48011c84508ee Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:30:30 +0900 Subject: [PATCH 06/66] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=EC=9D=84=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=ED=95=98=EA=B3=A0=20=ED=86=A0=ED=81=B0?= =?UTF-8?q?=EC=9D=98=20claim=EC=9D=84=20=EC=B0=BE=EC=95=84=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminTokenProvider - AdminJwtTokenProvider --- .../domain/admin/AdminTokenProvider.java | 10 ++ .../auth/AdminJwtTokenProvider.java | 117 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/domain/admin/AdminTokenProvider.java create mode 100644 src/main/java/com/atwoz/admin/infrastructure/auth/AdminJwtTokenProvider.java diff --git a/src/main/java/com/atwoz/admin/domain/admin/AdminTokenProvider.java b/src/main/java/com/atwoz/admin/domain/admin/AdminTokenProvider.java new file mode 100644 index 00000000..427d63b5 --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/AdminTokenProvider.java @@ -0,0 +1,10 @@ +package com.atwoz.admin.domain.admin; + +public interface AdminTokenProvider { + + String createAccessToken(Long id); + + String createRefreshToken(Long id); + + T extract(String token, String claimName, Class classType); +} diff --git a/src/main/java/com/atwoz/admin/infrastructure/auth/AdminJwtTokenProvider.java b/src/main/java/com/atwoz/admin/infrastructure/auth/AdminJwtTokenProvider.java new file mode 100644 index 00000000..0ee81c0c --- /dev/null +++ b/src/main/java/com/atwoz/admin/infrastructure/auth/AdminJwtTokenProvider.java @@ -0,0 +1,117 @@ +package com.atwoz.admin.infrastructure.auth; + +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.member.exception.exceptions.auth.ExpiredTokenException; +import com.atwoz.member.exception.exceptions.auth.SignatureInvalidException; +import com.atwoz.member.exception.exceptions.auth.TokenFormInvalidException; +import com.atwoz.member.exception.exceptions.auth.TokenInvalidException; +import com.atwoz.member.exception.exceptions.auth.UnsupportedTokenException; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.UnsupportedJwtException; +import io.jsonwebtoken.security.Keys; +import jakarta.annotation.PostConstruct; +import java.security.Key; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import lombok.NoArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@NoArgsConstructor +@Component +public class AdminJwtTokenProvider implements AdminTokenProvider { + + private static final String ID = "id"; + private static final String TOKEN_TYPE = "token type"; + private static final String REFRESH_TOKEN = "refresh token"; + private static final String ACCESS_TOKEN = "access token"; + private static final String ROLE = "role"; + private static final String ADMIN = "admin"; + + @Value("${jwt.secret}") + private String secret; + + @Value("${jwt.access-token-expiration-period}") + private int accessTokenExpirationPeriod; + + @Value("${jwt.refresh-token-expiration-period}") + private int refreshTokenExpirationPeriod; + + private Key key; + + @PostConstruct + private void init() { + key = Keys.hmacShaKeyFor(secret.getBytes()); + } + + @Override + public String createAccessToken(final Long id) { + Claims claims = Jwts.claims(); + claims.put(ID, id); + claims.put(TOKEN_TYPE, ACCESS_TOKEN); + claims.put(ROLE, ADMIN); + + return createToken(claims, accessTokenExpirationPeriod); + } + + @Override + public String createRefreshToken(final Long id) { + Claims claims = Jwts.claims(); + claims.put(ID, id); + claims.put(TOKEN_TYPE, REFRESH_TOKEN); + claims.put(ROLE, ADMIN); + + return createToken(claims, refreshTokenExpirationPeriod); + } + + private String createToken(final Claims claims, final int expirationPeriod) { + return Jwts.builder() + .setClaims(claims) + .setIssuedAt(issuedAt()) + .setExpiration(expiredAt(expirationPeriod)) + .signWith(key, SignatureAlgorithm.HS256) + .compact(); + } + + private Date issuedAt() { + LocalDateTime now = LocalDateTime.now(); + + return Date.from(now.atZone(ZoneId.systemDefault()) + .toInstant()); + } + + private Date expiredAt(final int expirationPeriod) { + LocalDateTime now = LocalDateTime.now(); + + return Date.from(now.plusDays(expirationPeriod) + .atZone(ZoneId.systemDefault()) + .toInstant()); + } + + @Override + public T extract(final String token, final String claimName, final Class classType) { + try { + return Jwts.parserBuilder() + .setSigningKey(secret.getBytes()) + .build() + .parseClaimsJws(token) + .getBody() + .get(claimName, classType); + } catch (SecurityException e) { + throw new SignatureInvalidException(); + } catch (MalformedJwtException e) { + throw new TokenFormInvalidException(); + } catch (ExpiredJwtException e) { + throw new ExpiredTokenException(); + } catch (UnsupportedJwtException e) { + throw new UnsupportedTokenException(); + } catch (IllegalArgumentException e) { + throw new TokenInvalidException(); + } + } +} From b0ca1fca99af7b8e6750b676d046ea18fc8f0c2e Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:31:07 +0900 Subject: [PATCH 07/66] =?UTF-8?q?feat:=20Admin=20Auth=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminAuthService --- .../application/auth/AdminAuthService.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/application/auth/AdminAuthService.java diff --git a/src/main/java/com/atwoz/admin/application/auth/AdminAuthService.java b/src/main/java/com/atwoz/admin/application/auth/AdminAuthService.java new file mode 100644 index 00000000..cc9ba182 --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/AdminAuthService.java @@ -0,0 +1,69 @@ +package com.atwoz.admin.application.auth; + +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminProfileSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; +import com.atwoz.admin.domain.admin.Admin; +import com.atwoz.admin.domain.admin.AdminRepository; +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +@Transactional +public class AdminAuthService { + + private static final String ID = "id"; + + private final AdminRepository adminRepository; + private final AdminTokenProvider adminTokenProvider; + + public AdminTokenResponse signUp(final AdminSignUpRequest adminSignUpRequest) { + AdminProfileSignUpRequest adminProfileSignUpRequest = adminSignUpRequest.adminProfileSignUpRequest(); + Admin admin = Admin.createWith( + adminSignUpRequest.email(), + adminSignUpRequest.password(), + adminSignUpRequest.confirmPassword(), + adminProfileSignUpRequest.name(), + adminProfileSignUpRequest.phoneNumber() + ); + Admin savedAdmin = adminRepository.save(admin); + + return createAdminTokenResponse(savedAdmin.getId()); + } + + private AdminTokenResponse createAdminTokenResponse(final Long id) { + return new AdminTokenResponse( + adminTokenProvider.createAccessToken(id), + adminTokenProvider.createRefreshToken(id) + ); + } + + public AdminTokenResponse login(final AdminLoginRequest adminLoginRequest) { + Admin foundAdmin = findAdminByEmail(adminLoginRequest.email()); + foundAdmin.validatePassword(adminLoginRequest.password()); + + return createAdminTokenResponse(foundAdmin.getId()); + } + + public AdminAccessTokenResponse reGenerateAccessToken(final String refreshToken) { + Admin foundAdmin = findAdminById(adminTokenProvider.extract(refreshToken, ID, Long.class)); + + return new AdminAccessTokenResponse(adminTokenProvider.createAccessToken(foundAdmin.getId())); + } + + private Admin findAdminByEmail(final String email) { + return adminRepository.findAdminByEmail(email) + .orElseThrow(AdminNotFoundException::new); + } + + private Admin findAdminById(final Long id) { + return adminRepository.findAdminById(id) + .orElseThrow(AdminNotFoundException::new); + } +} From 93e4724f73ae964718b0991ddd51ab249d6b5fe7 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:31:35 +0900 Subject: [PATCH 08/66] =?UTF-8?q?feat:=20Admin=20Auth=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminAuthController --- .../admin/ui/auth/AdminAuthController.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java diff --git a/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java b/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java new file mode 100644 index 00000000..034763e5 --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java @@ -0,0 +1,73 @@ +package com.atwoz.admin.ui.auth; + +import com.atwoz.admin.application.auth.AdminAuthService; +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; +import com.atwoz.admin.ui.auth.support.AdminRefreshToken; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseCookie; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/api/admins/auth") +public class AdminAuthController { + + private static final String COOKIE_NAME = "refreshToken"; + private static final String ANY_WAY = "/"; + + @Value("${cookie.max-age}") + private int maxAge; + + private final AdminAuthService adminAuthService; + + @PostMapping("/sign-up") + public ResponseEntity singUp( + @RequestBody @Valid final AdminSignUpRequest adminSignUpRequest) { + AdminTokenResponse adminTokenResponse = adminAuthService.signUp(adminSignUpRequest); + + return ResponseEntity.ok() + .headers(createCookieHeaders(adminTokenResponse.refreshToken())) + .body(new AdminAccessTokenResponse(adminTokenResponse.accessToken())); + } + + @PostMapping("/login") + public ResponseEntity login( + @RequestBody @Valid final AdminLoginRequest adminLoginRequest) { + AdminTokenResponse adminTokenResponse = adminAuthService.login(adminLoginRequest); + + return ResponseEntity.ok() + .headers(createCookieHeaders(adminTokenResponse.refreshToken())) + .body(new AdminAccessTokenResponse(adminTokenResponse.accessToken())); + } + + @PostMapping("/access-token-regeneration") + public ResponseEntity reGenerateAccessToken( + @AdminRefreshToken final String refreshToken) { + System.out.println("hihi : " + refreshToken); + return ResponseEntity.ok(adminAuthService.reGenerateAccessToken(refreshToken)); + } + + + private HttpHeaders createCookieHeaders(final String refreshToken) { + ResponseCookie cookie = ResponseCookie.from(COOKIE_NAME, refreshToken) + .httpOnly(true) + .secure(true) + .path(ANY_WAY) + .maxAge(maxAge) + .build(); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add(HttpHeaders.COOKIE, cookie.toString()); + + return httpHeaders; + } +} From 7ead96531369283553337e9f8b7d33702f05b04f Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:32:48 +0900 Subject: [PATCH 09/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=EC=9A=94=EC=B2=AD=20dto=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 - AdminSignUpRequest - AdminProfileSignUpRequest - AdminLoginRequest --- .../auth/dto/AdminLoginRequest.java | 12 +++++++++++ .../auth/dto/AdminProfileSignUpRequest.java | 7 +++++++ .../auth/dto/AdminSignUpRequest.java | 21 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminLoginRequest.java create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminSignUpRequest.java diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminLoginRequest.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminLoginRequest.java new file mode 100644 index 00000000..1ec13c2e --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminLoginRequest.java @@ -0,0 +1,12 @@ +package com.atwoz.admin.application.auth.dto; + +import jakarta.validation.constraints.NotBlank; + +public record AdminLoginRequest( + @NotBlank(message = "이메일을 입력해주세요") + String email, + + @NotBlank(message = "비밀번호를 입력해주세요") + String password +) { +} diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java new file mode 100644 index 00000000..112af4ab --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java @@ -0,0 +1,7 @@ +package com.atwoz.admin.application.auth.dto; + +public record AdminProfileSignUpRequest( + String name, + String phoneNumber +) { +} diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminSignUpRequest.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminSignUpRequest.java new file mode 100644 index 00000000..ba1336fc --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminSignUpRequest.java @@ -0,0 +1,21 @@ +package com.atwoz.admin.application.auth.dto; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +public record AdminSignUpRequest( + @NotBlank(message = "이메일을 입력해주세요") + String email, + + @NotBlank(message = "비밀번호를 입력해주세요") + String password, + + @NotBlank(message = "비밀번호 확인을 위해 다시한번 입력해주세요") + String confirmPassword, + + @Valid + @NotNull(message = "관리자 프로필 정보를 입력해주세요") + AdminProfileSignUpRequest adminProfileSignUpRequest +) { +} From be5a429e5d2515f6c7d6a6906790c7c0549fd619 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:34:18 +0900 Subject: [PATCH 10/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EC=97=AD=ED=95=A0=EA=B3=BC=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=EB=A5=BC=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20enum=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Department: 관리자의 부서 - AdminStatus: 관리자 계정 사용 가능 여부 - Authority: 관리자의 권한 --- .../java/com/atwoz/admin/domain/admin/vo/AdminStatus.java | 8 ++++++++ .../java/com/atwoz/admin/domain/admin/vo/Authority.java | 6 ++++++ .../java/com/atwoz/admin/domain/admin/vo/Department.java | 5 +++++ 3 files changed, 19 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/domain/admin/vo/AdminStatus.java create mode 100644 src/main/java/com/atwoz/admin/domain/admin/vo/Authority.java create mode 100644 src/main/java/com/atwoz/admin/domain/admin/vo/Department.java diff --git a/src/main/java/com/atwoz/admin/domain/admin/vo/AdminStatus.java b/src/main/java/com/atwoz/admin/domain/admin/vo/AdminStatus.java new file mode 100644 index 00000000..af420f09 --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/vo/AdminStatus.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.domain.admin.vo; + +public enum AdminStatus { + + AVAILABLE, + UNAVAILABLE, + PENDING +} diff --git a/src/main/java/com/atwoz/admin/domain/admin/vo/Authority.java b/src/main/java/com/atwoz/admin/domain/admin/vo/Authority.java new file mode 100644 index 00000000..db3871e5 --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/vo/Authority.java @@ -0,0 +1,6 @@ +package com.atwoz.admin.domain.admin.vo; + +public enum Authority { + MASTER, + ADMIN +} diff --git a/src/main/java/com/atwoz/admin/domain/admin/vo/Department.java b/src/main/java/com/atwoz/admin/domain/admin/vo/Department.java new file mode 100644 index 00000000..d113f1f2 --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/vo/Department.java @@ -0,0 +1,5 @@ +package com.atwoz.admin.domain.admin.vo; + +public enum Department { + OPERATION +} From 6c929bad45e42018996e5941d5c1004feb9b052c Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:35:32 +0900 Subject: [PATCH 11/66] =?UTF-8?q?feat:=20AT=EA=B0=80=20=EB=A7=8C=EB=A3=8C?= =?UTF-8?q?=EB=90=98=EC=97=88=EC=9D=84=20=EB=95=8C=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=9C=A0=EC=A0=80=EC=9D=98=20RT=EB=A5=BC?= =?UTF-8?q?=20Argument=20Resolver=EB=A5=BC=20=ED=86=B5=ED=95=B4=20?= =?UTF-8?q?=EC=86=90=EC=89=BD=EA=B2=8C=20=EB=B0=9B=EC=9D=84=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EC=9C=84=ED=95=B4=20=EC=96=B4=EB=85=B8=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminRefreshToken --- .../admin/ui/auth/support/AdminRefreshToken.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/AdminRefreshToken.java diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/AdminRefreshToken.java b/src/main/java/com/atwoz/admin/ui/auth/support/AdminRefreshToken.java new file mode 100644 index 00000000..f10a0fdd --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/AdminRefreshToken.java @@ -0,0 +1,11 @@ +package com.atwoz.admin.ui.auth.support; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface AdminRefreshToken { +} From 55b13a1339aee9346ffd1a82e8812cc084787ac6 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:36:21 +0900 Subject: [PATCH 12/66] =?UTF-8?q?feat:=20=EA=B2=80=EC=A6=9D=EB=90=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=EC=9D=98=20id=20=EA=B0=92=EC=9D=84?= =?UTF-8?q?=20argument=20resolver=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=B4?= =?UTF-8?q?=20=EC=89=BD=EA=B2=8C=20=EB=84=98=EA=B2=A8=EB=B0=9B=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AuthAdmin --- .../com/atwoz/admin/ui/auth/support/AuthAdmin.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/AuthAdmin.java diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/AuthAdmin.java b/src/main/java/com/atwoz/admin/ui/auth/support/AuthAdmin.java new file mode 100644 index 00000000..6334786c --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/AuthAdmin.java @@ -0,0 +1,11 @@ +package com.atwoz.admin.ui.auth.support; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuthAdmin { +} From d02be3bcb491776033110a69357f9ca67904d62c Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:37:02 +0900 Subject: [PATCH 13/66] =?UTF-8?q?remove:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=B4=EC=A7=84=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/atwoz/member/config/AuthConfig.java | 69 ------------ .../member/domain/auth/TokenProvider.java | 10 -- .../LoginValidCheckerInterceptor.java | 35 ------ .../ParseMemberIdFromTokenInterceptor.java | 30 ------ .../TokenRegenerateInterceptor.java | 50 --------- .../support/auth/AuthenticationContext.java | 31 ------ .../LoginValidCheckerInterceptorTest.java | 42 -------- .../TokenRegenerateInterceptorTest.java | 54 ---------- .../auth/AuthenticationContextTest.java | 56 ---------- .../auth/AuthenticationExtractorTest.java | 100 ------------------ 10 files changed, 477 deletions(-) delete mode 100644 src/main/java/com/atwoz/member/config/AuthConfig.java delete mode 100644 src/main/java/com/atwoz/member/domain/auth/TokenProvider.java delete mode 100644 src/main/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptor.java delete mode 100644 src/main/java/com/atwoz/member/ui/auth/interceptor/ParseMemberIdFromTokenInterceptor.java delete mode 100644 src/main/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptor.java delete mode 100644 src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContext.java delete mode 100644 src/test/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptorTest.java delete mode 100644 src/test/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptorTest.java delete mode 100644 src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContextTest.java delete mode 100644 src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractorTest.java diff --git a/src/main/java/com/atwoz/member/config/AuthConfig.java b/src/main/java/com/atwoz/member/config/AuthConfig.java deleted file mode 100644 index 43b0912e..00000000 --- a/src/main/java/com/atwoz/member/config/AuthConfig.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.atwoz.member.config; - -import com.atwoz.member.ui.auth.interceptor.LoginValidCheckerInterceptor; -import com.atwoz.member.ui.auth.interceptor.ParseMemberIdFromTokenInterceptor; -import com.atwoz.member.ui.auth.interceptor.PathMatcherInterceptor; -import com.atwoz.member.ui.auth.interceptor.TokenRegenerateInterceptor; -import com.atwoz.member.ui.auth.support.resolver.AuthArgumentResolver; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.DELETE; -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.GET; -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.OPTIONS; -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.PATCH; -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.POST; - -@RequiredArgsConstructor -@Configuration -public class AuthConfig implements WebMvcConfigurer { - - private final AuthArgumentResolver authArgumentResolver; - private final ParseMemberIdFromTokenInterceptor parseMemberIdFromTokenInterceptor; - private final LoginValidCheckerInterceptor loginValidCheckerInterceptor; - private final TokenRegenerateInterceptor tokenRegenerateInterceptor; - - @Override - public void addInterceptors(final InterceptorRegistry registry) { - registry.addInterceptor(parseMemberIdFromTokenInterceptor()); - registry.addInterceptor(loginValidCheckerInterceptor()); - registry.addInterceptor(tokenRegenerateInterceptor()); - } - - private HandlerInterceptor parseMemberIdFromTokenInterceptor() { - return new PathMatcherInterceptor(parseMemberIdFromTokenInterceptor) - .excludePathPattern("/**", OPTIONS) - .addPathPatterns("/api/info/**", GET, POST, PATCH) - .addPathPatterns("/api/surveys/**", GET, POST) - .addPathPatterns("/api/members/me/missions/**", GET, POST, PATCH) - .addPathPatterns("/api/members/me/surveys/**", GET, POST); - } - - /** - * @AuthMember를 통해서 인증이 필요한 경우에 해당 메서드에 URI를 추가해주면 된다. 추가를 해야지 인증,인가 가능 - */ - private HandlerInterceptor loginValidCheckerInterceptor() { - return new PathMatcherInterceptor(loginValidCheckerInterceptor) - .excludePathPattern("/**", OPTIONS) - .excludePathPattern("/api/missions/**", GET, POST, PATCH, DELETE) - .excludePathPattern("/api/surveys/**", GET, POST) - .addPathPatterns("/api/members/**", GET, POST, PATCH, DELETE) - .addPathPatterns("/api/reports/**", POST); - } - - private HandlerInterceptor tokenRegenerateInterceptor() { - return new PathMatcherInterceptor(tokenRegenerateInterceptor) - .excludePathPattern("/**", OPTIONS) - .addPathPatterns("/api/auth/login", POST); - } - - @Override - public void addArgumentResolvers(final List resolvers) { - resolvers.add(authArgumentResolver); - } -} diff --git a/src/main/java/com/atwoz/member/domain/auth/TokenProvider.java b/src/main/java/com/atwoz/member/domain/auth/TokenProvider.java deleted file mode 100644 index e5e27192..00000000 --- a/src/main/java/com/atwoz/member/domain/auth/TokenProvider.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.atwoz.member.domain.auth; - -public interface TokenProvider { - - String createTokenWithId(Long id); - - String createTokenWithPhoneNumber(String phoneNumber); - - T extract(String token, String claimName, Class classType); -} diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptor.java b/src/main/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptor.java deleted file mode 100644 index 23681fca..00000000 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptor.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -@RequiredArgsConstructor -@Component -public class LoginValidCheckerInterceptor implements HandlerInterceptor { - - private static final String MEMBER_ID = "id"; - - private final TokenProvider tokenProvider; - private final AuthenticationContext authenticationContext; - private final AuthenticationExtractor authenticationExtractor; - - @Override - public boolean preHandle(final HttpServletRequest request, - final HttpServletResponse response, - final Object handler) throws Exception { - String token = authenticationExtractor.extractFromRequest(request) - .orElseThrow(LoginInvalidException::new); - - Long extractedMemberId = tokenProvider.extract(token, MEMBER_ID, Long.class); - authenticationContext.setAuthentication(extractedMemberId); - - return true; - } -} diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/ParseMemberIdFromTokenInterceptor.java b/src/main/java/com/atwoz/member/ui/auth/interceptor/ParseMemberIdFromTokenInterceptor.java deleted file mode 100644 index eec586cf..00000000 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/ParseMemberIdFromTokenInterceptor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -@RequiredArgsConstructor -@Component -public class ParseMemberIdFromTokenInterceptor implements HandlerInterceptor { - - private final LoginValidCheckerInterceptor loginValidCheckerInterceptor; - private final AuthenticationContext authenticationContext; - private final AuthenticationExtractor authenticationExtractor; - - @Override - public boolean preHandle(final HttpServletRequest request, - final HttpServletResponse response, - final Object handler) throws Exception { - if (authenticationExtractor.extractFromRequest(request).isEmpty()) { - authenticationContext.setAnonymous(); - return true; - } - - return loginValidCheckerInterceptor.preHandle(request, response, handler); - } -} diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptor.java b/src/main/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptor.java deleted file mode 100644 index e5d37a50..00000000 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptor.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.domain.auth.JsonMapper; -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.domain.member.Member; -import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.exception.exceptions.member.MemberNotFoundException; -import com.atwoz.member.ui.auth.dto.TokenResponse; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.lang.Nullable; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.ModelAndView; - -@RequiredArgsConstructor -@Component -public class TokenRegenerateInterceptor implements HandlerInterceptor { - - private static final String PHONE_NUMBER = "phoneNumber"; - - private final TokenProvider tokenProvider; - private final MemberRepository memberRepository; - private final JsonMapper jsonMapper; - private final AuthenticationExtractor authenticationExtractor; - - @Override - public void postHandle(final HttpServletRequest request, - final HttpServletResponse response, - final Object handler, - final @Nullable ModelAndView modelAndView) throws Exception { - String token = authenticationExtractor.extractFromResponse(response); - String extractedPhoneNumber = tokenProvider.extract(token, PHONE_NUMBER, String.class); - - if (extractedPhoneNumber != null) { - response.resetBuffer(); - Member foundMember = findMemberByPhoneNumber(extractedPhoneNumber); - String createdToken = tokenProvider.createTokenWithId(foundMember.getId()); - byte[] convertedTokenResponse = jsonMapper.convertObjectToJsonByteArray(new TokenResponse(createdToken)); - response.getOutputStream().write(convertedTokenResponse); - } - } - - private Member findMemberByPhoneNumber(final String phoneNumber) { - return memberRepository.findByPhoneNumber(phoneNumber) - .orElseThrow(MemberNotFoundException::new); - } -} diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContext.java b/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContext.java deleted file mode 100644 index 1cfb9c50..00000000 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContext.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.atwoz.member.ui.auth.support.auth; - -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import java.util.Objects; -import org.springframework.stereotype.Component; -import org.springframework.web.context.annotation.RequestScope; - -@RequestScope -@Component -public class AuthenticationContext { - - private static final Long ANONYMOUS_MEMBER = -1L; - - private Long memberId; - - public void setAuthentication(Long memberId) { - this.memberId = memberId; - } - - public Long getPrincipal() { - if (Objects.isNull(this.memberId)) { - throw new LoginInvalidException(); - } - - return memberId; - } - - public void setAnonymous() { - this.memberId = ANONYMOUS_MEMBER; - } -} diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptorTest.java b/src/test/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptorTest.java deleted file mode 100644 index 9a5c2774..00000000 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptorTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -@SuppressWarnings("NonAsciiCharacters") -class LoginValidCheckerInterceptorTest { - - private final HttpServletRequest req = mock(HttpServletRequest.class); - private final HttpServletResponse res = mock(HttpServletResponse.class); - private final TokenProvider tokenProvider = mock(TokenProvider.class); - private final AuthenticationContext authenticationContext = mock(AuthenticationContext.class); - private final AuthenticationExtractor authenticationExtractor = mock(AuthenticationExtractor.class); - - @Test - void token이_없다면_예외를_발생한다() { - // given - LoginValidCheckerInterceptor loginValidCheckerInterceptor = new LoginValidCheckerInterceptor( - tokenProvider, - authenticationContext, - authenticationExtractor - ); - - when(req.getHeader("any")).thenReturn(null); - - // when & then - assertThatThrownBy(() -> loginValidCheckerInterceptor.preHandle(req, res, new Object())) - .isInstanceOf(LoginInvalidException.class); - } -} diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptorTest.java b/src/test/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptorTest.java deleted file mode 100644 index d0de0a61..00000000 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptorTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.domain.auth.JsonMapper; -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.exception.exceptions.auth.InvalidJsonKeyException; -import com.atwoz.member.infrastructure.member.MemberFakeRepository; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.Test; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.util.ContentCachingResponseWrapper; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@DisplayNameGeneration(ReplaceUnderscores.class) -@SuppressWarnings("NonAsciiCharacters") -class TokenRegenerateInterceptorTest { - - private final HttpServletRequest request = mock(HttpServletRequest.class); - private final ContentCachingResponseWrapper response = mock(ContentCachingResponseWrapper.class); - private final TokenProvider tokenProvider = mock(TokenProvider.class); - private final JsonMapper jsonMapper = mock(JsonMapper.class); - private final MemberRepository memberRepository = new MemberFakeRepository(); - private final AuthenticationExtractor authenticationExtractor = mock(AuthenticationExtractor.class); - - private TokenRegenerateInterceptor tokenRegenerateInterceptor; - - @BeforeEach - void setup() { - tokenRegenerateInterceptor = new TokenRegenerateInterceptor( - tokenProvider, - memberRepository, - jsonMapper, - authenticationExtractor - ); - } - - @Test - void token이_없으면_예외가_발생한다() { - // given - when(authenticationExtractor.extractFromResponse(response)).thenThrow(InvalidJsonKeyException.class); - - // when & then - assertThatThrownBy( - () -> tokenRegenerateInterceptor.postHandle(request, response, new Object(), new ModelAndView())) - .isInstanceOf(InvalidJsonKeyException.class); - } -} diff --git a/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContextTest.java b/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContextTest.java deleted file mode 100644 index 5f5cab3d..00000000 --- a/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContextTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.atwoz.member.ui.auth.support.auth; - -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -@SuppressWarnings("NonAsciiCharacters") -class AuthenticationContextTest { - - private AuthenticationContext authenticationContext; - - @BeforeEach - void setup() { - authenticationContext = new AuthenticationContext(); - } - - @Test - void member_id를_반환한다() { - // given - authenticationContext.setAuthentication(1L); - - // when - Long result = authenticationContext.getPrincipal(); - - // then - assertThat(result).isEqualTo(1L); - } - - @Test - void member_id가_없다면_예외를_발생한다() { - // given - authenticationContext.setAuthentication(null); - - // when & then - assertThatThrownBy(() -> authenticationContext.getPrincipal()) - .isInstanceOf(LoginInvalidException.class); - } - - @Test - void 미확인_유저로_바꾼다() { - // given - authenticationContext.setAnonymous(); - - // when - Long result = authenticationContext.getPrincipal(); - - // then - assertThat(result).isEqualTo(-1L); - } -} diff --git a/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractorTest.java b/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractorTest.java deleted file mode 100644 index 9606cf94..00000000 --- a/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractorTest.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.atwoz.member.ui.auth.support.auth; - -import com.atwoz.member.domain.auth.JsonMapper; -import com.atwoz.member.exception.exceptions.auth.InvalidJsonKeyException; -import com.fasterxml.jackson.core.JsonProcessingException; -import jakarta.servlet.http.HttpServletRequest; -import java.util.Optional; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.web.util.ContentCachingResponseWrapper; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.SoftAssertions.assertSoftly; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -@SuppressWarnings("NonAsciiCharacters") -class AuthenticationExtractorTest { - - private static final String AUTHORIZATION_HEADER = "Authorization"; - private static final String BEARER = "Bearer"; - - private final HttpServletRequest request = mock(HttpServletRequest.class); - private final ContentCachingResponseWrapper response = mock(ContentCachingResponseWrapper.class); - private final JsonMapper jsonMapper = mock(JsonMapper.class); - private AuthenticationExtractor authenticationExtractor; - - @BeforeEach - void setup() { - authenticationExtractor = new AuthenticationExtractor(jsonMapper); - } - - - @Nested - class 요청에서_토큰_추출 { - - @Test - void 토큰이_정상적으로_조회된다() { - // given - String expectedResponseToken = BEARER + " tokenSignature"; - when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn(expectedResponseToken); - - // when - Optional result = authenticationExtractor.extractFromRequest(request); - - // then - assertSoftly(softly -> { - softly.assertThat(result).isPresent(); - softly.assertThat(result).isEqualTo(Optional.of("tokenSignature")); - }); - } - - @Test - void 토큰_헤더가_없다면_빈_값이_반환된다() { - // given - when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn("InvalidType token"); - - // when - Optional result = authenticationExtractor.extractFromRequest(request); - - // then - assertThat(result).isEmpty(); - } - } - - @Nested - class 응답에서_토큰_추출 { - - @Test - void 토큰이_정상적으로_조회된다() throws JsonProcessingException { - // given - String tokenJson = "{\"token\":\"validToken\"}"; - when(response.getContentAsByteArray()).thenReturn(tokenJson.getBytes()); - when(jsonMapper.getValueByKey(tokenJson, "token")).thenReturn("validToken"); - - // when - String extractedToken = authenticationExtractor.extractFromResponse(response); - - // then - assertThat(extractedToken).isEqualTo("validToken"); - } - - @Test - void 응답_body에_토큰의_정보가_없으면_예외가_발생한다() { - // given - String invalidToken = "invalidToken"; - when(response.getContentAsByteArray()).thenReturn(invalidToken.getBytes()); - when(jsonMapper.getValueByKey(invalidToken, "token")).thenThrow(InvalidJsonKeyException.class); - - // when & then - assertThatThrownBy(() -> authenticationExtractor.extractFromResponse(response)) - .isInstanceOf(InvalidJsonKeyException.class); - } - } -} From b62f73d7cc833f25f60be6ed947c6d835399d26e Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:38:37 +0900 Subject: [PATCH 14/66] =?UTF-8?q?move:=20=ED=8C=8C=EC=9D=BC=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interceptor/PathMatcherInterceptor.java | 4 +- .../interceptor/support}/HttpMethod.java | 2 +- .../interceptor/support}/PathContainer.java | 7 ++- .../interceptor/support}/PathRequest.java | 2 +- ...uthService.java => MemberAuthService.java} | 24 ++++----- .../atwoz/member/config/MemberAuthConfig.java | 51 +++++++++++++++++++ ....java => MemberLoginInvalidException.java} | 4 +- ...java => MemberJwtMemberTokenProvider.java} | 42 ++++++++++----- ...troller.java => MemberAuthController.java} | 12 ++--- .../auth/support/{auth => }/AuthMember.java | 2 +- ...ava => MemberAuthenticationExtractor.java} | 23 ++------- .../support/{auth => }/OAuthAuthority.java | 2 +- .../support/{auth => }/OAuthPlatform.java | 2 +- .../support/{auth => }/OAuthProperties.java | 2 +- ...r.java => MemberAuthArgumentResolver.java} | 18 ++----- 15 files changed, 119 insertions(+), 78 deletions(-) rename src/main/java/com/atwoz/{member/ui/auth => global/config}/interceptor/PathMatcherInterceptor.java (91%) rename src/main/java/com/atwoz/{member/ui/auth/interceptor => global/config/interceptor/support}/HttpMethod.java (84%) rename src/main/java/com/atwoz/{member/ui/auth/interceptor => global/config/interceptor/support}/PathContainer.java (96%) rename src/main/java/com/atwoz/{member/ui/auth/interceptor => global/config/interceptor/support}/PathRequest.java (91%) rename src/main/java/com/atwoz/member/application/auth/{AuthService.java => MemberAuthService.java} (57%) create mode 100644 src/main/java/com/atwoz/member/config/MemberAuthConfig.java rename src/main/java/com/atwoz/member/exception/exceptions/auth/{LoginInvalidException.java => MemberLoginInvalidException.java} (52%) rename src/main/java/com/atwoz/member/infrastructure/auth/{JwtTokenProvider.java => MemberJwtMemberTokenProvider.java} (66%) rename src/main/java/com/atwoz/member/ui/auth/{AuthController.java => MemberAuthController.java} (74%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth => }/AuthMember.java (84%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth/AuthenticationExtractor.java => MemberAuthenticationExtractor.java} (56%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthAuthority.java (85%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthPlatform.java (92%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthProperties.java (92%) rename src/main/java/com/atwoz/member/ui/auth/support/resolver/{AuthArgumentResolver.java => MemberAuthArgumentResolver.java} (65%) diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathMatcherInterceptor.java b/src/main/java/com/atwoz/global/config/interceptor/PathMatcherInterceptor.java similarity index 91% rename from src/main/java/com/atwoz/member/ui/auth/interceptor/PathMatcherInterceptor.java rename to src/main/java/com/atwoz/global/config/interceptor/PathMatcherInterceptor.java index 51e8cd30..00e1dcb5 100644 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathMatcherInterceptor.java +++ b/src/main/java/com/atwoz/global/config/interceptor/PathMatcherInterceptor.java @@ -1,5 +1,7 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global.config.interceptor; +import com.atwoz.global.config.interceptor.support.HttpMethod; +import com.atwoz.global.config.interceptor.support.PathContainer; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/HttpMethod.java b/src/main/java/com/atwoz/global/config/interceptor/support/HttpMethod.java similarity index 84% rename from src/main/java/com/atwoz/member/ui/auth/interceptor/HttpMethod.java rename to src/main/java/com/atwoz/global/config/interceptor/support/HttpMethod.java index d61ba25e..267b9e2a 100644 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/HttpMethod.java +++ b/src/main/java/com/atwoz/global/config/interceptor/support/HttpMethod.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global.config.interceptor.support; public enum HttpMethod { diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathContainer.java b/src/main/java/com/atwoz/global/config/interceptor/support/PathContainer.java similarity index 96% rename from src/main/java/com/atwoz/member/ui/auth/interceptor/PathContainer.java rename to src/main/java/com/atwoz/global/config/interceptor/support/PathContainer.java index 53bffbf0..f955fa96 100644 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathContainer.java +++ b/src/main/java/com/atwoz/global/config/interceptor/support/PathContainer.java @@ -1,10 +1,9 @@ -package com.atwoz.member.ui.auth.interceptor; - -import org.springframework.util.AntPathMatcher; -import org.springframework.util.PathMatcher; +package com.atwoz.global.config.interceptor.support; import java.util.ArrayList; import java.util.List; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.PathMatcher; public class PathContainer { diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathRequest.java b/src/main/java/com/atwoz/global/config/interceptor/support/PathRequest.java similarity index 91% rename from src/main/java/com/atwoz/member/ui/auth/interceptor/PathRequest.java rename to src/main/java/com/atwoz/global/config/interceptor/support/PathRequest.java index 44301134..2c6ed0b9 100644 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathRequest.java +++ b/src/main/java/com/atwoz/global/config/interceptor/support/PathRequest.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global.config.interceptor.support; import org.springframework.util.PathMatcher; diff --git a/src/main/java/com/atwoz/member/application/auth/AuthService.java b/src/main/java/com/atwoz/member/application/auth/MemberAuthService.java similarity index 57% rename from src/main/java/com/atwoz/member/application/auth/AuthService.java rename to src/main/java/com/atwoz/member/application/auth/MemberAuthService.java index 4183b5a4..f6383453 100644 --- a/src/main/java/com/atwoz/member/application/auth/AuthService.java +++ b/src/main/java/com/atwoz/member/application/auth/MemberAuthService.java @@ -1,9 +1,9 @@ package com.atwoz.member.application.auth; -import com.atwoz.global.event.Events; import com.atwoz.member.application.auth.dto.LoginRequest; -import com.atwoz.member.application.auth.event.ValidatedLoginEvent; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; +import com.atwoz.member.domain.member.Member; +import com.atwoz.member.domain.member.MemberRepository; import com.atwoz.member.infrastructure.auth.dto.MemberInfoResponse; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; import lombok.RequiredArgsConstructor; @@ -12,23 +12,23 @@ @RequiredArgsConstructor @Service -public class AuthService { +public class MemberAuthService { private static final String DEFAULT_PHONE_NUMBER = "01011111111"; - private final TokenProvider tokenProvider; + private final MemberTokenProvider memberTokenProvider; private final OAuthRequester oAuthRequester; + private final MemberRepository memberRepository; + /** + * OAuth 인증방식과 PASS 인증 방식에 차이가 존재해서 회의 후 메서드 변경을 진행할 예정 + */ @Transactional public String login(final LoginRequest request, final OAuthProviderRequest provider) { String accessToken = oAuthRequester.getAccessToken(request.code(), provider); MemberInfoResponse memberInfoResponse = oAuthRequester.getMemberInfo(accessToken, provider); - - /** - * OAuth 인증방식과 PASS 인증 방식에 차이가 존재해서 회의 후 메서드 변경을 진행할 예정 - */ - Events.raise(new ValidatedLoginEvent(DEFAULT_PHONE_NUMBER)); - - return tokenProvider.createTokenWithPhoneNumber(DEFAULT_PHONE_NUMBER); + Member createdMember = Member.createWithOAuth(DEFAULT_PHONE_NUMBER); + memberRepository.save(createdMember); + return memberTokenProvider.createAccessToken(createdMember.getId()); } } diff --git a/src/main/java/com/atwoz/member/config/MemberAuthConfig.java b/src/main/java/com/atwoz/member/config/MemberAuthConfig.java new file mode 100644 index 00000000..8dac265f --- /dev/null +++ b/src/main/java/com/atwoz/member/config/MemberAuthConfig.java @@ -0,0 +1,51 @@ +package com.atwoz.member.config; + +import com.atwoz.global.config.interceptor.PathMatcherInterceptor; +import com.atwoz.member.ui.auth.interceptor.MemberLoginValidCheckerInterceptor; +import com.atwoz.member.ui.auth.support.resolver.MemberAuthArgumentResolver; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import static com.atwoz.global.config.interceptor.support.HttpMethod.DELETE; +import static com.atwoz.global.config.interceptor.support.HttpMethod.GET; +import static com.atwoz.global.config.interceptor.support.HttpMethod.OPTIONS; +import static com.atwoz.global.config.interceptor.support.HttpMethod.PATCH; +import static com.atwoz.global.config.interceptor.support.HttpMethod.POST; + +@RequiredArgsConstructor +@Configuration +public class MemberAuthConfig implements WebMvcConfigurer { + + private final MemberAuthArgumentResolver memberAuthArgumentResolver; + private final MemberLoginValidCheckerInterceptor memberLoginValidCheckerInterceptor; + + @Override + public void addInterceptors(final InterceptorRegistry registry) { + registry.addInterceptor(loginValidCheckerInterceptor()); + } + + /** + * @AuthMember를 통해서 인증이 필요한 경우에 해당 메서드에 URI를 추가해주면 된다. 추가를 해야지 인증,인가 가능 + */ + private HandlerInterceptor loginValidCheckerInterceptor() { + return new PathMatcherInterceptor(memberLoginValidCheckerInterceptor) + .excludePathPattern("/**", OPTIONS) + .excludePathPattern("/api/missions/**", GET, POST, PATCH, DELETE) + .excludePathPattern("/api/surveys/**", GET, POST) + .addPathPatterns("/api/members/**", GET, POST, PATCH, DELETE) + .addPathPatterns("/api/reports/**", POST) + .addPathPatterns("/api/surveys/**", GET, POST) + .addPathPatterns("/api/members/me/missions/**", GET, POST, PATCH) + .addPathPatterns("/api/members/me/surveys/**", GET, POST); + } + + @Override + public void addArgumentResolvers(final List resolvers) { + resolvers.add(memberAuthArgumentResolver); + } +} diff --git a/src/main/java/com/atwoz/member/exception/exceptions/auth/LoginInvalidException.java b/src/main/java/com/atwoz/member/exception/exceptions/auth/MemberLoginInvalidException.java similarity index 52% rename from src/main/java/com/atwoz/member/exception/exceptions/auth/LoginInvalidException.java rename to src/main/java/com/atwoz/member/exception/exceptions/auth/MemberLoginInvalidException.java index 1716d862..e217bcc0 100644 --- a/src/main/java/com/atwoz/member/exception/exceptions/auth/LoginInvalidException.java +++ b/src/main/java/com/atwoz/member/exception/exceptions/auth/MemberLoginInvalidException.java @@ -1,8 +1,8 @@ package com.atwoz.member.exception.exceptions.auth; -public class LoginInvalidException extends RuntimeException { +public class MemberLoginInvalidException extends RuntimeException { - public LoginInvalidException() { + public MemberLoginInvalidException() { super("로그인 정보를 찾을 수 없습니다."); } } diff --git a/src/main/java/com/atwoz/member/infrastructure/auth/JwtTokenProvider.java b/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtMemberTokenProvider.java similarity index 66% rename from src/main/java/com/atwoz/member/infrastructure/auth/JwtTokenProvider.java rename to src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtMemberTokenProvider.java index 073c7df2..1df22539 100644 --- a/src/main/java/com/atwoz/member/infrastructure/auth/JwtTokenProvider.java +++ b/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtMemberTokenProvider.java @@ -1,6 +1,6 @@ package com.atwoz.member.infrastructure.auth; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; import com.atwoz.member.exception.exceptions.auth.ExpiredTokenException; import com.atwoz.member.exception.exceptions.auth.SignatureInvalidException; import com.atwoz.member.exception.exceptions.auth.TokenFormInvalidException; @@ -24,13 +24,23 @@ @NoArgsConstructor @Component -public class JwtTokenProvider implements TokenProvider { +public class MemberJwtMemberTokenProvider implements MemberTokenProvider { + + private static final String ID = "id"; + private static final String TOKEN_TYPE = "token type"; + private static final String REFRESH_TOKEN = "refresh token"; + private static final String ACCESS_TOKEN = "access token"; + private static final String ROLE = "role"; + private static final String MEMBER = "member"; @Value("${jwt.secret}") private String secret; - @Value("${jwt.expiration-period}") - private int expirationPeriod; + @Value("${jwt.access-token-expiration-period}") + private int accessTokenExpirationPeriod; + + @Value("${jwt.refresh-token-expiration-period}") + private int refreshTokenExpirationPeriod; private Key key; @@ -40,24 +50,28 @@ private void init() { } @Override - public String createTokenWithId(final Long id) { + public String createAccessToken(final Long id) { Claims claims = Jwts.claims(); - claims.put("id", id); - return createToken(claims); + claims.put(ID, id); + claims.put(TOKEN_TYPE, ACCESS_TOKEN); + claims.put(ROLE, MEMBER); + return createToken(claims, accessTokenExpirationPeriod); } @Override - public String createTokenWithPhoneNumber(final String phoneNumber) { + public String createRefreshToken(final Long id) { Claims claims = Jwts.claims(); - claims.put("phoneNumber", phoneNumber); - return createToken(claims); + claims.put(ID, id); + claims.put(TOKEN_TYPE, REFRESH_TOKEN); + claims.put(ROLE, MEMBER); + return createToken(claims, refreshTokenExpirationPeriod); } - private String createToken(final Claims claims) { + private String createToken(final Claims claims, final int expirationPeriod) { return Jwts.builder() .setClaims(claims) .setIssuedAt(issuedAt()) - .setExpiration(expiredAt()) + .setExpiration(expiredAt(expirationPeriod)) .signWith(key, SignatureAlgorithm.HS256) .compact(); } @@ -69,10 +83,10 @@ private Date issuedAt() { .toInstant()); } - private Date expiredAt() { + private Date expiredAt(final int expirationPeriod) { LocalDateTime now = LocalDateTime.now(); - return Date.from(now.plusHours(expirationPeriod) + return Date.from(now.plusDays(expirationPeriod) .atZone(ZoneId.systemDefault()) .toInstant()); } diff --git a/src/main/java/com/atwoz/member/ui/auth/AuthController.java b/src/main/java/com/atwoz/member/ui/auth/MemberAuthController.java similarity index 74% rename from src/main/java/com/atwoz/member/ui/auth/AuthController.java rename to src/main/java/com/atwoz/member/ui/auth/MemberAuthController.java index 00868d7a..79790959 100644 --- a/src/main/java/com/atwoz/member/ui/auth/AuthController.java +++ b/src/main/java/com/atwoz/member/ui/auth/MemberAuthController.java @@ -1,10 +1,10 @@ package com.atwoz.member.ui.auth; -import com.atwoz.member.application.auth.AuthService; +import com.atwoz.member.application.auth.MemberAuthService; import com.atwoz.member.application.auth.dto.LoginRequest; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; import com.atwoz.member.ui.auth.dto.TokenResponse; -import com.atwoz.member.ui.auth.support.auth.OAuthAuthority; +import com.atwoz.member.ui.auth.support.OAuthAuthority; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -14,16 +14,16 @@ import org.springframework.web.bind.annotation.RestController; @RequiredArgsConstructor -@RequestMapping("/api/auth") +@RequestMapping("/api/members/auth") @RestController -public class AuthController { +public class MemberAuthController { - private final AuthService authService; + private final MemberAuthService memberAuthService; @PostMapping("/login") public ResponseEntity login(@RequestBody @Valid final LoginRequest request, @OAuthAuthority final OAuthProviderRequest provider) { - String token = authService.login(request, provider); + String token = memberAuthService.login(request, provider); return ResponseEntity.ok(new TokenResponse(token)); } } diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthMember.java b/src/main/java/com/atwoz/member/ui/auth/support/AuthMember.java similarity index 84% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/AuthMember.java rename to src/main/java/com/atwoz/member/ui/auth/support/AuthMember.java index 7d29f516..4a1f9058 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthMember.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/AuthMember.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractor.java b/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractor.java similarity index 56% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractor.java rename to src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractor.java index 51a6f8e1..d6da4b8a 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractor.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractor.java @@ -1,28 +1,22 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; -import com.atwoz.member.domain.auth.JsonMapper; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import org.springframework.web.util.ContentCachingResponseWrapper; @RequiredArgsConstructor @Component -public class AuthenticationExtractor { +public class MemberAuthenticationExtractor { private static final String AUTHORIZATION_HEADER = "Authorization"; private static final String BEARER = "Bearer"; private static final String HEADER_SPLIT_DELIMITER = " "; - private static final String TOKEN = "token"; private static final int TOKEN_TYPE_INDEX = 0; private static final int TOKEN_VALUE_INDEX = 1; private static final int VALID_HEADER_SPLIT_LENGTH = 2; - private final JsonMapper jsonMapper; - public Optional extractFromRequest(final HttpServletRequest request) { String header = request.getHeader(AUTHORIZATION_HEADER); @@ -33,7 +27,7 @@ public Optional extractFromRequest(final HttpServletRequest request) { return extractFromHeader(header.split(HEADER_SPLIT_DELIMITER)); } - public Optional extractFromHeader(final String[] headerParts) { + private Optional extractFromHeader(final String[] headerParts) { if (headerParts.length == VALID_HEADER_SPLIT_LENGTH && headerParts[TOKEN_TYPE_INDEX].equals(BEARER)) { return Optional.ofNullable(headerParts[TOKEN_VALUE_INDEX]); @@ -41,16 +35,5 @@ public Optional extractFromHeader(final String[] headerParts) { return Optional.empty(); } - - public String extractFromResponse(final HttpServletResponse response) { - ContentCachingResponseWrapper responseWrapper = (ContentCachingResponseWrapper) response; - String responseBody = getResponseBody(responseWrapper); - - return jsonMapper.getValueByKey(responseBody, TOKEN); - } - - private String getResponseBody(final ContentCachingResponseWrapper responseWrapper) { - return new String(responseWrapper.getContentAsByteArray()); - } } diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthAuthority.java b/src/main/java/com/atwoz/member/ui/auth/support/OAuthAuthority.java similarity index 85% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthAuthority.java rename to src/main/java/com/atwoz/member/ui/auth/support/OAuthAuthority.java index 5f2a41b2..10c4f1e8 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthAuthority.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/OAuthAuthority.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatform.java b/src/main/java/com/atwoz/member/ui/auth/support/OAuthPlatform.java similarity index 92% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatform.java rename to src/main/java/com/atwoz/member/ui/auth/support/OAuthPlatform.java index 2a64d1fb..27ae49cc 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatform.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/OAuthPlatform.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import com.atwoz.member.exception.exceptions.auth.OAuthPlatformNotFountException; import java.util.Arrays; diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthProperties.java b/src/main/java/com/atwoz/member/ui/auth/support/OAuthProperties.java similarity index 92% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthProperties.java rename to src/main/java/com/atwoz/member/ui/auth/support/OAuthProperties.java index 3439f194..cd53303a 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthProperties.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/OAuthProperties.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; import java.util.Map; diff --git a/src/main/java/com/atwoz/member/ui/auth/support/resolver/AuthArgumentResolver.java b/src/main/java/com/atwoz/member/ui/auth/support/resolver/MemberAuthArgumentResolver.java similarity index 65% rename from src/main/java/com/atwoz/member/ui/auth/support/resolver/AuthArgumentResolver.java rename to src/main/java/com/atwoz/member/ui/auth/support/resolver/MemberAuthArgumentResolver.java index 930d6283..01cf7fce 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/resolver/AuthArgumentResolver.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/resolver/MemberAuthArgumentResolver.java @@ -1,8 +1,7 @@ package com.atwoz.member.ui.auth.support.resolver; -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import com.atwoz.member.ui.auth.support.auth.AuthMember; -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; +import com.atwoz.member.ui.auth.support.AuthMember; +import com.atwoz.member.ui.auth.support.MemberAuthenticationContext; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; @@ -13,11 +12,9 @@ @RequiredArgsConstructor @Component -public class AuthArgumentResolver implements HandlerMethodArgumentResolver { +public class MemberAuthArgumentResolver implements HandlerMethodArgumentResolver { - private static final int ANONYMOUS = -1; - - private final AuthenticationContext authenticationContext; + private final MemberAuthenticationContext memberAuthenticationContext; @Override public boolean supportsParameter(final MethodParameter parameter) { @@ -30,12 +27,7 @@ public Object resolveArgument(final MethodParameter parameter, final ModelAndViewContainer mavContainer, final NativeWebRequest webRequest, final WebDataBinderFactory binderFactory) throws Exception { - Long memberId = authenticationContext.getPrincipal(); - - if (memberId == ANONYMOUS) { - throw new LoginInvalidException(); - } - return memberId; + return memberAuthenticationContext.getPrincipal(); } } From b8ddb8d29e792d4b8595e46c297fab9072792d93 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:41:12 +0900 Subject: [PATCH 15/66] =?UTF-8?q?refactor:=20=ED=95=9C=20=EB=B0=94?= =?UTF-8?q?=EC=9A=B4=EB=94=94=EB=93=9C=20=EC=BB=A8=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=95=88=EC=97=90=20=EC=A1=B4=EC=9E=AC=ED=95=98?= =?UTF-8?q?=EB=8D=98=20=EA=B4=80=EB=A6=AC=EC=9E=90=EC=99=80=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EB=A5=BC=20=EC=84=9C=EB=A1=9C=20=EB=8B=A4=EB=A5=B8=20?= =?UTF-8?q?=EC=BB=A8=ED=85=8D=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/auth/MemberTokenProvider.java | 10 ++++++ .../exception/MemberExceptionHandler.java | 6 ++-- .../MemberLoginValidCheckerInterceptor.java | 34 +++++++++++++++++++ .../support/MemberAuthenticationContext.java | 25 ++++++++++++++ .../resolver/OAuthArgumentResolver.java | 4 +-- .../member/ui/member/MemberController.java | 2 +- 6 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/atwoz/member/domain/auth/MemberTokenProvider.java create mode 100644 src/main/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptor.java create mode 100644 src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContext.java diff --git a/src/main/java/com/atwoz/member/domain/auth/MemberTokenProvider.java b/src/main/java/com/atwoz/member/domain/auth/MemberTokenProvider.java new file mode 100644 index 00000000..01f63460 --- /dev/null +++ b/src/main/java/com/atwoz/member/domain/auth/MemberTokenProvider.java @@ -0,0 +1,10 @@ +package com.atwoz.member.domain.auth; + +public interface MemberTokenProvider { + + String createAccessToken(Long id); + + String createRefreshToken(Long id); + + T extract(String token, String claimName, Class classType); +} diff --git a/src/main/java/com/atwoz/member/exception/MemberExceptionHandler.java b/src/main/java/com/atwoz/member/exception/MemberExceptionHandler.java index 76e4ffb9..cd13c9e0 100644 --- a/src/main/java/com/atwoz/member/exception/MemberExceptionHandler.java +++ b/src/main/java/com/atwoz/member/exception/MemberExceptionHandler.java @@ -3,7 +3,7 @@ import com.atwoz.member.exception.exceptions.auth.ExpiredTokenException; import com.atwoz.member.exception.exceptions.auth.InvalidJsonKeyException; import com.atwoz.member.exception.exceptions.auth.JsonDataInvalidException; -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; import com.atwoz.member.exception.exceptions.auth.OAuthPlatformNotFountException; import com.atwoz.member.exception.exceptions.auth.SignatureInvalidException; import com.atwoz.member.exception.exceptions.auth.TokenFormInvalidException; @@ -85,8 +85,8 @@ public ResponseEntity handleTokenInvalidException(final TokenInvalidExce return getUnauthorized(e); } - @ExceptionHandler(LoginInvalidException.class) - public ResponseEntity handleLoginInvalidException(final LoginInvalidException e) { + @ExceptionHandler(MemberLoginInvalidException.class) + public ResponseEntity handleLoginInvalidException(final MemberLoginInvalidException e) { return getUnauthorized(e); } diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptor.java b/src/main/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptor.java new file mode 100644 index 00000000..9475d5e2 --- /dev/null +++ b/src/main/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptor.java @@ -0,0 +1,34 @@ +package com.atwoz.member.ui.auth.interceptor; + +import com.atwoz.member.domain.auth.MemberTokenProvider; +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; +import com.atwoz.member.ui.auth.support.MemberAuthenticationContext; +import com.atwoz.member.ui.auth.support.MemberAuthenticationExtractor; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +@RequiredArgsConstructor +@Component +public class MemberLoginValidCheckerInterceptor implements HandlerInterceptor { + + private static final String MEMBER_ID = "id"; + + private final MemberAuthenticationContext memberAuthenticationContext; + private final MemberAuthenticationExtractor memberAuthenticationExtractor; + private final MemberTokenProvider memberTokenProvider; + + @Override + public boolean preHandle(final HttpServletRequest request, + final HttpServletResponse response, + final Object handler) throws Exception { + String token = memberAuthenticationExtractor.extractFromRequest(request) + .orElseThrow(MemberLoginInvalidException::new); + Long extractedId = memberTokenProvider.extract(token, MEMBER_ID, Long.class); + memberAuthenticationContext.setAuthentication(extractedId); + + return true; + } +} diff --git a/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContext.java b/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContext.java new file mode 100644 index 00000000..3ab06f7c --- /dev/null +++ b/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContext.java @@ -0,0 +1,25 @@ +package com.atwoz.member.ui.auth.support; + +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; +import java.util.Objects; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +@RequestScope +@Component +public class MemberAuthenticationContext { + + private Long memberId; + + public void setAuthentication(final Long memberId) { + this.memberId = memberId; + } + + public Long getPrincipal() { + if (Objects.isNull(this.memberId)) { + throw new MemberLoginInvalidException(); + } + + return memberId; + } +} diff --git a/src/main/java/com/atwoz/member/ui/auth/support/resolver/OAuthArgumentResolver.java b/src/main/java/com/atwoz/member/ui/auth/support/resolver/OAuthArgumentResolver.java index 4a8fe4d4..998460e1 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/resolver/OAuthArgumentResolver.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/resolver/OAuthArgumentResolver.java @@ -1,8 +1,8 @@ package com.atwoz.member.ui.auth.support.resolver; import com.atwoz.member.domain.auth.JsonMapper; -import com.atwoz.member.ui.auth.support.auth.OAuthAuthority; -import com.atwoz.member.ui.auth.support.auth.OAuthProperties; +import com.atwoz.member.ui.auth.support.OAuthAuthority; +import com.atwoz.member.ui.auth.support.OAuthProperties; import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; diff --git a/src/main/java/com/atwoz/member/ui/member/MemberController.java b/src/main/java/com/atwoz/member/ui/member/MemberController.java index d9263f6f..40d12ada 100644 --- a/src/main/java/com/atwoz/member/ui/member/MemberController.java +++ b/src/main/java/com/atwoz/member/ui/member/MemberController.java @@ -5,7 +5,7 @@ import com.atwoz.member.application.member.dto.MemberInitializeRequest; import com.atwoz.member.application.member.dto.MemberUpdateRequest; import com.atwoz.member.infrastructure.member.dto.MemberResponse; -import com.atwoz.member.ui.auth.support.auth.AuthMember; +import com.atwoz.member.ui.auth.support.AuthMember; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; From 99a5b5eda43d9c6c6c8ed49e6f69f2f054b89719 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:45:49 +0900 Subject: [PATCH 16/66] =?UTF-8?q?refactor:=20Member=20=EB=B0=94=EC=9A=B4?= =?UTF-8?q?=EB=94=94=EB=93=9C=20=EC=BB=A8=ED=85=8D=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mission/ui/membermission/MemberMissionsController.java | 2 +- src/main/java/com/atwoz/report/ui/ReportController.java | 2 +- .../survey/ui/membersurvey/MemberSurveysController.java | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/atwoz/mission/ui/membermission/MemberMissionsController.java b/src/main/java/com/atwoz/mission/ui/membermission/MemberMissionsController.java index 1bd7dce2..d5946377 100644 --- a/src/main/java/com/atwoz/mission/ui/membermission/MemberMissionsController.java +++ b/src/main/java/com/atwoz/mission/ui/membermission/MemberMissionsController.java @@ -1,6 +1,6 @@ package com.atwoz.mission.ui.membermission; -import com.atwoz.member.ui.auth.support.auth.AuthMember; +import com.atwoz.member.ui.auth.support.AuthMember; import com.atwoz.mission.application.membermission.MemberMissionsQueryService; import com.atwoz.mission.intrastructure.membermission.dto.MemberMissionPagingResponse; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/atwoz/report/ui/ReportController.java b/src/main/java/com/atwoz/report/ui/ReportController.java index f3afd230..27cde16e 100644 --- a/src/main/java/com/atwoz/report/ui/ReportController.java +++ b/src/main/java/com/atwoz/report/ui/ReportController.java @@ -1,6 +1,6 @@ package com.atwoz.report.ui; -import com.atwoz.member.ui.auth.support.auth.AuthMember; +import com.atwoz.member.ui.auth.support.AuthMember; import com.atwoz.report.application.ReportService; import com.atwoz.report.application.dto.ReportCreateRequest; import jakarta.validation.Valid; diff --git a/src/main/java/com/atwoz/survey/ui/membersurvey/MemberSurveysController.java b/src/main/java/com/atwoz/survey/ui/membersurvey/MemberSurveysController.java index 46ec5e9a..7aa15f71 100644 --- a/src/main/java/com/atwoz/survey/ui/membersurvey/MemberSurveysController.java +++ b/src/main/java/com/atwoz/survey/ui/membersurvey/MemberSurveysController.java @@ -1,12 +1,13 @@ package com.atwoz.survey.ui.membersurvey; -import com.atwoz.member.ui.auth.support.auth.AuthMember; +import com.atwoz.member.ui.auth.support.AuthMember; import com.atwoz.survey.application.membersurvey.MemberSurveysQueryService; import com.atwoz.survey.application.membersurvey.MemberSurveysService; import com.atwoz.survey.application.membersurvey.dto.SurveySubmitRequest; import com.atwoz.survey.infrastructure.membersurvey.dto.MemberSurveyResponse; import com.atwoz.survey.ui.membersurvey.dto.MatchMemberSearchResponse; import jakarta.validation.Valid; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -17,8 +18,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @RequiredArgsConstructor @RequestMapping("/api/members/me/surveys") @RestController From 41788fc7bf099cfc8d29890fedee8642375c79c4 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:46:22 +0900 Subject: [PATCH 17/66] =?UTF-8?q?test:=20AdminAuthController=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/auth/AdminAuthControllerTest.java | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/ui/auth/AdminAuthControllerTest.java diff --git a/src/test/java/com/atwoz/admin/ui/auth/AdminAuthControllerTest.java b/src/test/java/com/atwoz/admin/ui/auth/AdminAuthControllerTest.java new file mode 100644 index 00000000..84ea99d4 --- /dev/null +++ b/src/test/java/com/atwoz/admin/ui/auth/AdminAuthControllerTest.java @@ -0,0 +1,137 @@ +package com.atwoz.admin.ui.auth; + +import com.atwoz.admin.application.auth.AdminAuthService; +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; +import com.atwoz.helper.MockBeanInjection; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import static com.atwoz.admin.fixture.AdminRequestFixture.관리자_로그인_요청; +import static com.atwoz.admin.fixture.AdminRequestFixture.관리자_회원_가입_요청; +import static com.atwoz.admin.fixture.AdminTokenResponseFixture.관리자_액세스_토큰_생성_응답; +import static com.atwoz.admin.fixture.AdminTokenResponseFixture.관리자_토큰_생성_응답; +import static com.atwoz.helper.RestDocsHelper.customDocument; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@AutoConfigureRestDocs +@WebMvcTest(AdminAuthController.class) +class AdminAuthControllerTest extends MockBeanInjection { + + private static final String BEARER_TOKEN = "Bearer token"; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + @Autowired + private AdminAuthService adminAuthService; + + @Test + void 회원_가입을_진행한다() throws Exception { + // given + AdminSignUpRequest adminSignUpRequest = 관리자_회원_가입_요청(); + AdminTokenResponse adminTokenResponse = 관리자_토큰_생성_응답(); + when(adminAuthService.signUp(adminSignUpRequest)).thenReturn(adminTokenResponse); + + // when & then + mockMvc.perform(post("/api/admins/auth/sign-up") + .content(objectMapper.writeValueAsString(adminSignUpRequest)) + .contentType(MediaType.APPLICATION_JSON) + ).andExpect(status().isOk()) + .andDo(customDocument("관리자_회원가입", + requestFields( + fieldWithPath("email").description("이메일"), + fieldWithPath("password").description("비밀번호"), + fieldWithPath("confirmPassword").description("비밀번호 확인"), + fieldWithPath("adminProfileSignUpRequest").description("관리자 프로필 정보"), + fieldWithPath("adminProfileSignUpRequest.name").description("이름"), + fieldWithPath("adminProfileSignUpRequest.phoneNumber").description("전화번호") + ), + responseHeaders( + headerWithName("Cookie").description("발급된 리프레쉬 토큰") + ), + responseFields( + fieldWithPath("accessToken").description("발급된 액세스 토큰") + ) + ) + ); + } + + @Test + void 로그인을_진행한다() throws Exception { + // given + AdminLoginRequest adminLoginRequest = 관리자_로그인_요청(); + AdminTokenResponse adminTokenResponse = 관리자_토큰_생성_응답(); + when(adminAuthService.login(adminLoginRequest)).thenReturn(adminTokenResponse); + + // when & then + mockMvc.perform(post("/api/admins/auth/login") + .content(objectMapper.writeValueAsString(adminLoginRequest)) + .contentType(MediaType.APPLICATION_JSON) + ).andExpect(status().isOk()) + .andDo(print()) + .andDo(customDocument("관리자_로그인", + requestFields( + fieldWithPath("email").description("이메일"), + fieldWithPath("password").description("비밀번호") + ), + responseHeaders( + headerWithName("Cookie").description("발급된 리프레쉬 토큰") + ), + responseFields( + fieldWithPath("accessToken").description("발급된 액세스 토큰") + ) + ) + ); + } + + @Test + void 액세스_토큰을_재발행한다() throws Exception { + // given + String refreshToken = "refreshToken"; + AdminAccessTokenResponse adminAccessTokenResponse = 관리자_액세스_토큰_생성_응답(); + when(adminAuthService.reGenerateAccessToken(any())).thenReturn(adminAccessTokenResponse); + + // when & then + mockMvc.perform(post("/api/admins/auth/access-token-regeneration") + .header(AUTHORIZATION, BEARER_TOKEN) + .header(HttpHeaders.COOKIE, refreshToken) + ).andExpect(status().isOk()) + .andDo(print()) + .andDo(customDocument("관리자_액세스_토큰_재발행", + requestHeaders( + headerWithName(AUTHORIZATION).description("유저 토큰 정보"), + headerWithName("Cookie").description("이전에 발급받은 리프레쉬 토큰") + ), + responseFields( + fieldWithPath("accessToken").description("지금 발급된 액세스 토큰") + ) + ) + ); + } +} From c072bd6e50cd989d8fd3fc876b5fcf49afc4d5d7 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:46:39 +0900 Subject: [PATCH 18/66] =?UTF-8?q?test:=20AdminAuthenticationContext=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminAuthenticationContextTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContextTest.java diff --git a/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContextTest.java b/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContextTest.java new file mode 100644 index 00000000..f9f3374d --- /dev/null +++ b/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContextTest.java @@ -0,0 +1,44 @@ +package com.atwoz.admin.ui.auth.support; + +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AdminAuthenticationContextTest { + + private AdminAuthenticationContext adminAuthenticationContext; + + @BeforeEach + void setup() { + adminAuthenticationContext = new AdminAuthenticationContext(); + } + + @Test + void admin_id를_반환한다() { + // given + adminAuthenticationContext.setAuthentication(1L); + + // when + Long result = adminAuthenticationContext.getPrincipal(); + + // then + assertThat(result).isEqualTo(1L); + } + + @Test + void admin_id가_없다면_예외를_발생한다() { + // given + adminAuthenticationContext.setAuthentication(null); + + // when & then + assertThatThrownBy(() -> adminAuthenticationContext.getPrincipal()) + .isInstanceOf(AdminLoginInvalidException.class); + } +} From 3115b3c51505893b62203da4b5c67503cdd45581 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:46:53 +0900 Subject: [PATCH 19/66] =?UTF-8?q?test:=20AdminAuthenticationExtractor=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminAuthenticationExtractorTest.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractorTest.java diff --git a/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractorTest.java b/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractorTest.java new file mode 100644 index 00000000..ff6871ad --- /dev/null +++ b/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractorTest.java @@ -0,0 +1,62 @@ +package com.atwoz.admin.ui.auth.support; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AdminAuthenticationExtractorTest { + + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String BEARER = "Bearer"; + + private final HttpServletRequest request = mock(HttpServletRequest.class); + private AdminAuthenticationExtractor adminAuthenticationExtractor; + + @BeforeEach + void setup() { + adminAuthenticationExtractor = new AdminAuthenticationExtractor(); + } + + @Nested + class 요청에서_토큰_추출 { + + @Test + void 토큰이_정상적으로_조회된다() { + // given + String expectedResponseToken = BEARER + " tokenSignature"; + when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn(expectedResponseToken); + + // when + Optional result = adminAuthenticationExtractor.extractFromRequest(request); + + // then + assertSoftly(softly -> { + softly.assertThat(result).isPresent(); + softly.assertThat(result).isEqualTo(Optional.of("tokenSignature")); + }); + } + + @Test + void 토큰_헤더가_없다면_빈_값이_반환된다() { + // given + when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn("InvalidType token"); + + // when + Optional result = adminAuthenticationExtractor.extractFromRequest(request); + + // then + assertThat(result).isEmpty(); + } + } +} From 48b6564bb000652f674555c45a6462bc1e3de0eb Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:47:15 +0900 Subject: [PATCH 20/66] =?UTF-8?q?test:=20AdminAuthService=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/AdminAuthServiceTest.java | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/application/auth/AdminAuthServiceTest.java diff --git a/src/test/java/com/atwoz/admin/application/auth/AdminAuthServiceTest.java b/src/test/java/com/atwoz/admin/application/auth/AdminAuthServiceTest.java new file mode 100644 index 00000000..eff1aafb --- /dev/null +++ b/src/test/java/com/atwoz/admin/application/auth/AdminAuthServiceTest.java @@ -0,0 +1,133 @@ +package com.atwoz.admin.application.auth; + +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; +import com.atwoz.admin.domain.admin.AdminRepository; +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminNotFoundException; +import com.atwoz.admin.exception.exceptions.InvalidPasswordException; +import com.atwoz.admin.infrastructure.admin.AdminFakeRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static com.atwoz.admin.fixture.AdminFixture.관리자_생성; +import static com.atwoz.admin.fixture.AdminRequestFixture.관리자_로그인_요청; +import static com.atwoz.admin.fixture.AdminRequestFixture.관리자_회원_가입_요청; +import static com.atwoz.admin.fixture.AdminTokenResponseFixture.관리자_액세스_토큰_생성_응답; +import static com.atwoz.admin.fixture.AdminTokenResponseFixture.관리자_토큰_생성_응답; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@ExtendWith(MockitoExtension.class) +class AdminAuthServiceTest { + + private static final String EMAIL = "email@email.com"; + private static final String PASSWORD = "password"; + private static final String ID = "id"; + + @Mock + private AdminTokenProvider adminTokenProvider; + private AdminAuthService adminAuthService; + private AdminRepository adminRepository; + + @BeforeEach + void setup() { + adminRepository = new AdminFakeRepository(); + adminAuthService = new AdminAuthService(adminRepository, adminTokenProvider); + } + + @Test + void 회원_가입을_진행하면_토큰을_반환한다() { + // given + AdminSignUpRequest adminSignUpRequest = 관리자_회원_가입_요청(); + AdminTokenResponse adminTokenResponse = 관리자_토큰_생성_응답(); + when(adminTokenProvider.createAccessToken(any())).thenReturn(adminTokenResponse.accessToken()); + when(adminTokenProvider.createRefreshToken(any())).thenReturn(adminTokenResponse.refreshToken()); + + // when + AdminTokenResponse response = adminAuthService.signUp(adminSignUpRequest); + + // then + assertSoftly(softly -> { + softly.assertThat(response.accessToken()).isEqualTo(adminTokenResponse.accessToken()); + softly.assertThat(response.refreshToken()).isEqualTo(adminTokenResponse.refreshToken()); + }); + } + + @Nested + class 로그인 { + + @Test + void 로그인_입력이_올바르면_토큰을_반환한다() { + // given + adminRepository.save(관리자_생성()); + AdminLoginRequest adminLoginRequest = 관리자_로그인_요청(); + AdminTokenResponse adminTokenResponse = 관리자_토큰_생성_응답(); + when(adminTokenProvider.createAccessToken(any())).thenReturn(adminTokenResponse.accessToken()); + when(adminTokenProvider.createRefreshToken(any())).thenReturn(adminTokenResponse.refreshToken()); + + // when + AdminTokenResponse response = adminAuthService.login(adminLoginRequest); + + // then + assertSoftly(softly -> { + softly.assertThat(response.accessToken()).isEqualTo(adminTokenResponse.accessToken()); + softly.assertThat(response.refreshToken()).isEqualTo(adminTokenResponse.refreshToken()); + }); + } + + @Test + void 입력한_이메일이_올바르지_않으면_예외가_발생한다() { + // given + adminRepository.save(관리자_생성()); + String invalidEmail = "invalidEmail"; + AdminLoginRequest adminLoginRequest = 관리자_로그인_요청(invalidEmail, PASSWORD); + + // when & then + assertThatThrownBy(() -> adminAuthService.login(adminLoginRequest)) + .isInstanceOf(AdminNotFoundException.class); + } + + @Test + void 입력한_비밀번호가_올바르지_않으면_예외가_발생한다() { + // given + adminRepository.save(관리자_생성()); + String invalidPassword = "invalidPassword"; + AdminLoginRequest adminLoginRequest = 관리자_로그인_요청(EMAIL, invalidPassword); + + // when & then + assertThatThrownBy(() -> adminAuthService.login(adminLoginRequest)) + .isInstanceOf(InvalidPasswordException.class); + } + } + + @Test + void 리프레쉬_토큰으로_액세스_토큰을_재생성한다() { + // given + adminRepository.save(관리자_생성()); + Long expectedId = 1L; + String refreshToken = "refreshToken"; + AdminAccessTokenResponse adminAccessTokenResponse = 관리자_액세스_토큰_생성_응답(); + when(adminTokenProvider.extract(refreshToken, ID, Long.class)).thenReturn(expectedId); + when(adminTokenProvider.createAccessToken(any())).thenReturn(adminAccessTokenResponse.accessToken()); + + // when + AdminAccessTokenResponse response = adminAuthService.reGenerateAccessToken(refreshToken); + + // then + assertThat(response.accessToken()).isEqualTo(adminAccessTokenResponse.accessToken()); + } +} From 1ab3e4d8bd007c1036206fae3046b34956683055 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:48:02 +0900 Subject: [PATCH 21/66] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20AdminFakeRepository=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/AdminFakeRepository.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/infrastructure/admin/AdminFakeRepository.java diff --git a/src/test/java/com/atwoz/admin/infrastructure/admin/AdminFakeRepository.java b/src/test/java/com/atwoz/admin/infrastructure/admin/AdminFakeRepository.java new file mode 100644 index 00000000..ab3c9001 --- /dev/null +++ b/src/test/java/com/atwoz/admin/infrastructure/admin/AdminFakeRepository.java @@ -0,0 +1,40 @@ +package com.atwoz.admin.infrastructure.admin; + +import com.atwoz.admin.domain.admin.Admin; +import com.atwoz.admin.domain.admin.AdminRepository; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@SuppressWarnings("NonAsciiCharacters") +public class AdminFakeRepository implements AdminRepository { + + private final Map map = new HashMap<>(); + private Long id = 1L; + + @Override + public Admin save(final Admin admin) { + Admin savedAdmin = Admin.createWith( + admin.getEmail(), + admin.getPassword(), + admin.getPassword(), + admin.getName(), + admin.getPhoneNumber() + ); + + map.put(id++, savedAdmin); + return savedAdmin; + } + + @Override + public Optional findAdminById(final Long id) { + return Optional.ofNullable(map.get(id)); + } + + @Override + public Optional findAdminByEmail(final String email) { + return map.values().stream() + .filter(admin -> email.equals(admin.getEmail())) + .findAny(); + } +} From c63397cc1da901acd1c7793a9faa4b1dd03bacc3 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:48:56 +0900 Subject: [PATCH 22/66] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=ED=8E=B8=ED=95=98=EA=B2=8C=20=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20Fixture=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminFixture - AdminRequestFixture - AdminTokenResponseFixture --- .../com/atwoz/admin/fixture/AdminFixture.java | 35 ++++++++++++++++ .../admin/fixture/AdminRequestFixture.java | 40 +++++++++++++++++++ .../fixture/AdminTokenResponseFixture.java | 24 +++++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/fixture/AdminFixture.java create mode 100644 src/test/java/com/atwoz/admin/fixture/AdminRequestFixture.java create mode 100644 src/test/java/com/atwoz/admin/fixture/AdminTokenResponseFixture.java diff --git a/src/test/java/com/atwoz/admin/fixture/AdminFixture.java b/src/test/java/com/atwoz/admin/fixture/AdminFixture.java new file mode 100644 index 00000000..818f1c28 --- /dev/null +++ b/src/test/java/com/atwoz/admin/fixture/AdminFixture.java @@ -0,0 +1,35 @@ +package com.atwoz.admin.fixture; + +import com.atwoz.admin.domain.admin.Admin; + +public class AdminFixture { + + private static final String EMAIL = "email@email.com"; + private static final String PASSWORD = "password"; + private static final String NAME = "name"; + private static final String PHONE_NUMBER = "010-1234-5678"; + + public static Admin 관리자_생성() { + return Admin.createWith( + EMAIL, + PASSWORD, + PASSWORD, + NAME, + PHONE_NUMBER + ); + } + + public static Admin 관리자_생성(final String email, + final String password, + final String confirmPassword, + final String name, + final String phoneNumber) { + return Admin.createWith( + email, + password, + confirmPassword, + name, + phoneNumber + ); + } +} diff --git a/src/test/java/com/atwoz/admin/fixture/AdminRequestFixture.java b/src/test/java/com/atwoz/admin/fixture/AdminRequestFixture.java new file mode 100644 index 00000000..509098e0 --- /dev/null +++ b/src/test/java/com/atwoz/admin/fixture/AdminRequestFixture.java @@ -0,0 +1,40 @@ +package com.atwoz.admin.fixture; + +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminProfileSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; + +public class AdminRequestFixture { + + private static final String EMAIL = "email@email.com"; + private static final String PASSWORD = "password"; + private static final String NAME = "name"; + private static final String PHONE_NUMBER = "010-1234-5678"; + + public static AdminSignUpRequest 관리자_회원_가입_요청() { + return new AdminSignUpRequest( + EMAIL, + PASSWORD, + PASSWORD, + new AdminProfileSignUpRequest( + NAME, + PHONE_NUMBER + ) + ); + } + + public static AdminLoginRequest 관리자_로그인_요청() { + return new AdminLoginRequest( + EMAIL, + PASSWORD + ); + } + + public static AdminLoginRequest 관리자_로그인_요청(final String email, + final String password) { + return new AdminLoginRequest( + email, + password + ); + } +} diff --git a/src/test/java/com/atwoz/admin/fixture/AdminTokenResponseFixture.java b/src/test/java/com/atwoz/admin/fixture/AdminTokenResponseFixture.java new file mode 100644 index 00000000..c9076a9e --- /dev/null +++ b/src/test/java/com/atwoz/admin/fixture/AdminTokenResponseFixture.java @@ -0,0 +1,24 @@ +package com.atwoz.admin.fixture; + +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; + +@SuppressWarnings("NonAsciiCharacters") +public class AdminTokenResponseFixture { + + private static final String ACCESS_TOKEN = "accessToken"; + private static final String REFRESH_TOKEN = "refreshToken"; + + public static AdminTokenResponse 관리자_토큰_생성_응답() { + return new AdminTokenResponse( + ACCESS_TOKEN, + REFRESH_TOKEN + ); + } + + public static AdminAccessTokenResponse 관리자_액세스_토큰_생성_응답() { + return new AdminAccessTokenResponse( + ACCESS_TOKEN + ); + } +} From fe6d42fa68103c1a553dc746ba71fc85cc337dec Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:49:10 +0900 Subject: [PATCH 23/66] =?UTF-8?q?test:=20AdminJpaRepository=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/AdminJpaRepositoryTest.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepositoryTest.java diff --git a/src/test/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepositoryTest.java b/src/test/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepositoryTest.java new file mode 100644 index 00000000..ce5814e9 --- /dev/null +++ b/src/test/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepositoryTest.java @@ -0,0 +1,65 @@ +package com.atwoz.admin.infrastructure.admin; + +import com.atwoz.admin.domain.admin.Admin; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import static com.atwoz.admin.fixture.AdminFixture.관리자_생성; +import static org.assertj.core.api.SoftAssertions.assertSoftly; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@DataJpaTest +class AdminJpaRepositoryTest { + + @Autowired + private AdminJpaRepository adminJpaRepository; + + private Admin admin; + + @BeforeEach + void setup() { + admin = 관리자_생성(); + adminJpaRepository.save(admin); + } + + @Nested + class 회원_조회 { + + @Test + void 아이디로_관리자를_찾는다() { + // given + Long adminId = admin.getId(); + + // when + Optional foundAdmin = adminJpaRepository.findById(adminId); + + // then + assertSoftly(softly -> { + softly.assertThat(foundAdmin).isPresent(); + softly.assertThat(foundAdmin.get()).usingRecursiveComparison().isEqualTo(admin); + }); + } + + @Test + void 이메일로_관리자를_찾는다() { + // given + String adminEmail = admin.getEmail(); + + // when + Optional foundAdmin = adminJpaRepository.findAdminByEmail(adminEmail); + + // then + assertSoftly(softly -> { + softly.assertThat(foundAdmin).isPresent(); + softly.assertThat(foundAdmin.get()).usingRecursiveComparison().isEqualTo(admin); + }); + } + } +} From cba1d2875e2ea6c899976f9c51a33728bbe7a605 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:49:37 +0900 Subject: [PATCH 24/66] =?UTF-8?q?test:=20AdminLoginValidCheckerInterceptor?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...AdminLoginValidCheckerInterceptorTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptorTest.java diff --git a/src/test/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptorTest.java b/src/test/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptorTest.java new file mode 100644 index 00000000..03ce531b --- /dev/null +++ b/src/test/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptorTest.java @@ -0,0 +1,41 @@ +package com.atwoz.admin.ui.auth.interceptor; + +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationContext; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationExtractor; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AdminLoginValidCheckerInterceptorTest { + + private final HttpServletRequest req = mock(HttpServletRequest.class); + private final HttpServletResponse res = mock(HttpServletResponse.class); + private final AdminAuthenticationContext adminAuthenticationContext = mock(AdminAuthenticationContext.class); + private final AdminAuthenticationExtractor adminAuthenticationExtractor = mock(AdminAuthenticationExtractor.class); + private final AdminTokenProvider adminTokenProvider = mock(AdminTokenProvider.class); + + @Test + void token이_없다면_예외를_발생한다() { + // given + AdminLoginValidCheckerInterceptor adminLoginValidCheckerInterceptor = new AdminLoginValidCheckerInterceptor( + adminAuthenticationContext, + adminAuthenticationExtractor, + adminTokenProvider + ); + when(req.getHeader("any")).thenReturn(null); + + // when & then + assertThatThrownBy(() -> adminLoginValidCheckerInterceptor.preHandle(req, res, new Object())) + .isInstanceOf(AdminLoginInvalidException.class); + } +} From 2912e1e733ac907e9db6d69bcf50a78036834ad4 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:49:53 +0900 Subject: [PATCH 25/66] =?UTF-8?q?test:=20Admin=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../atwoz/admin/domain/admin/AdminTest.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/domain/admin/AdminTest.java diff --git a/src/test/java/com/atwoz/admin/domain/admin/AdminTest.java b/src/test/java/com/atwoz/admin/domain/admin/AdminTest.java new file mode 100644 index 00000000..c6f88ae1 --- /dev/null +++ b/src/test/java/com/atwoz/admin/domain/admin/AdminTest.java @@ -0,0 +1,80 @@ +package com.atwoz.admin.domain.admin; + +import com.atwoz.admin.domain.admin.vo.AdminStatus; +import com.atwoz.admin.domain.admin.vo.Authority; +import com.atwoz.admin.domain.admin.vo.Department; +import com.atwoz.admin.exception.exceptions.InvalidPasswordException; +import com.atwoz.admin.exception.exceptions.PasswordMismatchException; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static com.atwoz.admin.fixture.AdminFixture.관리자_생성; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.SoftAssertions.assertSoftly; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AdminTest { + + private static final String EMAIL = "email@email.com"; + private static final String PASSWORD = "password"; + private static final String CONFIRM_PASSWORD = "password"; + private static final String NAME = "name"; + private static final String PHONE_NUMBER = "010-1234-5678"; + + @Nested + class 관리자_생성 { + + @Test + void 입력이_올바르면_관리자를_생성한다() { + // when + Admin admin = Admin.createWith( + EMAIL, + PASSWORD, + CONFIRM_PASSWORD, + NAME, + PHONE_NUMBER + ); + + // then + assertSoftly(softly -> { + softly.assertThat(admin.getEmail()).isEqualTo(EMAIL); + softly.assertThat(admin.getPassword()).isEqualTo(PASSWORD); + softly.assertThat(admin.getName()).isEqualTo(NAME); + softly.assertThat(admin.getPhoneNumber()).isEqualTo(PHONE_NUMBER); + softly.assertThat(admin.getAuthority()).isEqualTo(Authority.ADMIN); + softly.assertThat(admin.getDepartment()).isEqualTo(Department.OPERATION); + softly.assertThat(admin.getAdminStatus()).isEqualTo(AdminStatus.PENDING); + }); + + } + + @Test + void 회원_가입시_입력한_비밀번호와_확인_비밀번호가_다르면_예외가_발생한다() { + // given + String invalidConfirmPassword = "invalidConfirmPassword"; + + // when & then + assertThatThrownBy(() -> Admin.createWith( + EMAIL, + PASSWORD, + invalidConfirmPassword, + NAME, + PHONE_NUMBER + )).isInstanceOf(PasswordMismatchException.class); + } + } + + @Test + void 로그인시_입력한_비밀번호가_관리자의_비밀번호와_다르면_예외가_발생한다() { + // given + Admin admin = 관리자_생성(); + String invalidPassword = "invalidPassword"; + + // when & then + assertThatThrownBy(() -> admin.validatePassword(invalidPassword)) + .isInstanceOf(InvalidPasswordException.class); + } +} From 2b0b85f02dcf512456d4ee7e6f212fd9da309bf5 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:50:49 +0900 Subject: [PATCH 26/66] =?UTF-8?q?test:=20Member=20=EB=B0=94=EC=9A=B4?= =?UTF-8?q?=EB=94=94=EB=93=9C=20=EC=BB=A8=ED=85=8D=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HttpMethodTest.java | 3 +- .../PathContainerTest.java | 4 +- .../PathRequestTest.java | 4 +- .../com/atwoz/helper/MockBeanInjection.java | 82 ++++++++++++++----- ...ceTest.java => MemberAuthServiceTest.java} | 21 ++--- ...va => MemberAuthControllerWebMvcTest.java} | 10 +-- ...emberLoginValidCheckerInterceptorTest.java | 41 ++++++++++ .../MemberAuthenticationContextTest.java | 45 ++++++++++ .../MemberAuthenticationExtractorTest.java | 62 ++++++++++++++ .../support/{auth => }/OAuthPlatformTest.java | 2 +- .../{auth => }/OAuthPropertiesTest.java | 2 +- .../MemberControllerAcceptanceFixture.java | 6 +- ...erMissionsControllerAcceptanceFixture.java | 6 +- .../ui/ReportControllerAcceptanceFixture.java | 6 +- ...berSurveysControllerAcceptanceFixture.java | 8 +- .../SurveyControllerAcceptanceFixture.java | 6 +- 16 files changed, 250 insertions(+), 58 deletions(-) rename src/test/java/com/atwoz/{member/ui/auth/interceptor => global}/HttpMethodTest.java (87%) rename src/test/java/com/atwoz/{member/ui/auth/interceptor => global}/PathContainerTest.java (91%) rename src/test/java/com/atwoz/{member/ui/auth/interceptor => global}/PathRequestTest.java (83%) rename src/test/java/com/atwoz/member/application/auth/{AuthServiceTest.java => MemberAuthServiceTest.java} (61%) rename src/test/java/com/atwoz/member/ui/auth/{AuthControllerWebMvcTest.java => MemberAuthControllerWebMvcTest.java} (89%) create mode 100644 src/test/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptorTest.java create mode 100644 src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContextTest.java create mode 100644 src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractorTest.java rename src/test/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthPlatformTest.java (96%) rename src/test/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthPropertiesTest.java (95%) diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/HttpMethodTest.java b/src/test/java/com/atwoz/global/HttpMethodTest.java similarity index 87% rename from src/test/java/com/atwoz/member/ui/auth/interceptor/HttpMethodTest.java rename to src/test/java/com/atwoz/global/HttpMethodTest.java index 524f43f6..3e3d1e28 100644 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/HttpMethodTest.java +++ b/src/test/java/com/atwoz/global/HttpMethodTest.java @@ -1,5 +1,6 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global; +import com.atwoz.global.config.interceptor.support.HttpMethod; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/PathContainerTest.java b/src/test/java/com/atwoz/global/PathContainerTest.java similarity index 91% rename from src/test/java/com/atwoz/member/ui/auth/interceptor/PathContainerTest.java rename to src/test/java/com/atwoz/global/PathContainerTest.java index 3776ec64..5c83cb7e 100644 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/PathContainerTest.java +++ b/src/test/java/com/atwoz/global/PathContainerTest.java @@ -1,5 +1,7 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global; +import com.atwoz.global.config.interceptor.support.HttpMethod; +import com.atwoz.global.config.interceptor.support.PathContainer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/PathRequestTest.java b/src/test/java/com/atwoz/global/PathRequestTest.java similarity index 83% rename from src/test/java/com/atwoz/member/ui/auth/interceptor/PathRequestTest.java rename to src/test/java/com/atwoz/global/PathRequestTest.java index 7c914b53..51deff64 100644 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/PathRequestTest.java +++ b/src/test/java/com/atwoz/global/PathRequestTest.java @@ -1,5 +1,7 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global; +import com.atwoz.global.config.interceptor.support.HttpMethod; +import com.atwoz.global.config.interceptor.support.PathRequest; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/atwoz/helper/MockBeanInjection.java b/src/test/java/com/atwoz/helper/MockBeanInjection.java index 3f22eff4..78603a63 100644 --- a/src/test/java/com/atwoz/helper/MockBeanInjection.java +++ b/src/test/java/com/atwoz/helper/MockBeanInjection.java @@ -1,15 +1,23 @@ package com.atwoz.helper; -import com.atwoz.member.application.auth.AuthService; +import com.atwoz.admin.application.auth.AdminAuthService; +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.ui.auth.interceptor.AdminLoginValidCheckerInterceptor; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationContext; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationExtractor; +import com.atwoz.admin.ui.auth.support.resolver.AdminAuthArgumentResolver; +import com.atwoz.admin.ui.auth.support.resolver.AdminRefreshTokenExtractionArgumentResolver; +import com.atwoz.member.application.auth.MemberAuthService; import com.atwoz.member.application.member.MemberQueryService; import com.atwoz.member.application.member.MemberService; -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.ui.auth.interceptor.LoginValidCheckerInterceptor; -import com.atwoz.member.ui.auth.interceptor.ParseMemberIdFromTokenInterceptor; -import com.atwoz.member.ui.auth.interceptor.TokenRegenerateInterceptor; -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; -import com.atwoz.member.ui.auth.support.auth.OAuthProperties; -import com.atwoz.member.ui.auth.support.resolver.AuthArgumentResolver; +import com.atwoz.member.domain.auth.JsonMapper; +import com.atwoz.member.domain.auth.MemberTokenProvider; +import com.atwoz.member.domain.member.MemberRepository; +import com.atwoz.member.ui.auth.interceptor.MemberLoginValidCheckerInterceptor; +import com.atwoz.member.ui.auth.support.MemberAuthenticationContext; +import com.atwoz.member.ui.auth.support.MemberAuthenticationExtractor; +import com.atwoz.member.ui.auth.support.OAuthProperties; +import com.atwoz.member.ui.auth.support.resolver.MemberAuthArgumentResolver; import com.atwoz.member.ui.auth.support.resolver.OAuthArgumentResolver; import com.atwoz.mission.application.membermission.MemberMissionsQueryService; import com.atwoz.mission.application.membermission.MemberMissionsService; @@ -25,33 +33,67 @@ @MockBean(JpaMetamodelMappingContext.class) public class MockBeanInjection { + // Member @MockBean - protected TokenProvider tokenProvider; + protected OAuthArgumentResolver oAuthArgumentResolver; + + @MockBean + protected MemberAuthArgumentResolver memberAuthArgumentResolver; + + @MockBean + protected MemberLoginValidCheckerInterceptor memberLoginValidCheckerInterceptor; @MockBean - protected AuthenticationContext authenticationContext; + protected MemberAuthenticationContext memberAuthenticationContext; @MockBean - protected AuthService authService; + protected MemberAuthenticationExtractor authenticationExtractor; @MockBean protected OAuthProperties oAuthProperties; @MockBean - protected OAuthArgumentResolver oAuthArgumentResolver; + protected MemberService memberService; + + @MockBean + protected MemberQueryService memberQueryService; + + @MockBean + protected MemberAuthService memberAuthService; + + @MockBean + protected MemberTokenProvider memberTokenProvider; + + @MockBean + protected MemberRepository memberRepository; @MockBean - protected AuthArgumentResolver authArgumentResolver; + protected JsonMapper jsonMapper; + // Admin @MockBean - protected ParseMemberIdFromTokenInterceptor parseMemberIdFromTokenInterceptor; + protected AdminAuthArgumentResolver adminAuthArgumentResolver; @MockBean - protected LoginValidCheckerInterceptor loginValidCheckerInterceptor; + protected AdminRefreshTokenExtractionArgumentResolver adminRefreshTokenExtractionArgumentResolver; @MockBean - protected TokenRegenerateInterceptor tokenRegenerateInterceptor; + protected AdminLoginValidCheckerInterceptor adminLoginValidCheckerInterceptor; + @MockBean + protected AdminAuthenticationContext adminAuthenticationContext; + + @MockBean + protected AdminAuthenticationExtractor adminAuthenticationExtractor; + + @MockBean + protected AdminAuthService adminAuthService; + + @MockBean + protected AdminTokenProvider adminTokenProvider; + + + // Mission @MockBean protected MissionService missionService; @@ -64,9 +106,7 @@ public class MockBeanInjection { @MockBean protected MemberMissionsQueryService memberMissionsQueryService; - @MockBean - protected MemberService memberService; - + // Survey @MockBean protected SurveyService surveyService; @@ -76,9 +116,7 @@ public class MockBeanInjection { @MockBean protected MemberSurveysQueryService memberSurveysQueryService; - @MockBean - protected MemberQueryService memberQueryService; - + // Report @MockBean protected ReportService reportService; } diff --git a/src/test/java/com/atwoz/member/application/auth/AuthServiceTest.java b/src/test/java/com/atwoz/member/application/auth/MemberAuthServiceTest.java similarity index 61% rename from src/test/java/com/atwoz/member/application/auth/AuthServiceTest.java rename to src/test/java/com/atwoz/member/application/auth/MemberAuthServiceTest.java index f98d4965..2c7bf9ec 100644 --- a/src/test/java/com/atwoz/member/application/auth/AuthServiceTest.java +++ b/src/test/java/com/atwoz/member/application/auth/MemberAuthServiceTest.java @@ -1,12 +1,12 @@ package com.atwoz.member.application.auth; import com.atwoz.member.application.auth.dto.LoginRequest; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; import com.atwoz.member.infrastructure.auth.OAuthFakeRequester; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; +import com.atwoz.member.infrastructure.member.MemberFakeRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -14,21 +14,22 @@ import static com.atwoz.member.fixture.OAuthProviderFixture.인증_기관_생성; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.anyString; +import static org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@DisplayNameGeneration(ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") @ExtendWith(MockitoExtension.class) -class AuthServiceTest { +class MemberAuthServiceTest { @Mock - private TokenProvider tokenProvider; - private AuthService authService; + private MemberTokenProvider memberTokenProvider; + private MemberAuthService memberAuthService; @BeforeEach void setup() { - authService = new AuthService(tokenProvider, new OAuthFakeRequester()); + memberAuthService = new MemberAuthService(memberTokenProvider, new OAuthFakeRequester(), new MemberFakeRepository()); } @Test @@ -37,10 +38,10 @@ void setup() { LoginRequest loginRequest = new LoginRequest("kakao", "code"); OAuthProviderRequest oAuthProviderRequest = 인증_기관_생성(); String expectedToken = "token"; - when(tokenProvider.createTokenWithPhoneNumber(anyString())).thenReturn(expectedToken); + when(memberTokenProvider.createAccessToken(any())).thenReturn(expectedToken); // when - String token = authService.login(loginRequest, oAuthProviderRequest); + String token = memberAuthService.login(loginRequest, oAuthProviderRequest); // then assertThat(token).isEqualTo(expectedToken); diff --git a/src/test/java/com/atwoz/member/ui/auth/AuthControllerWebMvcTest.java b/src/test/java/com/atwoz/member/ui/auth/MemberAuthControllerWebMvcTest.java similarity index 89% rename from src/test/java/com/atwoz/member/ui/auth/AuthControllerWebMvcTest.java rename to src/test/java/com/atwoz/member/ui/auth/MemberAuthControllerWebMvcTest.java index d607ab70..84ee1e17 100644 --- a/src/test/java/com/atwoz/member/ui/auth/AuthControllerWebMvcTest.java +++ b/src/test/java/com/atwoz/member/ui/auth/MemberAuthControllerWebMvcTest.java @@ -26,8 +26,8 @@ @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") @AutoConfigureRestDocs -@WebMvcTest(AuthController.class) -class AuthControllerWebMvcTest extends MockBeanInjection { +@WebMvcTest(MemberAuthController.class) +class MemberAuthControllerWebMvcTest extends MockBeanInjection { @Autowired private MockMvc mockMvc; @@ -41,15 +41,15 @@ class AuthControllerWebMvcTest extends MockBeanInjection { OAuthProviderRequest oAuthProviderRequest = 인증_기관_생성(); LoginRequest loginRequest = new LoginRequest("kakao", "code"); String expectedToken = "token"; - when(authService.login(loginRequest, oAuthProviderRequest)).thenReturn(expectedToken); + when(memberAuthService.login(loginRequest, oAuthProviderRequest)).thenReturn(expectedToken); // when & then - mockMvc.perform(post("/api/auth/login") + mockMvc.perform(post("/api/members/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(loginRequest)) ).andExpect(status().isOk()) .andDo(print()) - .andDo(customDocument("do_signup", + .andDo(customDocument("유저_로그인", requestFields( fieldWithPath("provider").description("인증기관"), fieldWithPath("code").description("인증코드") diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptorTest.java b/src/test/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptorTest.java new file mode 100644 index 00000000..0925fae8 --- /dev/null +++ b/src/test/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptorTest.java @@ -0,0 +1,41 @@ +package com.atwoz.member.ui.auth.interceptor; + +import com.atwoz.member.domain.auth.MemberTokenProvider; +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; +import com.atwoz.member.ui.auth.support.MemberAuthenticationContext; +import com.atwoz.member.ui.auth.support.MemberAuthenticationExtractor; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class MemberLoginValidCheckerInterceptorTest { + + private final HttpServletRequest req = mock(HttpServletRequest.class); + private final HttpServletResponse res = mock(HttpServletResponse.class); + private final MemberAuthenticationContext memberAuthenticationContext = mock(MemberAuthenticationContext.class); + private final MemberAuthenticationExtractor memberAuthenticationExtractor = mock(MemberAuthenticationExtractor.class); + private final MemberTokenProvider memberTokenProvider = mock(MemberTokenProvider.class); + + @Test + void token이_없다면_예외를_발생한다() { + // given + MemberLoginValidCheckerInterceptor memberLoginValidCheckerInterceptor = new MemberLoginValidCheckerInterceptor( + memberAuthenticationContext, + memberAuthenticationExtractor, + memberTokenProvider + ); + when(req.getHeader("any")).thenReturn(null); + + // when & then + assertThatThrownBy(() -> memberLoginValidCheckerInterceptor.preHandle(req, res, new Object())) + .isInstanceOf(MemberLoginInvalidException.class); + } +} diff --git a/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContextTest.java b/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContextTest.java new file mode 100644 index 00000000..b2b9b611 --- /dev/null +++ b/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContextTest.java @@ -0,0 +1,45 @@ +package com.atwoz.member.ui.auth.support; + +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class MemberAuthenticationContextTest { + + private MemberAuthenticationContext memberAuthenticationContext; + + @BeforeEach + void setup() { + memberAuthenticationContext = new MemberAuthenticationContext(); + } + + @Test + void member_id를_반환한다() { + // given + memberAuthenticationContext.setAuthentication(1L); + + // when + Long result = memberAuthenticationContext.getPrincipal(); + + // then + assertThat(result).isEqualTo(1L); + } + + @Test + void member_id가_없다면_예외를_발생한다() { + // given + memberAuthenticationContext.setAuthentication(null); + + // when & then + assertThatThrownBy(() -> memberAuthenticationContext.getPrincipal()) + .isInstanceOf(MemberLoginInvalidException.class); + } +} + diff --git a/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractorTest.java b/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractorTest.java new file mode 100644 index 00000000..9b43d47a --- /dev/null +++ b/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractorTest.java @@ -0,0 +1,62 @@ +package com.atwoz.member.ui.auth.support; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class MemberAuthenticationExtractorTest { + + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String BEARER = "Bearer"; + + private final HttpServletRequest request = mock(HttpServletRequest.class); + private MemberAuthenticationExtractor memberAuthenticationExtractor; + + @BeforeEach + void setup() { + memberAuthenticationExtractor = new MemberAuthenticationExtractor(); + } + + @Nested + class 요청에서_토큰_추출 { + + @Test + void 토큰이_정상적으로_조회된다() { + // given + String expectedResponseToken = BEARER + " tokenSignature"; + when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn(expectedResponseToken); + + // when + Optional result = memberAuthenticationExtractor.extractFromRequest(request); + + // then + assertSoftly(softly -> { + softly.assertThat(result).isPresent(); + softly.assertThat(result).isEqualTo(Optional.of("tokenSignature")); + }); + } + + @Test + void 토큰_헤더가_없다면_빈_값이_반환된다() { + // given + when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn("InvalidType token"); + + // when + Optional result = memberAuthenticationExtractor.extractFromRequest(request); + + // then + assertThat(result).isEmpty(); + } + } +} diff --git a/src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatformTest.java b/src/test/java/com/atwoz/member/ui/auth/support/OAuthPlatformTest.java similarity index 96% rename from src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatformTest.java rename to src/test/java/com/atwoz/member/ui/auth/support/OAuthPlatformTest.java index a1ffd6d1..ea165058 100644 --- a/src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatformTest.java +++ b/src/test/java/com/atwoz/member/ui/auth/support/OAuthPlatformTest.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import com.atwoz.member.exception.exceptions.auth.OAuthPlatformNotFountException; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPropertiesTest.java b/src/test/java/com/atwoz/member/ui/auth/support/OAuthPropertiesTest.java similarity index 95% rename from src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPropertiesTest.java rename to src/test/java/com/atwoz/member/ui/auth/support/OAuthPropertiesTest.java index e9bd2b8a..5047b77c 100644 --- a/src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPropertiesTest.java +++ b/src/test/java/com/atwoz/member/ui/auth/support/OAuthPropertiesTest.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; diff --git a/src/test/java/com/atwoz/member/ui/member/MemberControllerAcceptanceFixture.java b/src/test/java/com/atwoz/member/ui/member/MemberControllerAcceptanceFixture.java index 0b8f0af2..4af22e8e 100644 --- a/src/test/java/com/atwoz/member/ui/member/MemberControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/member/ui/member/MemberControllerAcceptanceFixture.java @@ -3,7 +3,7 @@ import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.application.member.dto.MemberInitializeRequest; import com.atwoz.member.application.member.dto.MemberUpdateRequest; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; import com.atwoz.member.fixture.MemberRequestFixture; @@ -31,14 +31,14 @@ public class MemberControllerAcceptanceFixture extends IntegrationHelper { protected MemberRepository memberRepository; @Autowired - protected TokenProvider tokenProvider; + protected MemberTokenProvider memberTokenProvider; protected Member 회원_생성() { return memberRepository.save(일반_유저_생성()); } protected String 토큰_생성(final Member member) { - return tokenProvider.createTokenWithId(member.getId()); + return memberTokenProvider.createAccessToken(member.getId()); } protected String 회원_닉네임을_요청한다() { diff --git a/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java b/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java index f54c15ff..45e6210b 100644 --- a/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java @@ -4,7 +4,7 @@ import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; import com.atwoz.member.domain.member.profile.physical.vo.Gender; -import com.atwoz.member.infrastructure.auth.JwtTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtMemberTokenProvider; import com.atwoz.mission.domain.membermission.MemberMission; import com.atwoz.mission.domain.membermission.MemberMissions; import com.atwoz.mission.domain.membermission.MemberMissionsRepository; @@ -31,7 +31,7 @@ class MemberMissionsControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private JwtTokenProvider jwtTokenProvider; + private MemberJwtMemberTokenProvider memberJwtTokenProvider; @Autowired private MemberRepository memberRepository; @@ -47,7 +47,7 @@ class MemberMissionsControllerAcceptanceFixture extends IntegrationHelper { } protected String 토큰_생성(final Member member) { - return jwtTokenProvider.createTokenWithId(member.getId()); + return memberJwtTokenProvider.createAccessToken(member.getId()); } protected Mission 데일리_미션_생성() { diff --git a/src/test/java/com/atwoz/report/ui/ReportControllerAcceptanceFixture.java b/src/test/java/com/atwoz/report/ui/ReportControllerAcceptanceFixture.java index aa27bb9e..e49455a3 100644 --- a/src/test/java/com/atwoz/report/ui/ReportControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/report/ui/ReportControllerAcceptanceFixture.java @@ -1,7 +1,7 @@ package com.atwoz.report.ui; import com.atwoz.helper.IntegrationHelper; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; import com.atwoz.report.application.dto.ReportCreateRequest; @@ -27,14 +27,14 @@ public class ReportControllerAcceptanceFixture extends IntegrationHelper { protected MemberRepository memberRepository; @Autowired - protected TokenProvider tokenProvider; + protected MemberTokenProvider memberTokenProvider; protected Member 회원_생성() { return memberRepository.save(일반_유저_생성()); } protected String 토큰_생성(final Member member) { - return tokenProvider.createTokenWithId(member.getId()); + return memberTokenProvider.createAccessToken(member.getId()); } protected ReportCreateRequest 신고_요청서_요청() { diff --git a/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java b/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java index de7becb0..4796f01e 100644 --- a/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java @@ -3,7 +3,7 @@ import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.infrastructure.auth.JwtTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtMemberTokenProvider; import com.atwoz.survey.application.membersurvey.dto.SurveySubmitRequest; import com.atwoz.survey.domain.survey.SurveyRepository; import com.atwoz.survey.infrastructure.membersurvey.dto.MemberSurveyResponse; @@ -11,12 +11,12 @@ import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; +import java.util.List; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; -import java.util.List; import static com.atwoz.member.fixture.MemberFixture.일반_유저_생성; import static com.atwoz.survey.fixture.SurveyFixture.연애고사_선택_과목_질문_두개씩; import static com.atwoz.survey.fixture.SurveyFixture.연애고사_필수_과목_질문_30개씩; @@ -30,7 +30,7 @@ class MemberSurveysControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private JwtTokenProvider jwtTokenProvider; + private MemberJwtMemberTokenProvider memberJwtTokenProvider; @Autowired private MemberRepository memberRepository; @@ -47,7 +47,7 @@ class MemberSurveysControllerAcceptanceFixture extends IntegrationHelper { } protected String 토큰_생성(final Member member) { - return jwtTokenProvider.createTokenWithId(member.getId()); + return memberJwtTokenProvider.createAccessToken(member.getId()); } protected void 연애고사_필수_과목_질문_두개씩_생성() { diff --git a/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java b/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java index ef6eeec6..14f99252 100644 --- a/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java @@ -3,7 +3,7 @@ import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.infrastructure.auth.JwtTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtMemberTokenProvider; import com.atwoz.survey.application.survey.dto.SurveyCreateRequest; import com.atwoz.survey.ui.survey.dto.SurveyCreateResponse; import io.restassured.RestAssured; @@ -24,7 +24,7 @@ class SurveyControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private JwtTokenProvider jwtTokenProvider; + private MemberJwtMemberTokenProvider memberJwtTokenProvider; @Autowired private MemberRepository memberRepository; @@ -34,7 +34,7 @@ class SurveyControllerAcceptanceFixture extends IntegrationHelper { } protected String 토큰_생성(final Member member) { - return jwtTokenProvider.createTokenWithId(member.getId()); + return memberJwtTokenProvider.createAccessToken(member.getId()); } protected ExtractableResponse 연애고사_과목_생성_요청(final String url, final String token, final SurveyCreateRequest request) { From db2dc4197aae3b701cde18b094dee442a8bcaa2a Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:51:41 +0900 Subject: [PATCH 27/66] =?UTF-8?q?docs:=20member=EC=99=80=20auth=EB=A1=9C?= =?UTF-8?q?=20=EB=82=98=EB=88=84=EC=96=B4=EC=A0=B8=20=EC=9E=88=EB=8D=98=20?= =?UTF-8?q?member=20=EB=AC=B8=EC=84=9C=EB=A5=BC=20=ED=95=98=EB=82=98?= =?UTF-8?q?=EB=A1=9C=20=ED=95=A9=EC=B9=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/member.adoc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/docs/asciidoc/member.adoc b/src/docs/asciidoc/member.adoc index 580247dd..674bf80f 100644 --- a/src/docs/asciidoc/member.adoc +++ b/src/docs/asciidoc/member.adoc @@ -7,12 +7,25 @@ == Member +=== 로그인 + +==== 요청 (POST api/auth/login) + +include::{snippets}/member-auth-controller-web-mvc-test/do_signup/http-request.adoc[] +include::{snippets}/member-auth-controller-web-mvc-test/do_signup/request-fields.adoc[] + + +==== 응답 +include::{snippets}/member-auth-controller-web-mvc-test/do_signup/http-response.adoc[] +include::{snippets}/member-auth-controller-web-mvc-test/do_signup/request-fields.adoc[] + + === 닉네임 중복 확인 (GET /api/members/nickname/existence) ==== 요청 -include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/request-headers.adoc[] -include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/request-fields.adoc[] include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/http-request.adoc[] +include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/request-headers.adoc[] +include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/path-parameters.adoc[] ==== 응답 include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/http-response.adoc[] From 0af78a77eefa1bd85a54e51e2ba6672a9bb7fd0f Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:52:03 +0900 Subject: [PATCH 28/66] =?UTF-8?q?docs:=20auth=20=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/auth.adoc | 25 ------------------------- src/docs/asciidoc/index.adoc | 2 +- 2 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 src/docs/asciidoc/auth.adoc diff --git a/src/docs/asciidoc/auth.adoc b/src/docs/asciidoc/auth.adoc deleted file mode 100644 index 6835b9ac..00000000 --- a/src/docs/asciidoc/auth.adoc +++ /dev/null @@ -1,25 +0,0 @@ -:toc: left -:source-highlighter: highlightjs -:sectlinks: -:toclevels: 2 -:sectlinks: -:sectnums: - -== Auth - -=== 로그인 - -==== 요청 (POST api/auth/login) - -include::{snippets}/auth-controller-web-mvc-test/do_signup/http-request.adoc[] -include::{snippets}/auth-controller-web-mvc-test/do_signup/request-fields.adoc[] - - -==== 응답 -include::{snippets}/auth-controller-web-mvc-test/do_signup/http-response.adoc[] -include::{snippets}/auth-controller-web-mvc-test/do_signup/request-fields.adoc[] - - - - - diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index c3293ce6..c51d39db 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -5,8 +5,8 @@ :sectlinks: == atwoz Server API -* link:auth.adoc[회원 API] * link:member.adoc[회원 정보 API] +* link:admin.adoc[관리자 정보 API] * link:mission.adoc[미션 API] * link:membermissions.adoc[회원 미션 API] * link:survey.adoc[연애고사 API] From a74eabbf5883573be537cedde0a8b6f49e3546e8 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:52:30 +0900 Subject: [PATCH 29/66] =?UTF-8?q?docs:=20admin=20api=20=EB=AC=B8=EC=84=9C?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/admin.adoc | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/docs/asciidoc/admin.adoc diff --git a/src/docs/asciidoc/admin.adoc b/src/docs/asciidoc/admin.adoc new file mode 100644 index 00000000..5d2be966 --- /dev/null +++ b/src/docs/asciidoc/admin.adoc @@ -0,0 +1,42 @@ +:toc: left +:source-highlighter: highlightjs +:sectlinks: +:toclevels: 2 +:sectlinks: +:sectnums: + +== Admin + +=== 회원 가입(POST /api/admins/auth/sign-up) + +==== 요청 +include::{snippets}/admin-auth-controller-test/관리자_회원가입/http-request.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_회원가입/request-fields.adoc[] + +==== 응답 +include::{snippets}/admin-auth-controller-test/관리자_회원가입/http-response.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_회원가입/response-headers.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_회원가입/response-fields.adoc[] + + +=== 로그인(POST /api/admins/auth/login) + +==== 요청 +include::{snippets}/admin-auth-controller-test/관리자_로그인/http-request.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_로그인/request-fields.adoc[] + +==== 응답 +include::{snippets}/admin-auth-controller-test/관리자_로그인/http-response.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_로그인/response-headers.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_로그인/response-fields.adoc[] + + +=== 엑세스 토큰 재발행(POST /api/admins/auth/api/admins/auth/access-token-regeneration) + +==== 요청 +include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/http-request.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/request-headers.adoc[] + +==== 응답 +include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/http-response.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/response-fields.adoc[] From ea9ee8cddc20c87087f1eac45410729a1dc8f50b Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:54:15 +0900 Subject: [PATCH 30/66] =?UTF-8?q?docs:=20=ED=86=A0=ED=81=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=BF=A0=ED=82=A4=20=EB=A7=8C=EB=A3=8C=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 7 ++++++- src/test/resources/application.yml | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c80ea683..79196d9b 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,9 +21,14 @@ jasypt: bean: jasyptEncryptor password: ${ENCRYPT_KEY} +cookie: + max-age: ENC(71TbGrGwW0GBoO63e+8OOw==) + + jwt: secret: ENC(Tnm4CPIFdSiqmH67nWcDfRgaKmpSr4EvRJYZAYLiwOXazIY9aZnLBMlxQnKC2C0j10l6zkOEbRMKIa2W4u7DtIRjCC7QEzCSCdtm1NCEntKRybirDvUH8g==) - expiration-period: ENC(wtkJPr944E3bs6eMwjj4lQ==) + access-token-expiration-period: ENC(DXtx/CcsaXQDR8usvews6w====) + refresh-token-expiration-period: ENC(Z1emThIkYnnDGGpAkbp+kA==) mail: host: ENC(2PviuayFL6dKe91WydIBx81bpSBoI3FU) diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index d56ed96f..20c85494 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -24,9 +24,13 @@ jasypt: encryptor: password: password +cookie: + max-age: 10000 + jwt: secret: fortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortest - expiration-period: 10000 + access-token-expiration-period: 10000 + refresh-token-expiration-period: 10000 mail: host: smtp.blabla.com From a52a28ea085c754f6b3b1ed3161d9686a8b2b496 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:16:46 +0900 Subject: [PATCH 31/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EC=A0=80=EC=9E=A5=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20Admin=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/atwoz/admin/domain/admin/Admin.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/domain/admin/Admin.java diff --git a/src/main/java/com/atwoz/admin/domain/admin/Admin.java b/src/main/java/com/atwoz/admin/domain/admin/Admin.java new file mode 100644 index 00000000..8be1adac --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/Admin.java @@ -0,0 +1,87 @@ +package com.atwoz.admin.domain.admin; + +import com.atwoz.admin.domain.admin.vo.AdminStatus; +import com.atwoz.admin.domain.admin.vo.Authority; +import com.atwoz.admin.domain.admin.vo.Department; +import com.atwoz.admin.exception.exceptions.InvalidPasswordException; +import com.atwoz.admin.exception.exceptions.PasswordMismatchException; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@EqualsAndHashCode(of = "id", callSuper = false) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class Admin { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(unique = true, nullable = false) + private String email; + + @Column(nullable = false) + private String password; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String phoneNumber; + + @Enumerated(value = EnumType.STRING) + @Column(nullable = false) + private Authority authority; + + @Enumerated(value = EnumType.STRING) + @Column(nullable = false) + private Department department; + + @Enumerated(value = EnumType.STRING) + @Column(nullable = false) + private AdminStatus adminStatus; + + public static Admin createWith(final String email, + final String password, + final String confirmPassword, + final String name, + final String phoneNumber) { + validatePasswordsMatch(password, confirmPassword); + return Admin.builder() + .email(email) + .password(password) + .name(name) + .phoneNumber(phoneNumber) + .authority(Authority.ADMIN) + .department(Department.OPERATION) + .adminStatus(AdminStatus.PENDING) + .build(); + } + + private static void validatePasswordsMatch(final String password, + final String confirmPassword) { + if (!password.equals(confirmPassword)) { + throw new PasswordMismatchException(); + } + } + + public void validatePassword(final String password) { + if (!password.equals(this.password)) { + throw new InvalidPasswordException(); + } + } +} From 49f6a0a3f100d39e3b6e9fb9d13567a4342b3051 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:18:49 +0900 Subject: [PATCH 32/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=EC=9D=91=EB=8B=B5=20dto=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 - AdminAccessTokenResponse - AdminTokenResponse --- .../application/auth/dto/AdminAccessTokenResponse.java | 6 ++++++ .../admin/application/auth/dto/AdminTokenResponse.java | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminAccessTokenResponse.java create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminTokenResponse.java diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminAccessTokenResponse.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminAccessTokenResponse.java new file mode 100644 index 00000000..c0c7bbea --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminAccessTokenResponse.java @@ -0,0 +1,6 @@ +package com.atwoz.admin.application.auth.dto; + +public record AdminAccessTokenResponse( + String accessToken +) { +} diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminTokenResponse.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminTokenResponse.java new file mode 100644 index 00000000..0b2a69cb --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminTokenResponse.java @@ -0,0 +1,7 @@ +package com.atwoz.admin.application.auth.dto; + +public record AdminTokenResponse( + String accessToken, + String refreshToken +) { +} From dae8193c134569915475e9d6c8869f1153b4a8f1 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:23:43 +0900 Subject: [PATCH 33/66] =?UTF-8?q?feat:=20=ED=8A=B9=EC=A0=95=20uri=EB=A5=BC?= =?UTF-8?q?=20=EA=B4=80=EB=A6=AC=EC=9E=90=EC=97=90=EA=B2=8C=EB=A7=8C=20?= =?UTF-8?q?=ED=97=88=EC=9A=A9=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminAuthArgumentResolver - AdminAuthConfig - AdminAuthenticationContext - AdminAuthenticationContext - AdminLoginValidCheckerInterceptor - AdminRefreshTokenExtractionArgumentResolver --- .../atwoz/admin/config/AdminAuthConfig.java | 40 ++++++++++++ .../AdminLoginValidCheckerInterceptor.java | 42 +++++++++++++ .../support/AdminAuthenticationContext.java | 25 ++++++++ .../support/AdminAuthenticationExtractor.java | 36 +++++++++++ .../resolver/AdminAuthArgumentResolver.java | 32 ++++++++++ ...efreshTokenExtractionArgumentResolver.java | 61 +++++++++++++++++++ 6 files changed, 236 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/config/AdminAuthConfig.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptor.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContext.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractor.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminAuthArgumentResolver.java create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminRefreshTokenExtractionArgumentResolver.java diff --git a/src/main/java/com/atwoz/admin/config/AdminAuthConfig.java b/src/main/java/com/atwoz/admin/config/AdminAuthConfig.java new file mode 100644 index 00000000..97388421 --- /dev/null +++ b/src/main/java/com/atwoz/admin/config/AdminAuthConfig.java @@ -0,0 +1,40 @@ +package com.atwoz.admin.config; + +import com.atwoz.admin.ui.auth.interceptor.AdminLoginValidCheckerInterceptor; +import com.atwoz.admin.ui.auth.support.resolver.AdminAuthArgumentResolver; +import com.atwoz.admin.ui.auth.support.resolver.AdminRefreshTokenExtractionArgumentResolver; +import com.atwoz.global.config.interceptor.PathMatcherInterceptor; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import static com.atwoz.global.config.interceptor.support.HttpMethod.OPTIONS; + +@RequiredArgsConstructor +@Configuration +public class AdminAuthConfig implements WebMvcConfigurer { + + private final AdminAuthArgumentResolver adminAuthArgumentResolver; + private final AdminRefreshTokenExtractionArgumentResolver adminRefreshTokenExtractionArgumentResolver; + private final AdminLoginValidCheckerInterceptor adminLoginValidCheckerInterceptor; + + @Override + public void addInterceptors(final InterceptorRegistry registry) { + registry.addInterceptor(adminLoginValidCheckerInterceptor()); + } + + private HandlerInterceptor adminLoginValidCheckerInterceptor() { + return new PathMatcherInterceptor(adminLoginValidCheckerInterceptor) + .excludePathPattern("/**", OPTIONS); + } + + @Override + public void addArgumentResolvers(final List resolvers) { + resolvers.add(adminAuthArgumentResolver); + resolvers.add(adminRefreshTokenExtractionArgumentResolver); + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptor.java b/src/main/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptor.java new file mode 100644 index 00000000..d8785050 --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptor.java @@ -0,0 +1,42 @@ +package com.atwoz.admin.ui.auth.interceptor; + +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import com.atwoz.admin.exception.exceptions.UnauthorizedAccessToAdminException; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationContext; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationExtractor; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +@RequiredArgsConstructor +@Component +public class AdminLoginValidCheckerInterceptor implements HandlerInterceptor { + + private static final String ADMIN_ID = "id"; + private static final String ROLE = "role"; + private static final String ADMIN = "admin"; + + private final AdminAuthenticationContext adminAuthenticationContext; + private final AdminAuthenticationExtractor adminAuthenticationExtractor; + private final AdminTokenProvider adminTokenProvider; + + @Override + public boolean preHandle(final HttpServletRequest request, + final HttpServletResponse response, + final Object handler) throws Exception { + String token = adminAuthenticationExtractor.extractFromRequest(request) + .orElseThrow(AdminLoginInvalidException::new); + String extractedRole = adminTokenProvider.extract(token, ROLE, String.class); + if (!extractedRole.equals(ADMIN)) { + throw new UnauthorizedAccessToAdminException(); + } + + Long extractedId = adminTokenProvider.extract(token, ADMIN_ID, Long.class); + adminAuthenticationContext.setAuthentication(extractedId); + + return true; + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContext.java b/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContext.java new file mode 100644 index 00000000..efd4f4b5 --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContext.java @@ -0,0 +1,25 @@ +package com.atwoz.admin.ui.auth.support; + +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import java.util.Objects; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +@RequestScope +@Component +public class AdminAuthenticationContext { + + private Long memberId; + + public void setAuthentication(final Long memberId) { + this.memberId = memberId; + } + + public Long getPrincipal() { + if (Objects.isNull(this.memberId)) { + throw new AdminLoginInvalidException(); + } + + return memberId; + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractor.java b/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractor.java new file mode 100644 index 00000000..3a7d77ac --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractor.java @@ -0,0 +1,36 @@ +package com.atwoz.admin.ui.auth.support; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Optional; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +@Component +public class AdminAuthenticationExtractor { + + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String BEARER = "Bearer"; + private static final String HEADER_SPLIT_DELIMITER = " "; + private static final int TOKEN_TYPE_INDEX = 0; + private static final int TOKEN_VALUE_INDEX = 1; + private static final int VALID_HEADER_SPLIT_LENGTH = 2; + + public Optional extractFromRequest(final HttpServletRequest request) { + String header = request.getHeader(AUTHORIZATION_HEADER); + + if (!StringUtils.hasText(header)) { + return Optional.empty(); + } + + return extractFromHeader(header.split(HEADER_SPLIT_DELIMITER)); + } + + private Optional extractFromHeader(final String[] headerParts) { + if (headerParts.length == VALID_HEADER_SPLIT_LENGTH && + headerParts[TOKEN_TYPE_INDEX].equals(BEARER)) { + return Optional.ofNullable(headerParts[TOKEN_VALUE_INDEX]); + } + + return Optional.empty(); + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminAuthArgumentResolver.java b/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminAuthArgumentResolver.java new file mode 100644 index 00000000..4d2a53bc --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminAuthArgumentResolver.java @@ -0,0 +1,32 @@ +package com.atwoz.admin.ui.auth.support.resolver; + +import com.atwoz.admin.ui.auth.support.AdminAuthenticationContext; +import com.atwoz.admin.ui.auth.support.AuthAdmin; +import lombok.RequiredArgsConstructor; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@RequiredArgsConstructor +@Component +public class AdminAuthArgumentResolver implements HandlerMethodArgumentResolver { + + private final AdminAuthenticationContext adminAuthenticationContext; + + @Override + public boolean supportsParameter(final MethodParameter parameter) { + return parameter.hasParameterAnnotation(AuthAdmin.class) && + parameter.getParameterType().equals(Long.class); + } + + @Override + public Object resolveArgument(final MethodParameter parameter, + final ModelAndViewContainer mavContainer, + final NativeWebRequest webRequest, + final WebDataBinderFactory binderFactory) throws Exception { + return adminAuthenticationContext.getPrincipal(); + } +} diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminRefreshTokenExtractionArgumentResolver.java b/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminRefreshTokenExtractionArgumentResolver.java new file mode 100644 index 00000000..e137c71e --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/resolver/AdminRefreshTokenExtractionArgumentResolver.java @@ -0,0 +1,61 @@ +package com.atwoz.admin.ui.auth.support.resolver; + +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import com.atwoz.admin.exception.exceptions.UnauthorizedAccessToAdminException; +import com.atwoz.admin.ui.auth.support.AdminRefreshToken; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@RequiredArgsConstructor +@Component +public class AdminRefreshTokenExtractionArgumentResolver implements HandlerMethodArgumentResolver { + + private static final String REFRESH_TOKEN = "refreshToken"; + private static final String ROLE = "role"; + private static final String ADMIN = "admin"; + + private final AdminTokenProvider adminTokenProvider; + + @Override + public boolean supportsParameter(final MethodParameter parameter) { + return parameter.hasParameterAnnotation(AdminRefreshToken.class) && + parameter.getParameterType().equals(String.class); + } + + @Override + public Object resolveArgument(final MethodParameter parameter, + final ModelAndViewContainer mavContainer, + final NativeWebRequest webRequest, + final WebDataBinderFactory binderFactory) throws Exception { + HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); + if (request == null) { + throw new AdminLoginInvalidException(); + } + + String refreshToken = findRefreshToken(request.getCookies()); + String role = adminTokenProvider.extract(refreshToken, ROLE, String.class); + if (!Objects.equals(role, ADMIN)) { + throw new UnauthorizedAccessToAdminException(); + } + + return refreshToken; + } + + private String findRefreshToken(final Cookie[] cookies) { + return Arrays.stream(cookies) + .filter(cookie -> REFRESH_TOKEN.equals(cookie.getName())) + .findAny() + .orElseThrow(AdminLoginInvalidException::new) + .getValue(); + } +} From 9a28b47af7f81613d8a7702f5ec7b2d122774329 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:26:14 +0900 Subject: [PATCH 34/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=EC=8B=9C=20=EB=B0=9C=EC=83=9D=ED=95=A0=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8A=94=20=EC=98=88=EC=99=B8=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminExceptionHandler - AdminLoginInvalidException - AdminNotFoundException - InvalidPasswordException - PasswordMismatchException - UnauthorizedAccessToAdminException --- .../exception/AdminExceptionHandler.java | 61 +++++++++++++++++++ .../AdminLoginInvalidException.java | 8 +++ .../exceptions/AdminNotFoundException.java | 8 +++ .../exceptions/InvalidPasswordException.java | 8 +++ .../exceptions/PasswordMismatchException.java | 8 +++ .../UnauthorizedAccessToAdminException.java | 8 +++ 6 files changed, 101 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/exception/AdminExceptionHandler.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/AdminLoginInvalidException.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/AdminNotFoundException.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/InvalidPasswordException.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/PasswordMismatchException.java create mode 100644 src/main/java/com/atwoz/admin/exception/exceptions/UnauthorizedAccessToAdminException.java diff --git a/src/main/java/com/atwoz/admin/exception/AdminExceptionHandler.java b/src/main/java/com/atwoz/admin/exception/AdminExceptionHandler.java new file mode 100644 index 00000000..29f8bd93 --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/AdminExceptionHandler.java @@ -0,0 +1,61 @@ +package com.atwoz.admin.exception; + +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import com.atwoz.admin.exception.exceptions.AdminNotFoundException; +import com.atwoz.admin.exception.exceptions.InvalidPasswordException; +import com.atwoz.admin.exception.exceptions.PasswordMismatchException; +import com.atwoz.admin.exception.exceptions.UnauthorizedAccessToAdminException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class AdminExceptionHandler { + + @ExceptionHandler(PasswordMismatchException.class) + public ResponseEntity handlePasswordMismatchException(final PasswordMismatchException e) { + return getBadRequest(e); + } + + @ExceptionHandler(AdminNotFoundException.class) + public ResponseEntity handleAdminNotFoundException(final AdminNotFoundException e) { + return getNotFoundResponse(e); + } + + @ExceptionHandler(InvalidPasswordException.class) + public ResponseEntity handlePasswordInvalidException(final InvalidPasswordException e) { + return getBadRequest(e); + } + + @ExceptionHandler(UnauthorizedAccessToAdminException.class) + public ResponseEntity handleUnauthorizedAccessToAdminException(final UnauthorizedAccessToAdminException e) { + return getUnauthorized(e); + } + + @ExceptionHandler(AdminLoginInvalidException.class) + public ResponseEntity handleAdminLoginInvalidException(final AdminLoginInvalidException e) { + return getUnauthorized(e); + } + + private ResponseEntity getNotFoundResponse(final Exception e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(e.getMessage()); + } + + private ResponseEntity getUnauthorized(final Exception e) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(e.getMessage()); + } + + private ResponseEntity getConflicted(final Exception e) { + return ResponseEntity.status(HttpStatus.CONFLICT) + .body(e.getMessage()); + } + + private ResponseEntity getBadRequest(final Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(e.getMessage()); + } +} + diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/AdminLoginInvalidException.java b/src/main/java/com/atwoz/admin/exception/exceptions/AdminLoginInvalidException.java new file mode 100644 index 00000000..031ab33f --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/AdminLoginInvalidException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class AdminLoginInvalidException extends RuntimeException { + + public AdminLoginInvalidException() { + super("관리자 로그인이 유효하지 않습니다"); + } +} diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/AdminNotFoundException.java b/src/main/java/com/atwoz/admin/exception/exceptions/AdminNotFoundException.java new file mode 100644 index 00000000..c0a27b90 --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/AdminNotFoundException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class AdminNotFoundException extends RuntimeException { + + public AdminNotFoundException() { + super("관리자를 찾을 수 없습니다."); + } +} diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/InvalidPasswordException.java b/src/main/java/com/atwoz/admin/exception/exceptions/InvalidPasswordException.java new file mode 100644 index 00000000..c9549806 --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/InvalidPasswordException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class InvalidPasswordException extends RuntimeException { + + public InvalidPasswordException() { + super("잘못된 이메일/비밀번호 입력입니다. 다시 입력해주세요"); + } +} diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/PasswordMismatchException.java b/src/main/java/com/atwoz/admin/exception/exceptions/PasswordMismatchException.java new file mode 100644 index 00000000..fa51bc6f --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/PasswordMismatchException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class PasswordMismatchException extends RuntimeException { + + public PasswordMismatchException() { + super("비밀번호가 일치하지 않습니다."); + } +} diff --git a/src/main/java/com/atwoz/admin/exception/exceptions/UnauthorizedAccessToAdminException.java b/src/main/java/com/atwoz/admin/exception/exceptions/UnauthorizedAccessToAdminException.java new file mode 100644 index 00000000..fe196384 --- /dev/null +++ b/src/main/java/com/atwoz/admin/exception/exceptions/UnauthorizedAccessToAdminException.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.exception.exceptions; + +public class UnauthorizedAccessToAdminException extends RuntimeException { + + public UnauthorizedAccessToAdminException() { + super("권한이 없습니다."); + } +} From 33ea1cd8b6513ce521fb37ab86aabd618970408a Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:27:56 +0900 Subject: [PATCH 35/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20rep?= =?UTF-8?q?ository=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminRepository - AdminJpaRepository - AdminRepositoryImpl --- .../admin/domain/admin/AdminRepository.java | 12 ++++++++ .../admin/AdminJpaRepository.java | 10 +++++++ .../admin/AdminRepositoryImpl.java | 29 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/domain/admin/AdminRepository.java create mode 100644 src/main/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepository.java create mode 100644 src/main/java/com/atwoz/admin/infrastructure/admin/AdminRepositoryImpl.java diff --git a/src/main/java/com/atwoz/admin/domain/admin/AdminRepository.java b/src/main/java/com/atwoz/admin/domain/admin/AdminRepository.java new file mode 100644 index 00000000..8cc4830d --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/AdminRepository.java @@ -0,0 +1,12 @@ +package com.atwoz.admin.domain.admin; + +import java.util.Optional; + +public interface AdminRepository { + + Admin save(Admin admin); + + Optional findAdminById(Long id); + + Optional findAdminByEmail(String email); +} diff --git a/src/main/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepository.java b/src/main/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepository.java new file mode 100644 index 00000000..d305fcac --- /dev/null +++ b/src/main/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepository.java @@ -0,0 +1,10 @@ +package com.atwoz.admin.infrastructure.admin; + +import com.atwoz.admin.domain.admin.Admin; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AdminJpaRepository extends JpaRepository { + + Optional findAdminByEmail(String email); +} diff --git a/src/main/java/com/atwoz/admin/infrastructure/admin/AdminRepositoryImpl.java b/src/main/java/com/atwoz/admin/infrastructure/admin/AdminRepositoryImpl.java new file mode 100644 index 00000000..62b717b1 --- /dev/null +++ b/src/main/java/com/atwoz/admin/infrastructure/admin/AdminRepositoryImpl.java @@ -0,0 +1,29 @@ +package com.atwoz.admin.infrastructure.admin; + +import com.atwoz.admin.domain.admin.Admin; +import com.atwoz.admin.domain.admin.AdminRepository; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@RequiredArgsConstructor +@Repository +public class AdminRepositoryImpl implements AdminRepository { + + private final AdminJpaRepository adminJpaRepository; + + @Override + public Admin save(final Admin admin) { + return adminJpaRepository.save(admin); + } + + @Override + public Optional findAdminById(final Long id) { + return adminJpaRepository.findById(id); + } + + @Override + public Optional findAdminByEmail(final String email) { + return adminJpaRepository.findAdminByEmail(email); + } +} From b96c1201095ad4c7a4c0c8fa448ce09e4e54470f Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:30:30 +0900 Subject: [PATCH 36/66] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=EC=9D=84=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=ED=95=98=EA=B3=A0=20=ED=86=A0=ED=81=B0?= =?UTF-8?q?=EC=9D=98=20claim=EC=9D=84=20=EC=B0=BE=EC=95=84=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminTokenProvider - AdminJwtTokenProvider --- .../domain/admin/AdminTokenProvider.java | 10 ++ .../auth/AdminJwtTokenProvider.java | 117 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/domain/admin/AdminTokenProvider.java create mode 100644 src/main/java/com/atwoz/admin/infrastructure/auth/AdminJwtTokenProvider.java diff --git a/src/main/java/com/atwoz/admin/domain/admin/AdminTokenProvider.java b/src/main/java/com/atwoz/admin/domain/admin/AdminTokenProvider.java new file mode 100644 index 00000000..427d63b5 --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/AdminTokenProvider.java @@ -0,0 +1,10 @@ +package com.atwoz.admin.domain.admin; + +public interface AdminTokenProvider { + + String createAccessToken(Long id); + + String createRefreshToken(Long id); + + T extract(String token, String claimName, Class classType); +} diff --git a/src/main/java/com/atwoz/admin/infrastructure/auth/AdminJwtTokenProvider.java b/src/main/java/com/atwoz/admin/infrastructure/auth/AdminJwtTokenProvider.java new file mode 100644 index 00000000..0ee81c0c --- /dev/null +++ b/src/main/java/com/atwoz/admin/infrastructure/auth/AdminJwtTokenProvider.java @@ -0,0 +1,117 @@ +package com.atwoz.admin.infrastructure.auth; + +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.member.exception.exceptions.auth.ExpiredTokenException; +import com.atwoz.member.exception.exceptions.auth.SignatureInvalidException; +import com.atwoz.member.exception.exceptions.auth.TokenFormInvalidException; +import com.atwoz.member.exception.exceptions.auth.TokenInvalidException; +import com.atwoz.member.exception.exceptions.auth.UnsupportedTokenException; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.UnsupportedJwtException; +import io.jsonwebtoken.security.Keys; +import jakarta.annotation.PostConstruct; +import java.security.Key; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import lombok.NoArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@NoArgsConstructor +@Component +public class AdminJwtTokenProvider implements AdminTokenProvider { + + private static final String ID = "id"; + private static final String TOKEN_TYPE = "token type"; + private static final String REFRESH_TOKEN = "refresh token"; + private static final String ACCESS_TOKEN = "access token"; + private static final String ROLE = "role"; + private static final String ADMIN = "admin"; + + @Value("${jwt.secret}") + private String secret; + + @Value("${jwt.access-token-expiration-period}") + private int accessTokenExpirationPeriod; + + @Value("${jwt.refresh-token-expiration-period}") + private int refreshTokenExpirationPeriod; + + private Key key; + + @PostConstruct + private void init() { + key = Keys.hmacShaKeyFor(secret.getBytes()); + } + + @Override + public String createAccessToken(final Long id) { + Claims claims = Jwts.claims(); + claims.put(ID, id); + claims.put(TOKEN_TYPE, ACCESS_TOKEN); + claims.put(ROLE, ADMIN); + + return createToken(claims, accessTokenExpirationPeriod); + } + + @Override + public String createRefreshToken(final Long id) { + Claims claims = Jwts.claims(); + claims.put(ID, id); + claims.put(TOKEN_TYPE, REFRESH_TOKEN); + claims.put(ROLE, ADMIN); + + return createToken(claims, refreshTokenExpirationPeriod); + } + + private String createToken(final Claims claims, final int expirationPeriod) { + return Jwts.builder() + .setClaims(claims) + .setIssuedAt(issuedAt()) + .setExpiration(expiredAt(expirationPeriod)) + .signWith(key, SignatureAlgorithm.HS256) + .compact(); + } + + private Date issuedAt() { + LocalDateTime now = LocalDateTime.now(); + + return Date.from(now.atZone(ZoneId.systemDefault()) + .toInstant()); + } + + private Date expiredAt(final int expirationPeriod) { + LocalDateTime now = LocalDateTime.now(); + + return Date.from(now.plusDays(expirationPeriod) + .atZone(ZoneId.systemDefault()) + .toInstant()); + } + + @Override + public T extract(final String token, final String claimName, final Class classType) { + try { + return Jwts.parserBuilder() + .setSigningKey(secret.getBytes()) + .build() + .parseClaimsJws(token) + .getBody() + .get(claimName, classType); + } catch (SecurityException e) { + throw new SignatureInvalidException(); + } catch (MalformedJwtException e) { + throw new TokenFormInvalidException(); + } catch (ExpiredJwtException e) { + throw new ExpiredTokenException(); + } catch (UnsupportedJwtException e) { + throw new UnsupportedTokenException(); + } catch (IllegalArgumentException e) { + throw new TokenInvalidException(); + } + } +} From 56c22ee5f859d734bf0b43fa411dc7ac349069e3 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:31:07 +0900 Subject: [PATCH 37/66] =?UTF-8?q?feat:=20Admin=20Auth=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminAuthService --- .../application/auth/AdminAuthService.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/application/auth/AdminAuthService.java diff --git a/src/main/java/com/atwoz/admin/application/auth/AdminAuthService.java b/src/main/java/com/atwoz/admin/application/auth/AdminAuthService.java new file mode 100644 index 00000000..cc9ba182 --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/AdminAuthService.java @@ -0,0 +1,69 @@ +package com.atwoz.admin.application.auth; + +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminProfileSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; +import com.atwoz.admin.domain.admin.Admin; +import com.atwoz.admin.domain.admin.AdminRepository; +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +@Transactional +public class AdminAuthService { + + private static final String ID = "id"; + + private final AdminRepository adminRepository; + private final AdminTokenProvider adminTokenProvider; + + public AdminTokenResponse signUp(final AdminSignUpRequest adminSignUpRequest) { + AdminProfileSignUpRequest adminProfileSignUpRequest = adminSignUpRequest.adminProfileSignUpRequest(); + Admin admin = Admin.createWith( + adminSignUpRequest.email(), + adminSignUpRequest.password(), + adminSignUpRequest.confirmPassword(), + adminProfileSignUpRequest.name(), + adminProfileSignUpRequest.phoneNumber() + ); + Admin savedAdmin = adminRepository.save(admin); + + return createAdminTokenResponse(savedAdmin.getId()); + } + + private AdminTokenResponse createAdminTokenResponse(final Long id) { + return new AdminTokenResponse( + adminTokenProvider.createAccessToken(id), + adminTokenProvider.createRefreshToken(id) + ); + } + + public AdminTokenResponse login(final AdminLoginRequest adminLoginRequest) { + Admin foundAdmin = findAdminByEmail(adminLoginRequest.email()); + foundAdmin.validatePassword(adminLoginRequest.password()); + + return createAdminTokenResponse(foundAdmin.getId()); + } + + public AdminAccessTokenResponse reGenerateAccessToken(final String refreshToken) { + Admin foundAdmin = findAdminById(adminTokenProvider.extract(refreshToken, ID, Long.class)); + + return new AdminAccessTokenResponse(adminTokenProvider.createAccessToken(foundAdmin.getId())); + } + + private Admin findAdminByEmail(final String email) { + return adminRepository.findAdminByEmail(email) + .orElseThrow(AdminNotFoundException::new); + } + + private Admin findAdminById(final Long id) { + return adminRepository.findAdminById(id) + .orElseThrow(AdminNotFoundException::new); + } +} From d33bfc5092fe384f41005985efafaf911c22a70e Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:31:35 +0900 Subject: [PATCH 38/66] =?UTF-8?q?feat:=20Admin=20Auth=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminAuthController --- .../admin/ui/auth/AdminAuthController.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java diff --git a/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java b/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java new file mode 100644 index 00000000..034763e5 --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java @@ -0,0 +1,73 @@ +package com.atwoz.admin.ui.auth; + +import com.atwoz.admin.application.auth.AdminAuthService; +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; +import com.atwoz.admin.ui.auth.support.AdminRefreshToken; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseCookie; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/api/admins/auth") +public class AdminAuthController { + + private static final String COOKIE_NAME = "refreshToken"; + private static final String ANY_WAY = "/"; + + @Value("${cookie.max-age}") + private int maxAge; + + private final AdminAuthService adminAuthService; + + @PostMapping("/sign-up") + public ResponseEntity singUp( + @RequestBody @Valid final AdminSignUpRequest adminSignUpRequest) { + AdminTokenResponse adminTokenResponse = adminAuthService.signUp(adminSignUpRequest); + + return ResponseEntity.ok() + .headers(createCookieHeaders(adminTokenResponse.refreshToken())) + .body(new AdminAccessTokenResponse(adminTokenResponse.accessToken())); + } + + @PostMapping("/login") + public ResponseEntity login( + @RequestBody @Valid final AdminLoginRequest adminLoginRequest) { + AdminTokenResponse adminTokenResponse = adminAuthService.login(adminLoginRequest); + + return ResponseEntity.ok() + .headers(createCookieHeaders(adminTokenResponse.refreshToken())) + .body(new AdminAccessTokenResponse(adminTokenResponse.accessToken())); + } + + @PostMapping("/access-token-regeneration") + public ResponseEntity reGenerateAccessToken( + @AdminRefreshToken final String refreshToken) { + System.out.println("hihi : " + refreshToken); + return ResponseEntity.ok(adminAuthService.reGenerateAccessToken(refreshToken)); + } + + + private HttpHeaders createCookieHeaders(final String refreshToken) { + ResponseCookie cookie = ResponseCookie.from(COOKIE_NAME, refreshToken) + .httpOnly(true) + .secure(true) + .path(ANY_WAY) + .maxAge(maxAge) + .build(); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add(HttpHeaders.COOKIE, cookie.toString()); + + return httpHeaders; + } +} From 4aae7e6feee9cad7efabaa7f231b03e432c38eb2 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:32:48 +0900 Subject: [PATCH 39/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=EC=9A=94=EC=B2=AD=20dto=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 - AdminSignUpRequest - AdminProfileSignUpRequest - AdminLoginRequest --- .../auth/dto/AdminLoginRequest.java | 12 +++++++++++ .../auth/dto/AdminProfileSignUpRequest.java | 7 +++++++ .../auth/dto/AdminSignUpRequest.java | 21 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminLoginRequest.java create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java create mode 100644 src/main/java/com/atwoz/admin/application/auth/dto/AdminSignUpRequest.java diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminLoginRequest.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminLoginRequest.java new file mode 100644 index 00000000..1ec13c2e --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminLoginRequest.java @@ -0,0 +1,12 @@ +package com.atwoz.admin.application.auth.dto; + +import jakarta.validation.constraints.NotBlank; + +public record AdminLoginRequest( + @NotBlank(message = "이메일을 입력해주세요") + String email, + + @NotBlank(message = "비밀번호를 입력해주세요") + String password +) { +} diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java new file mode 100644 index 00000000..112af4ab --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java @@ -0,0 +1,7 @@ +package com.atwoz.admin.application.auth.dto; + +public record AdminProfileSignUpRequest( + String name, + String phoneNumber +) { +} diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminSignUpRequest.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminSignUpRequest.java new file mode 100644 index 00000000..ba1336fc --- /dev/null +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminSignUpRequest.java @@ -0,0 +1,21 @@ +package com.atwoz.admin.application.auth.dto; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +public record AdminSignUpRequest( + @NotBlank(message = "이메일을 입력해주세요") + String email, + + @NotBlank(message = "비밀번호를 입력해주세요") + String password, + + @NotBlank(message = "비밀번호 확인을 위해 다시한번 입력해주세요") + String confirmPassword, + + @Valid + @NotNull(message = "관리자 프로필 정보를 입력해주세요") + AdminProfileSignUpRequest adminProfileSignUpRequest +) { +} From c491d5866b4d0238645b99e9ced0ce7656d52d9b Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:34:18 +0900 Subject: [PATCH 40/66] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EC=97=AD=ED=95=A0=EA=B3=BC=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=EB=A5=BC=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20enum=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Department: 관리자의 부서 - AdminStatus: 관리자 계정 사용 가능 여부 - Authority: 관리자의 권한 --- .../java/com/atwoz/admin/domain/admin/vo/AdminStatus.java | 8 ++++++++ .../java/com/atwoz/admin/domain/admin/vo/Authority.java | 6 ++++++ .../java/com/atwoz/admin/domain/admin/vo/Department.java | 5 +++++ 3 files changed, 19 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/domain/admin/vo/AdminStatus.java create mode 100644 src/main/java/com/atwoz/admin/domain/admin/vo/Authority.java create mode 100644 src/main/java/com/atwoz/admin/domain/admin/vo/Department.java diff --git a/src/main/java/com/atwoz/admin/domain/admin/vo/AdminStatus.java b/src/main/java/com/atwoz/admin/domain/admin/vo/AdminStatus.java new file mode 100644 index 00000000..af420f09 --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/vo/AdminStatus.java @@ -0,0 +1,8 @@ +package com.atwoz.admin.domain.admin.vo; + +public enum AdminStatus { + + AVAILABLE, + UNAVAILABLE, + PENDING +} diff --git a/src/main/java/com/atwoz/admin/domain/admin/vo/Authority.java b/src/main/java/com/atwoz/admin/domain/admin/vo/Authority.java new file mode 100644 index 00000000..db3871e5 --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/vo/Authority.java @@ -0,0 +1,6 @@ +package com.atwoz.admin.domain.admin.vo; + +public enum Authority { + MASTER, + ADMIN +} diff --git a/src/main/java/com/atwoz/admin/domain/admin/vo/Department.java b/src/main/java/com/atwoz/admin/domain/admin/vo/Department.java new file mode 100644 index 00000000..d113f1f2 --- /dev/null +++ b/src/main/java/com/atwoz/admin/domain/admin/vo/Department.java @@ -0,0 +1,5 @@ +package com.atwoz.admin.domain.admin.vo; + +public enum Department { + OPERATION +} From 4c9ebfb24be9e68951cda396e465e70942d51163 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:35:32 +0900 Subject: [PATCH 41/66] =?UTF-8?q?feat:=20AT=EA=B0=80=20=EB=A7=8C=EB=A3=8C?= =?UTF-8?q?=EB=90=98=EC=97=88=EC=9D=84=20=EB=95=8C=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=9C=A0=EC=A0=80=EC=9D=98=20RT=EB=A5=BC?= =?UTF-8?q?=20Argument=20Resolver=EB=A5=BC=20=ED=86=B5=ED=95=B4=20?= =?UTF-8?q?=EC=86=90=EC=89=BD=EA=B2=8C=20=EB=B0=9B=EC=9D=84=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EC=9C=84=ED=95=B4=20=EC=96=B4=EB=85=B8=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminRefreshToken --- .../admin/ui/auth/support/AdminRefreshToken.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/AdminRefreshToken.java diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/AdminRefreshToken.java b/src/main/java/com/atwoz/admin/ui/auth/support/AdminRefreshToken.java new file mode 100644 index 00000000..f10a0fdd --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/AdminRefreshToken.java @@ -0,0 +1,11 @@ +package com.atwoz.admin.ui.auth.support; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface AdminRefreshToken { +} From 551d5d4f192f4ecf01eb41dc5cd3612b540ac3ad Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:36:21 +0900 Subject: [PATCH 42/66] =?UTF-8?q?feat:=20=EA=B2=80=EC=A6=9D=EB=90=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=EC=9D=98=20id=20=EA=B0=92=EC=9D=84?= =?UTF-8?q?=20argument=20resolver=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=B4?= =?UTF-8?q?=20=EC=89=BD=EA=B2=8C=20=EB=84=98=EA=B2=A8=EB=B0=9B=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AuthAdmin --- .../com/atwoz/admin/ui/auth/support/AuthAdmin.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/com/atwoz/admin/ui/auth/support/AuthAdmin.java diff --git a/src/main/java/com/atwoz/admin/ui/auth/support/AuthAdmin.java b/src/main/java/com/atwoz/admin/ui/auth/support/AuthAdmin.java new file mode 100644 index 00000000..6334786c --- /dev/null +++ b/src/main/java/com/atwoz/admin/ui/auth/support/AuthAdmin.java @@ -0,0 +1,11 @@ +package com.atwoz.admin.ui.auth.support; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuthAdmin { +} From ce994a9bb8102568b2a2c1b4f25507c1a03adc02 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:37:02 +0900 Subject: [PATCH 43/66] =?UTF-8?q?remove:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=B4=EC=A7=84=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/atwoz/member/config/AuthConfig.java | 69 ------------ .../member/domain/auth/TokenProvider.java | 10 -- .../LoginValidCheckerInterceptor.java | 35 ------ .../ParseMemberIdFromTokenInterceptor.java | 30 ------ .../TokenRegenerateInterceptor.java | 50 --------- .../support/auth/AuthenticationContext.java | 31 ------ .../LoginValidCheckerInterceptorTest.java | 42 -------- .../TokenRegenerateInterceptorTest.java | 54 ---------- .../auth/AuthenticationContextTest.java | 56 ---------- .../auth/AuthenticationExtractorTest.java | 100 ------------------ 10 files changed, 477 deletions(-) delete mode 100644 src/main/java/com/atwoz/member/config/AuthConfig.java delete mode 100644 src/main/java/com/atwoz/member/domain/auth/TokenProvider.java delete mode 100644 src/main/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptor.java delete mode 100644 src/main/java/com/atwoz/member/ui/auth/interceptor/ParseMemberIdFromTokenInterceptor.java delete mode 100644 src/main/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptor.java delete mode 100644 src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContext.java delete mode 100644 src/test/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptorTest.java delete mode 100644 src/test/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptorTest.java delete mode 100644 src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContextTest.java delete mode 100644 src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractorTest.java diff --git a/src/main/java/com/atwoz/member/config/AuthConfig.java b/src/main/java/com/atwoz/member/config/AuthConfig.java deleted file mode 100644 index 43b0912e..00000000 --- a/src/main/java/com/atwoz/member/config/AuthConfig.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.atwoz.member.config; - -import com.atwoz.member.ui.auth.interceptor.LoginValidCheckerInterceptor; -import com.atwoz.member.ui.auth.interceptor.ParseMemberIdFromTokenInterceptor; -import com.atwoz.member.ui.auth.interceptor.PathMatcherInterceptor; -import com.atwoz.member.ui.auth.interceptor.TokenRegenerateInterceptor; -import com.atwoz.member.ui.auth.support.resolver.AuthArgumentResolver; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.DELETE; -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.GET; -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.OPTIONS; -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.PATCH; -import static com.atwoz.member.ui.auth.interceptor.HttpMethod.POST; - -@RequiredArgsConstructor -@Configuration -public class AuthConfig implements WebMvcConfigurer { - - private final AuthArgumentResolver authArgumentResolver; - private final ParseMemberIdFromTokenInterceptor parseMemberIdFromTokenInterceptor; - private final LoginValidCheckerInterceptor loginValidCheckerInterceptor; - private final TokenRegenerateInterceptor tokenRegenerateInterceptor; - - @Override - public void addInterceptors(final InterceptorRegistry registry) { - registry.addInterceptor(parseMemberIdFromTokenInterceptor()); - registry.addInterceptor(loginValidCheckerInterceptor()); - registry.addInterceptor(tokenRegenerateInterceptor()); - } - - private HandlerInterceptor parseMemberIdFromTokenInterceptor() { - return new PathMatcherInterceptor(parseMemberIdFromTokenInterceptor) - .excludePathPattern("/**", OPTIONS) - .addPathPatterns("/api/info/**", GET, POST, PATCH) - .addPathPatterns("/api/surveys/**", GET, POST) - .addPathPatterns("/api/members/me/missions/**", GET, POST, PATCH) - .addPathPatterns("/api/members/me/surveys/**", GET, POST); - } - - /** - * @AuthMember를 통해서 인증이 필요한 경우에 해당 메서드에 URI를 추가해주면 된다. 추가를 해야지 인증,인가 가능 - */ - private HandlerInterceptor loginValidCheckerInterceptor() { - return new PathMatcherInterceptor(loginValidCheckerInterceptor) - .excludePathPattern("/**", OPTIONS) - .excludePathPattern("/api/missions/**", GET, POST, PATCH, DELETE) - .excludePathPattern("/api/surveys/**", GET, POST) - .addPathPatterns("/api/members/**", GET, POST, PATCH, DELETE) - .addPathPatterns("/api/reports/**", POST); - } - - private HandlerInterceptor tokenRegenerateInterceptor() { - return new PathMatcherInterceptor(tokenRegenerateInterceptor) - .excludePathPattern("/**", OPTIONS) - .addPathPatterns("/api/auth/login", POST); - } - - @Override - public void addArgumentResolvers(final List resolvers) { - resolvers.add(authArgumentResolver); - } -} diff --git a/src/main/java/com/atwoz/member/domain/auth/TokenProvider.java b/src/main/java/com/atwoz/member/domain/auth/TokenProvider.java deleted file mode 100644 index e5e27192..00000000 --- a/src/main/java/com/atwoz/member/domain/auth/TokenProvider.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.atwoz.member.domain.auth; - -public interface TokenProvider { - - String createTokenWithId(Long id); - - String createTokenWithPhoneNumber(String phoneNumber); - - T extract(String token, String claimName, Class classType); -} diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptor.java b/src/main/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptor.java deleted file mode 100644 index 23681fca..00000000 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptor.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -@RequiredArgsConstructor -@Component -public class LoginValidCheckerInterceptor implements HandlerInterceptor { - - private static final String MEMBER_ID = "id"; - - private final TokenProvider tokenProvider; - private final AuthenticationContext authenticationContext; - private final AuthenticationExtractor authenticationExtractor; - - @Override - public boolean preHandle(final HttpServletRequest request, - final HttpServletResponse response, - final Object handler) throws Exception { - String token = authenticationExtractor.extractFromRequest(request) - .orElseThrow(LoginInvalidException::new); - - Long extractedMemberId = tokenProvider.extract(token, MEMBER_ID, Long.class); - authenticationContext.setAuthentication(extractedMemberId); - - return true; - } -} diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/ParseMemberIdFromTokenInterceptor.java b/src/main/java/com/atwoz/member/ui/auth/interceptor/ParseMemberIdFromTokenInterceptor.java deleted file mode 100644 index eec586cf..00000000 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/ParseMemberIdFromTokenInterceptor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -@RequiredArgsConstructor -@Component -public class ParseMemberIdFromTokenInterceptor implements HandlerInterceptor { - - private final LoginValidCheckerInterceptor loginValidCheckerInterceptor; - private final AuthenticationContext authenticationContext; - private final AuthenticationExtractor authenticationExtractor; - - @Override - public boolean preHandle(final HttpServletRequest request, - final HttpServletResponse response, - final Object handler) throws Exception { - if (authenticationExtractor.extractFromRequest(request).isEmpty()) { - authenticationContext.setAnonymous(); - return true; - } - - return loginValidCheckerInterceptor.preHandle(request, response, handler); - } -} diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptor.java b/src/main/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptor.java deleted file mode 100644 index e5d37a50..00000000 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptor.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.domain.auth.JsonMapper; -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.domain.member.Member; -import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.exception.exceptions.member.MemberNotFoundException; -import com.atwoz.member.ui.auth.dto.TokenResponse; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.lang.Nullable; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.ModelAndView; - -@RequiredArgsConstructor -@Component -public class TokenRegenerateInterceptor implements HandlerInterceptor { - - private static final String PHONE_NUMBER = "phoneNumber"; - - private final TokenProvider tokenProvider; - private final MemberRepository memberRepository; - private final JsonMapper jsonMapper; - private final AuthenticationExtractor authenticationExtractor; - - @Override - public void postHandle(final HttpServletRequest request, - final HttpServletResponse response, - final Object handler, - final @Nullable ModelAndView modelAndView) throws Exception { - String token = authenticationExtractor.extractFromResponse(response); - String extractedPhoneNumber = tokenProvider.extract(token, PHONE_NUMBER, String.class); - - if (extractedPhoneNumber != null) { - response.resetBuffer(); - Member foundMember = findMemberByPhoneNumber(extractedPhoneNumber); - String createdToken = tokenProvider.createTokenWithId(foundMember.getId()); - byte[] convertedTokenResponse = jsonMapper.convertObjectToJsonByteArray(new TokenResponse(createdToken)); - response.getOutputStream().write(convertedTokenResponse); - } - } - - private Member findMemberByPhoneNumber(final String phoneNumber) { - return memberRepository.findByPhoneNumber(phoneNumber) - .orElseThrow(MemberNotFoundException::new); - } -} diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContext.java b/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContext.java deleted file mode 100644 index 1cfb9c50..00000000 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContext.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.atwoz.member.ui.auth.support.auth; - -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import java.util.Objects; -import org.springframework.stereotype.Component; -import org.springframework.web.context.annotation.RequestScope; - -@RequestScope -@Component -public class AuthenticationContext { - - private static final Long ANONYMOUS_MEMBER = -1L; - - private Long memberId; - - public void setAuthentication(Long memberId) { - this.memberId = memberId; - } - - public Long getPrincipal() { - if (Objects.isNull(this.memberId)) { - throw new LoginInvalidException(); - } - - return memberId; - } - - public void setAnonymous() { - this.memberId = ANONYMOUS_MEMBER; - } -} diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptorTest.java b/src/test/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptorTest.java deleted file mode 100644 index 9a5c2774..00000000 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/LoginValidCheckerInterceptorTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -@SuppressWarnings("NonAsciiCharacters") -class LoginValidCheckerInterceptorTest { - - private final HttpServletRequest req = mock(HttpServletRequest.class); - private final HttpServletResponse res = mock(HttpServletResponse.class); - private final TokenProvider tokenProvider = mock(TokenProvider.class); - private final AuthenticationContext authenticationContext = mock(AuthenticationContext.class); - private final AuthenticationExtractor authenticationExtractor = mock(AuthenticationExtractor.class); - - @Test - void token이_없다면_예외를_발생한다() { - // given - LoginValidCheckerInterceptor loginValidCheckerInterceptor = new LoginValidCheckerInterceptor( - tokenProvider, - authenticationContext, - authenticationExtractor - ); - - when(req.getHeader("any")).thenReturn(null); - - // when & then - assertThatThrownBy(() -> loginValidCheckerInterceptor.preHandle(req, res, new Object())) - .isInstanceOf(LoginInvalidException.class); - } -} diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptorTest.java b/src/test/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptorTest.java deleted file mode 100644 index d0de0a61..00000000 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/TokenRegenerateInterceptorTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.atwoz.member.ui.auth.interceptor; - -import com.atwoz.member.domain.auth.JsonMapper; -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.exception.exceptions.auth.InvalidJsonKeyException; -import com.atwoz.member.infrastructure.member.MemberFakeRepository; -import com.atwoz.member.ui.auth.support.auth.AuthenticationExtractor; -import jakarta.servlet.http.HttpServletRequest; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.Test; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.util.ContentCachingResponseWrapper; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@DisplayNameGeneration(ReplaceUnderscores.class) -@SuppressWarnings("NonAsciiCharacters") -class TokenRegenerateInterceptorTest { - - private final HttpServletRequest request = mock(HttpServletRequest.class); - private final ContentCachingResponseWrapper response = mock(ContentCachingResponseWrapper.class); - private final TokenProvider tokenProvider = mock(TokenProvider.class); - private final JsonMapper jsonMapper = mock(JsonMapper.class); - private final MemberRepository memberRepository = new MemberFakeRepository(); - private final AuthenticationExtractor authenticationExtractor = mock(AuthenticationExtractor.class); - - private TokenRegenerateInterceptor tokenRegenerateInterceptor; - - @BeforeEach - void setup() { - tokenRegenerateInterceptor = new TokenRegenerateInterceptor( - tokenProvider, - memberRepository, - jsonMapper, - authenticationExtractor - ); - } - - @Test - void token이_없으면_예외가_발생한다() { - // given - when(authenticationExtractor.extractFromResponse(response)).thenThrow(InvalidJsonKeyException.class); - - // when & then - assertThatThrownBy( - () -> tokenRegenerateInterceptor.postHandle(request, response, new Object(), new ModelAndView())) - .isInstanceOf(InvalidJsonKeyException.class); - } -} diff --git a/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContextTest.java b/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContextTest.java deleted file mode 100644 index 5f5cab3d..00000000 --- a/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationContextTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.atwoz.member.ui.auth.support.auth; - -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -@SuppressWarnings("NonAsciiCharacters") -class AuthenticationContextTest { - - private AuthenticationContext authenticationContext; - - @BeforeEach - void setup() { - authenticationContext = new AuthenticationContext(); - } - - @Test - void member_id를_반환한다() { - // given - authenticationContext.setAuthentication(1L); - - // when - Long result = authenticationContext.getPrincipal(); - - // then - assertThat(result).isEqualTo(1L); - } - - @Test - void member_id가_없다면_예외를_발생한다() { - // given - authenticationContext.setAuthentication(null); - - // when & then - assertThatThrownBy(() -> authenticationContext.getPrincipal()) - .isInstanceOf(LoginInvalidException.class); - } - - @Test - void 미확인_유저로_바꾼다() { - // given - authenticationContext.setAnonymous(); - - // when - Long result = authenticationContext.getPrincipal(); - - // then - assertThat(result).isEqualTo(-1L); - } -} diff --git a/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractorTest.java b/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractorTest.java deleted file mode 100644 index 9606cf94..00000000 --- a/src/test/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractorTest.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.atwoz.member.ui.auth.support.auth; - -import com.atwoz.member.domain.auth.JsonMapper; -import com.atwoz.member.exception.exceptions.auth.InvalidJsonKeyException; -import com.fasterxml.jackson.core.JsonProcessingException; -import jakarta.servlet.http.HttpServletRequest; -import java.util.Optional; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.web.util.ContentCachingResponseWrapper; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.SoftAssertions.assertSoftly; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -@SuppressWarnings("NonAsciiCharacters") -class AuthenticationExtractorTest { - - private static final String AUTHORIZATION_HEADER = "Authorization"; - private static final String BEARER = "Bearer"; - - private final HttpServletRequest request = mock(HttpServletRequest.class); - private final ContentCachingResponseWrapper response = mock(ContentCachingResponseWrapper.class); - private final JsonMapper jsonMapper = mock(JsonMapper.class); - private AuthenticationExtractor authenticationExtractor; - - @BeforeEach - void setup() { - authenticationExtractor = new AuthenticationExtractor(jsonMapper); - } - - - @Nested - class 요청에서_토큰_추출 { - - @Test - void 토큰이_정상적으로_조회된다() { - // given - String expectedResponseToken = BEARER + " tokenSignature"; - when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn(expectedResponseToken); - - // when - Optional result = authenticationExtractor.extractFromRequest(request); - - // then - assertSoftly(softly -> { - softly.assertThat(result).isPresent(); - softly.assertThat(result).isEqualTo(Optional.of("tokenSignature")); - }); - } - - @Test - void 토큰_헤더가_없다면_빈_값이_반환된다() { - // given - when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn("InvalidType token"); - - // when - Optional result = authenticationExtractor.extractFromRequest(request); - - // then - assertThat(result).isEmpty(); - } - } - - @Nested - class 응답에서_토큰_추출 { - - @Test - void 토큰이_정상적으로_조회된다() throws JsonProcessingException { - // given - String tokenJson = "{\"token\":\"validToken\"}"; - when(response.getContentAsByteArray()).thenReturn(tokenJson.getBytes()); - when(jsonMapper.getValueByKey(tokenJson, "token")).thenReturn("validToken"); - - // when - String extractedToken = authenticationExtractor.extractFromResponse(response); - - // then - assertThat(extractedToken).isEqualTo("validToken"); - } - - @Test - void 응답_body에_토큰의_정보가_없으면_예외가_발생한다() { - // given - String invalidToken = "invalidToken"; - when(response.getContentAsByteArray()).thenReturn(invalidToken.getBytes()); - when(jsonMapper.getValueByKey(invalidToken, "token")).thenThrow(InvalidJsonKeyException.class); - - // when & then - assertThatThrownBy(() -> authenticationExtractor.extractFromResponse(response)) - .isInstanceOf(InvalidJsonKeyException.class); - } - } -} From 10cf2e7eab501de2ee4f9a9ea22a91729a6302f7 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:38:37 +0900 Subject: [PATCH 44/66] =?UTF-8?q?move:=20=ED=8C=8C=EC=9D=BC=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interceptor/PathMatcherInterceptor.java | 4 +- .../interceptor/support}/HttpMethod.java | 2 +- .../interceptor/support}/PathContainer.java | 7 ++- .../interceptor/support}/PathRequest.java | 2 +- ...uthService.java => MemberAuthService.java} | 24 ++++----- .../atwoz/member/config/MemberAuthConfig.java | 51 +++++++++++++++++++ ....java => MemberLoginInvalidException.java} | 4 +- ...java => MemberJwtMemberTokenProvider.java} | 42 ++++++++++----- ...troller.java => MemberAuthController.java} | 12 ++--- .../auth/support/{auth => }/AuthMember.java | 2 +- ...ava => MemberAuthenticationExtractor.java} | 23 ++------- .../support/{auth => }/OAuthAuthority.java | 2 +- .../support/{auth => }/OAuthPlatform.java | 2 +- .../support/{auth => }/OAuthProperties.java | 2 +- ...r.java => MemberAuthArgumentResolver.java} | 18 ++----- 15 files changed, 119 insertions(+), 78 deletions(-) rename src/main/java/com/atwoz/{member/ui/auth => global/config}/interceptor/PathMatcherInterceptor.java (91%) rename src/main/java/com/atwoz/{member/ui/auth/interceptor => global/config/interceptor/support}/HttpMethod.java (84%) rename src/main/java/com/atwoz/{member/ui/auth/interceptor => global/config/interceptor/support}/PathContainer.java (96%) rename src/main/java/com/atwoz/{member/ui/auth/interceptor => global/config/interceptor/support}/PathRequest.java (91%) rename src/main/java/com/atwoz/member/application/auth/{AuthService.java => MemberAuthService.java} (57%) create mode 100644 src/main/java/com/atwoz/member/config/MemberAuthConfig.java rename src/main/java/com/atwoz/member/exception/exceptions/auth/{LoginInvalidException.java => MemberLoginInvalidException.java} (52%) rename src/main/java/com/atwoz/member/infrastructure/auth/{JwtTokenProvider.java => MemberJwtMemberTokenProvider.java} (66%) rename src/main/java/com/atwoz/member/ui/auth/{AuthController.java => MemberAuthController.java} (74%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth => }/AuthMember.java (84%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth/AuthenticationExtractor.java => MemberAuthenticationExtractor.java} (56%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthAuthority.java (85%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthPlatform.java (92%) rename src/main/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthProperties.java (92%) rename src/main/java/com/atwoz/member/ui/auth/support/resolver/{AuthArgumentResolver.java => MemberAuthArgumentResolver.java} (65%) diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathMatcherInterceptor.java b/src/main/java/com/atwoz/global/config/interceptor/PathMatcherInterceptor.java similarity index 91% rename from src/main/java/com/atwoz/member/ui/auth/interceptor/PathMatcherInterceptor.java rename to src/main/java/com/atwoz/global/config/interceptor/PathMatcherInterceptor.java index 51e8cd30..00e1dcb5 100644 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathMatcherInterceptor.java +++ b/src/main/java/com/atwoz/global/config/interceptor/PathMatcherInterceptor.java @@ -1,5 +1,7 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global.config.interceptor; +import com.atwoz.global.config.interceptor.support.HttpMethod; +import com.atwoz.global.config.interceptor.support.PathContainer; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/HttpMethod.java b/src/main/java/com/atwoz/global/config/interceptor/support/HttpMethod.java similarity index 84% rename from src/main/java/com/atwoz/member/ui/auth/interceptor/HttpMethod.java rename to src/main/java/com/atwoz/global/config/interceptor/support/HttpMethod.java index d61ba25e..267b9e2a 100644 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/HttpMethod.java +++ b/src/main/java/com/atwoz/global/config/interceptor/support/HttpMethod.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global.config.interceptor.support; public enum HttpMethod { diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathContainer.java b/src/main/java/com/atwoz/global/config/interceptor/support/PathContainer.java similarity index 96% rename from src/main/java/com/atwoz/member/ui/auth/interceptor/PathContainer.java rename to src/main/java/com/atwoz/global/config/interceptor/support/PathContainer.java index 53bffbf0..f955fa96 100644 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathContainer.java +++ b/src/main/java/com/atwoz/global/config/interceptor/support/PathContainer.java @@ -1,10 +1,9 @@ -package com.atwoz.member.ui.auth.interceptor; - -import org.springframework.util.AntPathMatcher; -import org.springframework.util.PathMatcher; +package com.atwoz.global.config.interceptor.support; import java.util.ArrayList; import java.util.List; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.PathMatcher; public class PathContainer { diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathRequest.java b/src/main/java/com/atwoz/global/config/interceptor/support/PathRequest.java similarity index 91% rename from src/main/java/com/atwoz/member/ui/auth/interceptor/PathRequest.java rename to src/main/java/com/atwoz/global/config/interceptor/support/PathRequest.java index 44301134..2c6ed0b9 100644 --- a/src/main/java/com/atwoz/member/ui/auth/interceptor/PathRequest.java +++ b/src/main/java/com/atwoz/global/config/interceptor/support/PathRequest.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global.config.interceptor.support; import org.springframework.util.PathMatcher; diff --git a/src/main/java/com/atwoz/member/application/auth/AuthService.java b/src/main/java/com/atwoz/member/application/auth/MemberAuthService.java similarity index 57% rename from src/main/java/com/atwoz/member/application/auth/AuthService.java rename to src/main/java/com/atwoz/member/application/auth/MemberAuthService.java index 4183b5a4..f6383453 100644 --- a/src/main/java/com/atwoz/member/application/auth/AuthService.java +++ b/src/main/java/com/atwoz/member/application/auth/MemberAuthService.java @@ -1,9 +1,9 @@ package com.atwoz.member.application.auth; -import com.atwoz.global.event.Events; import com.atwoz.member.application.auth.dto.LoginRequest; -import com.atwoz.member.application.auth.event.ValidatedLoginEvent; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; +import com.atwoz.member.domain.member.Member; +import com.atwoz.member.domain.member.MemberRepository; import com.atwoz.member.infrastructure.auth.dto.MemberInfoResponse; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; import lombok.RequiredArgsConstructor; @@ -12,23 +12,23 @@ @RequiredArgsConstructor @Service -public class AuthService { +public class MemberAuthService { private static final String DEFAULT_PHONE_NUMBER = "01011111111"; - private final TokenProvider tokenProvider; + private final MemberTokenProvider memberTokenProvider; private final OAuthRequester oAuthRequester; + private final MemberRepository memberRepository; + /** + * OAuth 인증방식과 PASS 인증 방식에 차이가 존재해서 회의 후 메서드 변경을 진행할 예정 + */ @Transactional public String login(final LoginRequest request, final OAuthProviderRequest provider) { String accessToken = oAuthRequester.getAccessToken(request.code(), provider); MemberInfoResponse memberInfoResponse = oAuthRequester.getMemberInfo(accessToken, provider); - - /** - * OAuth 인증방식과 PASS 인증 방식에 차이가 존재해서 회의 후 메서드 변경을 진행할 예정 - */ - Events.raise(new ValidatedLoginEvent(DEFAULT_PHONE_NUMBER)); - - return tokenProvider.createTokenWithPhoneNumber(DEFAULT_PHONE_NUMBER); + Member createdMember = Member.createWithOAuth(DEFAULT_PHONE_NUMBER); + memberRepository.save(createdMember); + return memberTokenProvider.createAccessToken(createdMember.getId()); } } diff --git a/src/main/java/com/atwoz/member/config/MemberAuthConfig.java b/src/main/java/com/atwoz/member/config/MemberAuthConfig.java new file mode 100644 index 00000000..8dac265f --- /dev/null +++ b/src/main/java/com/atwoz/member/config/MemberAuthConfig.java @@ -0,0 +1,51 @@ +package com.atwoz.member.config; + +import com.atwoz.global.config.interceptor.PathMatcherInterceptor; +import com.atwoz.member.ui.auth.interceptor.MemberLoginValidCheckerInterceptor; +import com.atwoz.member.ui.auth.support.resolver.MemberAuthArgumentResolver; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import static com.atwoz.global.config.interceptor.support.HttpMethod.DELETE; +import static com.atwoz.global.config.interceptor.support.HttpMethod.GET; +import static com.atwoz.global.config.interceptor.support.HttpMethod.OPTIONS; +import static com.atwoz.global.config.interceptor.support.HttpMethod.PATCH; +import static com.atwoz.global.config.interceptor.support.HttpMethod.POST; + +@RequiredArgsConstructor +@Configuration +public class MemberAuthConfig implements WebMvcConfigurer { + + private final MemberAuthArgumentResolver memberAuthArgumentResolver; + private final MemberLoginValidCheckerInterceptor memberLoginValidCheckerInterceptor; + + @Override + public void addInterceptors(final InterceptorRegistry registry) { + registry.addInterceptor(loginValidCheckerInterceptor()); + } + + /** + * @AuthMember를 통해서 인증이 필요한 경우에 해당 메서드에 URI를 추가해주면 된다. 추가를 해야지 인증,인가 가능 + */ + private HandlerInterceptor loginValidCheckerInterceptor() { + return new PathMatcherInterceptor(memberLoginValidCheckerInterceptor) + .excludePathPattern("/**", OPTIONS) + .excludePathPattern("/api/missions/**", GET, POST, PATCH, DELETE) + .excludePathPattern("/api/surveys/**", GET, POST) + .addPathPatterns("/api/members/**", GET, POST, PATCH, DELETE) + .addPathPatterns("/api/reports/**", POST) + .addPathPatterns("/api/surveys/**", GET, POST) + .addPathPatterns("/api/members/me/missions/**", GET, POST, PATCH) + .addPathPatterns("/api/members/me/surveys/**", GET, POST); + } + + @Override + public void addArgumentResolvers(final List resolvers) { + resolvers.add(memberAuthArgumentResolver); + } +} diff --git a/src/main/java/com/atwoz/member/exception/exceptions/auth/LoginInvalidException.java b/src/main/java/com/atwoz/member/exception/exceptions/auth/MemberLoginInvalidException.java similarity index 52% rename from src/main/java/com/atwoz/member/exception/exceptions/auth/LoginInvalidException.java rename to src/main/java/com/atwoz/member/exception/exceptions/auth/MemberLoginInvalidException.java index 1716d862..e217bcc0 100644 --- a/src/main/java/com/atwoz/member/exception/exceptions/auth/LoginInvalidException.java +++ b/src/main/java/com/atwoz/member/exception/exceptions/auth/MemberLoginInvalidException.java @@ -1,8 +1,8 @@ package com.atwoz.member.exception.exceptions.auth; -public class LoginInvalidException extends RuntimeException { +public class MemberLoginInvalidException extends RuntimeException { - public LoginInvalidException() { + public MemberLoginInvalidException() { super("로그인 정보를 찾을 수 없습니다."); } } diff --git a/src/main/java/com/atwoz/member/infrastructure/auth/JwtTokenProvider.java b/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtMemberTokenProvider.java similarity index 66% rename from src/main/java/com/atwoz/member/infrastructure/auth/JwtTokenProvider.java rename to src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtMemberTokenProvider.java index 073c7df2..1df22539 100644 --- a/src/main/java/com/atwoz/member/infrastructure/auth/JwtTokenProvider.java +++ b/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtMemberTokenProvider.java @@ -1,6 +1,6 @@ package com.atwoz.member.infrastructure.auth; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; import com.atwoz.member.exception.exceptions.auth.ExpiredTokenException; import com.atwoz.member.exception.exceptions.auth.SignatureInvalidException; import com.atwoz.member.exception.exceptions.auth.TokenFormInvalidException; @@ -24,13 +24,23 @@ @NoArgsConstructor @Component -public class JwtTokenProvider implements TokenProvider { +public class MemberJwtMemberTokenProvider implements MemberTokenProvider { + + private static final String ID = "id"; + private static final String TOKEN_TYPE = "token type"; + private static final String REFRESH_TOKEN = "refresh token"; + private static final String ACCESS_TOKEN = "access token"; + private static final String ROLE = "role"; + private static final String MEMBER = "member"; @Value("${jwt.secret}") private String secret; - @Value("${jwt.expiration-period}") - private int expirationPeriod; + @Value("${jwt.access-token-expiration-period}") + private int accessTokenExpirationPeriod; + + @Value("${jwt.refresh-token-expiration-period}") + private int refreshTokenExpirationPeriod; private Key key; @@ -40,24 +50,28 @@ private void init() { } @Override - public String createTokenWithId(final Long id) { + public String createAccessToken(final Long id) { Claims claims = Jwts.claims(); - claims.put("id", id); - return createToken(claims); + claims.put(ID, id); + claims.put(TOKEN_TYPE, ACCESS_TOKEN); + claims.put(ROLE, MEMBER); + return createToken(claims, accessTokenExpirationPeriod); } @Override - public String createTokenWithPhoneNumber(final String phoneNumber) { + public String createRefreshToken(final Long id) { Claims claims = Jwts.claims(); - claims.put("phoneNumber", phoneNumber); - return createToken(claims); + claims.put(ID, id); + claims.put(TOKEN_TYPE, REFRESH_TOKEN); + claims.put(ROLE, MEMBER); + return createToken(claims, refreshTokenExpirationPeriod); } - private String createToken(final Claims claims) { + private String createToken(final Claims claims, final int expirationPeriod) { return Jwts.builder() .setClaims(claims) .setIssuedAt(issuedAt()) - .setExpiration(expiredAt()) + .setExpiration(expiredAt(expirationPeriod)) .signWith(key, SignatureAlgorithm.HS256) .compact(); } @@ -69,10 +83,10 @@ private Date issuedAt() { .toInstant()); } - private Date expiredAt() { + private Date expiredAt(final int expirationPeriod) { LocalDateTime now = LocalDateTime.now(); - return Date.from(now.plusHours(expirationPeriod) + return Date.from(now.plusDays(expirationPeriod) .atZone(ZoneId.systemDefault()) .toInstant()); } diff --git a/src/main/java/com/atwoz/member/ui/auth/AuthController.java b/src/main/java/com/atwoz/member/ui/auth/MemberAuthController.java similarity index 74% rename from src/main/java/com/atwoz/member/ui/auth/AuthController.java rename to src/main/java/com/atwoz/member/ui/auth/MemberAuthController.java index 00868d7a..79790959 100644 --- a/src/main/java/com/atwoz/member/ui/auth/AuthController.java +++ b/src/main/java/com/atwoz/member/ui/auth/MemberAuthController.java @@ -1,10 +1,10 @@ package com.atwoz.member.ui.auth; -import com.atwoz.member.application.auth.AuthService; +import com.atwoz.member.application.auth.MemberAuthService; import com.atwoz.member.application.auth.dto.LoginRequest; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; import com.atwoz.member.ui.auth.dto.TokenResponse; -import com.atwoz.member.ui.auth.support.auth.OAuthAuthority; +import com.atwoz.member.ui.auth.support.OAuthAuthority; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -14,16 +14,16 @@ import org.springframework.web.bind.annotation.RestController; @RequiredArgsConstructor -@RequestMapping("/api/auth") +@RequestMapping("/api/members/auth") @RestController -public class AuthController { +public class MemberAuthController { - private final AuthService authService; + private final MemberAuthService memberAuthService; @PostMapping("/login") public ResponseEntity login(@RequestBody @Valid final LoginRequest request, @OAuthAuthority final OAuthProviderRequest provider) { - String token = authService.login(request, provider); + String token = memberAuthService.login(request, provider); return ResponseEntity.ok(new TokenResponse(token)); } } diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthMember.java b/src/main/java/com/atwoz/member/ui/auth/support/AuthMember.java similarity index 84% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/AuthMember.java rename to src/main/java/com/atwoz/member/ui/auth/support/AuthMember.java index 7d29f516..4a1f9058 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthMember.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/AuthMember.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractor.java b/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractor.java similarity index 56% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractor.java rename to src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractor.java index 51a6f8e1..d6da4b8a 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/AuthenticationExtractor.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractor.java @@ -1,28 +1,22 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; -import com.atwoz.member.domain.auth.JsonMapper; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import org.springframework.web.util.ContentCachingResponseWrapper; @RequiredArgsConstructor @Component -public class AuthenticationExtractor { +public class MemberAuthenticationExtractor { private static final String AUTHORIZATION_HEADER = "Authorization"; private static final String BEARER = "Bearer"; private static final String HEADER_SPLIT_DELIMITER = " "; - private static final String TOKEN = "token"; private static final int TOKEN_TYPE_INDEX = 0; private static final int TOKEN_VALUE_INDEX = 1; private static final int VALID_HEADER_SPLIT_LENGTH = 2; - private final JsonMapper jsonMapper; - public Optional extractFromRequest(final HttpServletRequest request) { String header = request.getHeader(AUTHORIZATION_HEADER); @@ -33,7 +27,7 @@ public Optional extractFromRequest(final HttpServletRequest request) { return extractFromHeader(header.split(HEADER_SPLIT_DELIMITER)); } - public Optional extractFromHeader(final String[] headerParts) { + private Optional extractFromHeader(final String[] headerParts) { if (headerParts.length == VALID_HEADER_SPLIT_LENGTH && headerParts[TOKEN_TYPE_INDEX].equals(BEARER)) { return Optional.ofNullable(headerParts[TOKEN_VALUE_INDEX]); @@ -41,16 +35,5 @@ public Optional extractFromHeader(final String[] headerParts) { return Optional.empty(); } - - public String extractFromResponse(final HttpServletResponse response) { - ContentCachingResponseWrapper responseWrapper = (ContentCachingResponseWrapper) response; - String responseBody = getResponseBody(responseWrapper); - - return jsonMapper.getValueByKey(responseBody, TOKEN); - } - - private String getResponseBody(final ContentCachingResponseWrapper responseWrapper) { - return new String(responseWrapper.getContentAsByteArray()); - } } diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthAuthority.java b/src/main/java/com/atwoz/member/ui/auth/support/OAuthAuthority.java similarity index 85% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthAuthority.java rename to src/main/java/com/atwoz/member/ui/auth/support/OAuthAuthority.java index 5f2a41b2..10c4f1e8 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthAuthority.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/OAuthAuthority.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatform.java b/src/main/java/com/atwoz/member/ui/auth/support/OAuthPlatform.java similarity index 92% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatform.java rename to src/main/java/com/atwoz/member/ui/auth/support/OAuthPlatform.java index 2a64d1fb..27ae49cc 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatform.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/OAuthPlatform.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import com.atwoz.member.exception.exceptions.auth.OAuthPlatformNotFountException; import java.util.Arrays; diff --git a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthProperties.java b/src/main/java/com/atwoz/member/ui/auth/support/OAuthProperties.java similarity index 92% rename from src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthProperties.java rename to src/main/java/com/atwoz/member/ui/auth/support/OAuthProperties.java index 3439f194..cd53303a 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/auth/OAuthProperties.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/OAuthProperties.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; import java.util.Map; diff --git a/src/main/java/com/atwoz/member/ui/auth/support/resolver/AuthArgumentResolver.java b/src/main/java/com/atwoz/member/ui/auth/support/resolver/MemberAuthArgumentResolver.java similarity index 65% rename from src/main/java/com/atwoz/member/ui/auth/support/resolver/AuthArgumentResolver.java rename to src/main/java/com/atwoz/member/ui/auth/support/resolver/MemberAuthArgumentResolver.java index 930d6283..01cf7fce 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/resolver/AuthArgumentResolver.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/resolver/MemberAuthArgumentResolver.java @@ -1,8 +1,7 @@ package com.atwoz.member.ui.auth.support.resolver; -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; -import com.atwoz.member.ui.auth.support.auth.AuthMember; -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; +import com.atwoz.member.ui.auth.support.AuthMember; +import com.atwoz.member.ui.auth.support.MemberAuthenticationContext; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; @@ -13,11 +12,9 @@ @RequiredArgsConstructor @Component -public class AuthArgumentResolver implements HandlerMethodArgumentResolver { +public class MemberAuthArgumentResolver implements HandlerMethodArgumentResolver { - private static final int ANONYMOUS = -1; - - private final AuthenticationContext authenticationContext; + private final MemberAuthenticationContext memberAuthenticationContext; @Override public boolean supportsParameter(final MethodParameter parameter) { @@ -30,12 +27,7 @@ public Object resolveArgument(final MethodParameter parameter, final ModelAndViewContainer mavContainer, final NativeWebRequest webRequest, final WebDataBinderFactory binderFactory) throws Exception { - Long memberId = authenticationContext.getPrincipal(); - - if (memberId == ANONYMOUS) { - throw new LoginInvalidException(); - } - return memberId; + return memberAuthenticationContext.getPrincipal(); } } From 6eb2887241e35024fa57f5613971c410d4ba71d0 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:41:12 +0900 Subject: [PATCH 45/66] =?UTF-8?q?refactor:=20=ED=95=9C=20=EB=B0=94?= =?UTF-8?q?=EC=9A=B4=EB=94=94=EB=93=9C=20=EC=BB=A8=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=95=88=EC=97=90=20=EC=A1=B4=EC=9E=AC=ED=95=98?= =?UTF-8?q?=EB=8D=98=20=EA=B4=80=EB=A6=AC=EC=9E=90=EC=99=80=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EB=A5=BC=20=EC=84=9C=EB=A1=9C=20=EB=8B=A4=EB=A5=B8=20?= =?UTF-8?q?=EC=BB=A8=ED=85=8D=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/auth/MemberTokenProvider.java | 10 ++++++ .../exception/MemberExceptionHandler.java | 6 ++-- .../MemberLoginValidCheckerInterceptor.java | 34 +++++++++++++++++++ .../support/MemberAuthenticationContext.java | 25 ++++++++++++++ .../resolver/OAuthArgumentResolver.java | 4 +-- .../member/ui/member/MemberController.java | 2 +- 6 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/atwoz/member/domain/auth/MemberTokenProvider.java create mode 100644 src/main/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptor.java create mode 100644 src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContext.java diff --git a/src/main/java/com/atwoz/member/domain/auth/MemberTokenProvider.java b/src/main/java/com/atwoz/member/domain/auth/MemberTokenProvider.java new file mode 100644 index 00000000..01f63460 --- /dev/null +++ b/src/main/java/com/atwoz/member/domain/auth/MemberTokenProvider.java @@ -0,0 +1,10 @@ +package com.atwoz.member.domain.auth; + +public interface MemberTokenProvider { + + String createAccessToken(Long id); + + String createRefreshToken(Long id); + + T extract(String token, String claimName, Class classType); +} diff --git a/src/main/java/com/atwoz/member/exception/MemberExceptionHandler.java b/src/main/java/com/atwoz/member/exception/MemberExceptionHandler.java index 76e4ffb9..cd13c9e0 100644 --- a/src/main/java/com/atwoz/member/exception/MemberExceptionHandler.java +++ b/src/main/java/com/atwoz/member/exception/MemberExceptionHandler.java @@ -3,7 +3,7 @@ import com.atwoz.member.exception.exceptions.auth.ExpiredTokenException; import com.atwoz.member.exception.exceptions.auth.InvalidJsonKeyException; import com.atwoz.member.exception.exceptions.auth.JsonDataInvalidException; -import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; import com.atwoz.member.exception.exceptions.auth.OAuthPlatformNotFountException; import com.atwoz.member.exception.exceptions.auth.SignatureInvalidException; import com.atwoz.member.exception.exceptions.auth.TokenFormInvalidException; @@ -85,8 +85,8 @@ public ResponseEntity handleTokenInvalidException(final TokenInvalidExce return getUnauthorized(e); } - @ExceptionHandler(LoginInvalidException.class) - public ResponseEntity handleLoginInvalidException(final LoginInvalidException e) { + @ExceptionHandler(MemberLoginInvalidException.class) + public ResponseEntity handleLoginInvalidException(final MemberLoginInvalidException e) { return getUnauthorized(e); } diff --git a/src/main/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptor.java b/src/main/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptor.java new file mode 100644 index 00000000..9475d5e2 --- /dev/null +++ b/src/main/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptor.java @@ -0,0 +1,34 @@ +package com.atwoz.member.ui.auth.interceptor; + +import com.atwoz.member.domain.auth.MemberTokenProvider; +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; +import com.atwoz.member.ui.auth.support.MemberAuthenticationContext; +import com.atwoz.member.ui.auth.support.MemberAuthenticationExtractor; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +@RequiredArgsConstructor +@Component +public class MemberLoginValidCheckerInterceptor implements HandlerInterceptor { + + private static final String MEMBER_ID = "id"; + + private final MemberAuthenticationContext memberAuthenticationContext; + private final MemberAuthenticationExtractor memberAuthenticationExtractor; + private final MemberTokenProvider memberTokenProvider; + + @Override + public boolean preHandle(final HttpServletRequest request, + final HttpServletResponse response, + final Object handler) throws Exception { + String token = memberAuthenticationExtractor.extractFromRequest(request) + .orElseThrow(MemberLoginInvalidException::new); + Long extractedId = memberTokenProvider.extract(token, MEMBER_ID, Long.class); + memberAuthenticationContext.setAuthentication(extractedId); + + return true; + } +} diff --git a/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContext.java b/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContext.java new file mode 100644 index 00000000..3ab06f7c --- /dev/null +++ b/src/main/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContext.java @@ -0,0 +1,25 @@ +package com.atwoz.member.ui.auth.support; + +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; +import java.util.Objects; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +@RequestScope +@Component +public class MemberAuthenticationContext { + + private Long memberId; + + public void setAuthentication(final Long memberId) { + this.memberId = memberId; + } + + public Long getPrincipal() { + if (Objects.isNull(this.memberId)) { + throw new MemberLoginInvalidException(); + } + + return memberId; + } +} diff --git a/src/main/java/com/atwoz/member/ui/auth/support/resolver/OAuthArgumentResolver.java b/src/main/java/com/atwoz/member/ui/auth/support/resolver/OAuthArgumentResolver.java index 4a8fe4d4..998460e1 100644 --- a/src/main/java/com/atwoz/member/ui/auth/support/resolver/OAuthArgumentResolver.java +++ b/src/main/java/com/atwoz/member/ui/auth/support/resolver/OAuthArgumentResolver.java @@ -1,8 +1,8 @@ package com.atwoz.member.ui.auth.support.resolver; import com.atwoz.member.domain.auth.JsonMapper; -import com.atwoz.member.ui.auth.support.auth.OAuthAuthority; -import com.atwoz.member.ui.auth.support.auth.OAuthProperties; +import com.atwoz.member.ui.auth.support.OAuthAuthority; +import com.atwoz.member.ui.auth.support.OAuthProperties; import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; diff --git a/src/main/java/com/atwoz/member/ui/member/MemberController.java b/src/main/java/com/atwoz/member/ui/member/MemberController.java index d9263f6f..40d12ada 100644 --- a/src/main/java/com/atwoz/member/ui/member/MemberController.java +++ b/src/main/java/com/atwoz/member/ui/member/MemberController.java @@ -5,7 +5,7 @@ import com.atwoz.member.application.member.dto.MemberInitializeRequest; import com.atwoz.member.application.member.dto.MemberUpdateRequest; import com.atwoz.member.infrastructure.member.dto.MemberResponse; -import com.atwoz.member.ui.auth.support.auth.AuthMember; +import com.atwoz.member.ui.auth.support.AuthMember; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; From 99553e846b4ed10ca13e58fdac5ffc13c16eca76 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:45:49 +0900 Subject: [PATCH 46/66] =?UTF-8?q?refactor:=20Member=20=EB=B0=94=EC=9A=B4?= =?UTF-8?q?=EB=94=94=EB=93=9C=20=EC=BB=A8=ED=85=8D=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mission/ui/membermission/MemberMissionsController.java | 2 +- src/main/java/com/atwoz/report/ui/ReportController.java | 2 +- .../survey/ui/membersurvey/MemberSurveysController.java | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/atwoz/mission/ui/membermission/MemberMissionsController.java b/src/main/java/com/atwoz/mission/ui/membermission/MemberMissionsController.java index 1bd7dce2..d5946377 100644 --- a/src/main/java/com/atwoz/mission/ui/membermission/MemberMissionsController.java +++ b/src/main/java/com/atwoz/mission/ui/membermission/MemberMissionsController.java @@ -1,6 +1,6 @@ package com.atwoz.mission.ui.membermission; -import com.atwoz.member.ui.auth.support.auth.AuthMember; +import com.atwoz.member.ui.auth.support.AuthMember; import com.atwoz.mission.application.membermission.MemberMissionsQueryService; import com.atwoz.mission.intrastructure.membermission.dto.MemberMissionPagingResponse; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/atwoz/report/ui/ReportController.java b/src/main/java/com/atwoz/report/ui/ReportController.java index f3afd230..27cde16e 100644 --- a/src/main/java/com/atwoz/report/ui/ReportController.java +++ b/src/main/java/com/atwoz/report/ui/ReportController.java @@ -1,6 +1,6 @@ package com.atwoz.report.ui; -import com.atwoz.member.ui.auth.support.auth.AuthMember; +import com.atwoz.member.ui.auth.support.AuthMember; import com.atwoz.report.application.ReportService; import com.atwoz.report.application.dto.ReportCreateRequest; import jakarta.validation.Valid; diff --git a/src/main/java/com/atwoz/survey/ui/membersurvey/MemberSurveysController.java b/src/main/java/com/atwoz/survey/ui/membersurvey/MemberSurveysController.java index 46ec5e9a..7aa15f71 100644 --- a/src/main/java/com/atwoz/survey/ui/membersurvey/MemberSurveysController.java +++ b/src/main/java/com/atwoz/survey/ui/membersurvey/MemberSurveysController.java @@ -1,12 +1,13 @@ package com.atwoz.survey.ui.membersurvey; -import com.atwoz.member.ui.auth.support.auth.AuthMember; +import com.atwoz.member.ui.auth.support.AuthMember; import com.atwoz.survey.application.membersurvey.MemberSurveysQueryService; import com.atwoz.survey.application.membersurvey.MemberSurveysService; import com.atwoz.survey.application.membersurvey.dto.SurveySubmitRequest; import com.atwoz.survey.infrastructure.membersurvey.dto.MemberSurveyResponse; import com.atwoz.survey.ui.membersurvey.dto.MatchMemberSearchResponse; import jakarta.validation.Valid; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -17,8 +18,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @RequiredArgsConstructor @RequestMapping("/api/members/me/surveys") @RestController From ab57bc32e2a67c45db291268852de197e14f2d99 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:46:22 +0900 Subject: [PATCH 47/66] =?UTF-8?q?test:=20AdminAuthController=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/auth/AdminAuthControllerTest.java | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/ui/auth/AdminAuthControllerTest.java diff --git a/src/test/java/com/atwoz/admin/ui/auth/AdminAuthControllerTest.java b/src/test/java/com/atwoz/admin/ui/auth/AdminAuthControllerTest.java new file mode 100644 index 00000000..84ea99d4 --- /dev/null +++ b/src/test/java/com/atwoz/admin/ui/auth/AdminAuthControllerTest.java @@ -0,0 +1,137 @@ +package com.atwoz.admin.ui.auth; + +import com.atwoz.admin.application.auth.AdminAuthService; +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; +import com.atwoz.helper.MockBeanInjection; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import static com.atwoz.admin.fixture.AdminRequestFixture.관리자_로그인_요청; +import static com.atwoz.admin.fixture.AdminRequestFixture.관리자_회원_가입_요청; +import static com.atwoz.admin.fixture.AdminTokenResponseFixture.관리자_액세스_토큰_생성_응답; +import static com.atwoz.admin.fixture.AdminTokenResponseFixture.관리자_토큰_생성_응답; +import static com.atwoz.helper.RestDocsHelper.customDocument; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@AutoConfigureRestDocs +@WebMvcTest(AdminAuthController.class) +class AdminAuthControllerTest extends MockBeanInjection { + + private static final String BEARER_TOKEN = "Bearer token"; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + @Autowired + private AdminAuthService adminAuthService; + + @Test + void 회원_가입을_진행한다() throws Exception { + // given + AdminSignUpRequest adminSignUpRequest = 관리자_회원_가입_요청(); + AdminTokenResponse adminTokenResponse = 관리자_토큰_생성_응답(); + when(adminAuthService.signUp(adminSignUpRequest)).thenReturn(adminTokenResponse); + + // when & then + mockMvc.perform(post("/api/admins/auth/sign-up") + .content(objectMapper.writeValueAsString(adminSignUpRequest)) + .contentType(MediaType.APPLICATION_JSON) + ).andExpect(status().isOk()) + .andDo(customDocument("관리자_회원가입", + requestFields( + fieldWithPath("email").description("이메일"), + fieldWithPath("password").description("비밀번호"), + fieldWithPath("confirmPassword").description("비밀번호 확인"), + fieldWithPath("adminProfileSignUpRequest").description("관리자 프로필 정보"), + fieldWithPath("adminProfileSignUpRequest.name").description("이름"), + fieldWithPath("adminProfileSignUpRequest.phoneNumber").description("전화번호") + ), + responseHeaders( + headerWithName("Cookie").description("발급된 리프레쉬 토큰") + ), + responseFields( + fieldWithPath("accessToken").description("발급된 액세스 토큰") + ) + ) + ); + } + + @Test + void 로그인을_진행한다() throws Exception { + // given + AdminLoginRequest adminLoginRequest = 관리자_로그인_요청(); + AdminTokenResponse adminTokenResponse = 관리자_토큰_생성_응답(); + when(adminAuthService.login(adminLoginRequest)).thenReturn(adminTokenResponse); + + // when & then + mockMvc.perform(post("/api/admins/auth/login") + .content(objectMapper.writeValueAsString(adminLoginRequest)) + .contentType(MediaType.APPLICATION_JSON) + ).andExpect(status().isOk()) + .andDo(print()) + .andDo(customDocument("관리자_로그인", + requestFields( + fieldWithPath("email").description("이메일"), + fieldWithPath("password").description("비밀번호") + ), + responseHeaders( + headerWithName("Cookie").description("발급된 리프레쉬 토큰") + ), + responseFields( + fieldWithPath("accessToken").description("발급된 액세스 토큰") + ) + ) + ); + } + + @Test + void 액세스_토큰을_재발행한다() throws Exception { + // given + String refreshToken = "refreshToken"; + AdminAccessTokenResponse adminAccessTokenResponse = 관리자_액세스_토큰_생성_응답(); + when(adminAuthService.reGenerateAccessToken(any())).thenReturn(adminAccessTokenResponse); + + // when & then + mockMvc.perform(post("/api/admins/auth/access-token-regeneration") + .header(AUTHORIZATION, BEARER_TOKEN) + .header(HttpHeaders.COOKIE, refreshToken) + ).andExpect(status().isOk()) + .andDo(print()) + .andDo(customDocument("관리자_액세스_토큰_재발행", + requestHeaders( + headerWithName(AUTHORIZATION).description("유저 토큰 정보"), + headerWithName("Cookie").description("이전에 발급받은 리프레쉬 토큰") + ), + responseFields( + fieldWithPath("accessToken").description("지금 발급된 액세스 토큰") + ) + ) + ); + } +} From ffc72dae78d555f8762bacff13d543ab34172f35 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:46:39 +0900 Subject: [PATCH 48/66] =?UTF-8?q?test:=20AdminAuthenticationContext=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminAuthenticationContextTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContextTest.java diff --git a/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContextTest.java b/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContextTest.java new file mode 100644 index 00000000..f9f3374d --- /dev/null +++ b/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationContextTest.java @@ -0,0 +1,44 @@ +package com.atwoz.admin.ui.auth.support; + +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AdminAuthenticationContextTest { + + private AdminAuthenticationContext adminAuthenticationContext; + + @BeforeEach + void setup() { + adminAuthenticationContext = new AdminAuthenticationContext(); + } + + @Test + void admin_id를_반환한다() { + // given + adminAuthenticationContext.setAuthentication(1L); + + // when + Long result = adminAuthenticationContext.getPrincipal(); + + // then + assertThat(result).isEqualTo(1L); + } + + @Test + void admin_id가_없다면_예외를_발생한다() { + // given + adminAuthenticationContext.setAuthentication(null); + + // when & then + assertThatThrownBy(() -> adminAuthenticationContext.getPrincipal()) + .isInstanceOf(AdminLoginInvalidException.class); + } +} From dc412d0a3c95beaed3d2fbfa8170a0f79b14e0a3 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:46:53 +0900 Subject: [PATCH 49/66] =?UTF-8?q?test:=20AdminAuthenticationExtractor=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminAuthenticationExtractorTest.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractorTest.java diff --git a/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractorTest.java b/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractorTest.java new file mode 100644 index 00000000..ff6871ad --- /dev/null +++ b/src/test/java/com/atwoz/admin/ui/auth/support/AdminAuthenticationExtractorTest.java @@ -0,0 +1,62 @@ +package com.atwoz.admin.ui.auth.support; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AdminAuthenticationExtractorTest { + + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String BEARER = "Bearer"; + + private final HttpServletRequest request = mock(HttpServletRequest.class); + private AdminAuthenticationExtractor adminAuthenticationExtractor; + + @BeforeEach + void setup() { + adminAuthenticationExtractor = new AdminAuthenticationExtractor(); + } + + @Nested + class 요청에서_토큰_추출 { + + @Test + void 토큰이_정상적으로_조회된다() { + // given + String expectedResponseToken = BEARER + " tokenSignature"; + when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn(expectedResponseToken); + + // when + Optional result = adminAuthenticationExtractor.extractFromRequest(request); + + // then + assertSoftly(softly -> { + softly.assertThat(result).isPresent(); + softly.assertThat(result).isEqualTo(Optional.of("tokenSignature")); + }); + } + + @Test + void 토큰_헤더가_없다면_빈_값이_반환된다() { + // given + when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn("InvalidType token"); + + // when + Optional result = adminAuthenticationExtractor.extractFromRequest(request); + + // then + assertThat(result).isEmpty(); + } + } +} From 0b72297cebb0beb3d930ea783675ae92072a6606 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:47:15 +0900 Subject: [PATCH 50/66] =?UTF-8?q?test:=20AdminAuthService=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/AdminAuthServiceTest.java | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/application/auth/AdminAuthServiceTest.java diff --git a/src/test/java/com/atwoz/admin/application/auth/AdminAuthServiceTest.java b/src/test/java/com/atwoz/admin/application/auth/AdminAuthServiceTest.java new file mode 100644 index 00000000..eff1aafb --- /dev/null +++ b/src/test/java/com/atwoz/admin/application/auth/AdminAuthServiceTest.java @@ -0,0 +1,133 @@ +package com.atwoz.admin.application.auth; + +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; +import com.atwoz.admin.domain.admin.AdminRepository; +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminNotFoundException; +import com.atwoz.admin.exception.exceptions.InvalidPasswordException; +import com.atwoz.admin.infrastructure.admin.AdminFakeRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static com.atwoz.admin.fixture.AdminFixture.관리자_생성; +import static com.atwoz.admin.fixture.AdminRequestFixture.관리자_로그인_요청; +import static com.atwoz.admin.fixture.AdminRequestFixture.관리자_회원_가입_요청; +import static com.atwoz.admin.fixture.AdminTokenResponseFixture.관리자_액세스_토큰_생성_응답; +import static com.atwoz.admin.fixture.AdminTokenResponseFixture.관리자_토큰_생성_응답; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@ExtendWith(MockitoExtension.class) +class AdminAuthServiceTest { + + private static final String EMAIL = "email@email.com"; + private static final String PASSWORD = "password"; + private static final String ID = "id"; + + @Mock + private AdminTokenProvider adminTokenProvider; + private AdminAuthService adminAuthService; + private AdminRepository adminRepository; + + @BeforeEach + void setup() { + adminRepository = new AdminFakeRepository(); + adminAuthService = new AdminAuthService(adminRepository, adminTokenProvider); + } + + @Test + void 회원_가입을_진행하면_토큰을_반환한다() { + // given + AdminSignUpRequest adminSignUpRequest = 관리자_회원_가입_요청(); + AdminTokenResponse adminTokenResponse = 관리자_토큰_생성_응답(); + when(adminTokenProvider.createAccessToken(any())).thenReturn(adminTokenResponse.accessToken()); + when(adminTokenProvider.createRefreshToken(any())).thenReturn(adminTokenResponse.refreshToken()); + + // when + AdminTokenResponse response = adminAuthService.signUp(adminSignUpRequest); + + // then + assertSoftly(softly -> { + softly.assertThat(response.accessToken()).isEqualTo(adminTokenResponse.accessToken()); + softly.assertThat(response.refreshToken()).isEqualTo(adminTokenResponse.refreshToken()); + }); + } + + @Nested + class 로그인 { + + @Test + void 로그인_입력이_올바르면_토큰을_반환한다() { + // given + adminRepository.save(관리자_생성()); + AdminLoginRequest adminLoginRequest = 관리자_로그인_요청(); + AdminTokenResponse adminTokenResponse = 관리자_토큰_생성_응답(); + when(adminTokenProvider.createAccessToken(any())).thenReturn(adminTokenResponse.accessToken()); + when(adminTokenProvider.createRefreshToken(any())).thenReturn(adminTokenResponse.refreshToken()); + + // when + AdminTokenResponse response = adminAuthService.login(adminLoginRequest); + + // then + assertSoftly(softly -> { + softly.assertThat(response.accessToken()).isEqualTo(adminTokenResponse.accessToken()); + softly.assertThat(response.refreshToken()).isEqualTo(adminTokenResponse.refreshToken()); + }); + } + + @Test + void 입력한_이메일이_올바르지_않으면_예외가_발생한다() { + // given + adminRepository.save(관리자_생성()); + String invalidEmail = "invalidEmail"; + AdminLoginRequest adminLoginRequest = 관리자_로그인_요청(invalidEmail, PASSWORD); + + // when & then + assertThatThrownBy(() -> adminAuthService.login(adminLoginRequest)) + .isInstanceOf(AdminNotFoundException.class); + } + + @Test + void 입력한_비밀번호가_올바르지_않으면_예외가_발생한다() { + // given + adminRepository.save(관리자_생성()); + String invalidPassword = "invalidPassword"; + AdminLoginRequest adminLoginRequest = 관리자_로그인_요청(EMAIL, invalidPassword); + + // when & then + assertThatThrownBy(() -> adminAuthService.login(adminLoginRequest)) + .isInstanceOf(InvalidPasswordException.class); + } + } + + @Test + void 리프레쉬_토큰으로_액세스_토큰을_재생성한다() { + // given + adminRepository.save(관리자_생성()); + Long expectedId = 1L; + String refreshToken = "refreshToken"; + AdminAccessTokenResponse adminAccessTokenResponse = 관리자_액세스_토큰_생성_응답(); + when(adminTokenProvider.extract(refreshToken, ID, Long.class)).thenReturn(expectedId); + when(adminTokenProvider.createAccessToken(any())).thenReturn(adminAccessTokenResponse.accessToken()); + + // when + AdminAccessTokenResponse response = adminAuthService.reGenerateAccessToken(refreshToken); + + // then + assertThat(response.accessToken()).isEqualTo(adminAccessTokenResponse.accessToken()); + } +} From 7e5d3bde6e53a5eb36b1735e10bbc94649ec7153 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:48:02 +0900 Subject: [PATCH 51/66] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20AdminFakeRepository=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/AdminFakeRepository.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/infrastructure/admin/AdminFakeRepository.java diff --git a/src/test/java/com/atwoz/admin/infrastructure/admin/AdminFakeRepository.java b/src/test/java/com/atwoz/admin/infrastructure/admin/AdminFakeRepository.java new file mode 100644 index 00000000..ab3c9001 --- /dev/null +++ b/src/test/java/com/atwoz/admin/infrastructure/admin/AdminFakeRepository.java @@ -0,0 +1,40 @@ +package com.atwoz.admin.infrastructure.admin; + +import com.atwoz.admin.domain.admin.Admin; +import com.atwoz.admin.domain.admin.AdminRepository; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@SuppressWarnings("NonAsciiCharacters") +public class AdminFakeRepository implements AdminRepository { + + private final Map map = new HashMap<>(); + private Long id = 1L; + + @Override + public Admin save(final Admin admin) { + Admin savedAdmin = Admin.createWith( + admin.getEmail(), + admin.getPassword(), + admin.getPassword(), + admin.getName(), + admin.getPhoneNumber() + ); + + map.put(id++, savedAdmin); + return savedAdmin; + } + + @Override + public Optional findAdminById(final Long id) { + return Optional.ofNullable(map.get(id)); + } + + @Override + public Optional findAdminByEmail(final String email) { + return map.values().stream() + .filter(admin -> email.equals(admin.getEmail())) + .findAny(); + } +} From 46fb99a617b566b9eca0f9330fd6de5777178e9d Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:48:56 +0900 Subject: [PATCH 52/66] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=ED=8E=B8=ED=95=98=EA=B2=8C=20=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20Fixture=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminFixture - AdminRequestFixture - AdminTokenResponseFixture --- .../com/atwoz/admin/fixture/AdminFixture.java | 35 ++++++++++++++++ .../admin/fixture/AdminRequestFixture.java | 40 +++++++++++++++++++ .../fixture/AdminTokenResponseFixture.java | 24 +++++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/fixture/AdminFixture.java create mode 100644 src/test/java/com/atwoz/admin/fixture/AdminRequestFixture.java create mode 100644 src/test/java/com/atwoz/admin/fixture/AdminTokenResponseFixture.java diff --git a/src/test/java/com/atwoz/admin/fixture/AdminFixture.java b/src/test/java/com/atwoz/admin/fixture/AdminFixture.java new file mode 100644 index 00000000..818f1c28 --- /dev/null +++ b/src/test/java/com/atwoz/admin/fixture/AdminFixture.java @@ -0,0 +1,35 @@ +package com.atwoz.admin.fixture; + +import com.atwoz.admin.domain.admin.Admin; + +public class AdminFixture { + + private static final String EMAIL = "email@email.com"; + private static final String PASSWORD = "password"; + private static final String NAME = "name"; + private static final String PHONE_NUMBER = "010-1234-5678"; + + public static Admin 관리자_생성() { + return Admin.createWith( + EMAIL, + PASSWORD, + PASSWORD, + NAME, + PHONE_NUMBER + ); + } + + public static Admin 관리자_생성(final String email, + final String password, + final String confirmPassword, + final String name, + final String phoneNumber) { + return Admin.createWith( + email, + password, + confirmPassword, + name, + phoneNumber + ); + } +} diff --git a/src/test/java/com/atwoz/admin/fixture/AdminRequestFixture.java b/src/test/java/com/atwoz/admin/fixture/AdminRequestFixture.java new file mode 100644 index 00000000..509098e0 --- /dev/null +++ b/src/test/java/com/atwoz/admin/fixture/AdminRequestFixture.java @@ -0,0 +1,40 @@ +package com.atwoz.admin.fixture; + +import com.atwoz.admin.application.auth.dto.AdminLoginRequest; +import com.atwoz.admin.application.auth.dto.AdminProfileSignUpRequest; +import com.atwoz.admin.application.auth.dto.AdminSignUpRequest; + +public class AdminRequestFixture { + + private static final String EMAIL = "email@email.com"; + private static final String PASSWORD = "password"; + private static final String NAME = "name"; + private static final String PHONE_NUMBER = "010-1234-5678"; + + public static AdminSignUpRequest 관리자_회원_가입_요청() { + return new AdminSignUpRequest( + EMAIL, + PASSWORD, + PASSWORD, + new AdminProfileSignUpRequest( + NAME, + PHONE_NUMBER + ) + ); + } + + public static AdminLoginRequest 관리자_로그인_요청() { + return new AdminLoginRequest( + EMAIL, + PASSWORD + ); + } + + public static AdminLoginRequest 관리자_로그인_요청(final String email, + final String password) { + return new AdminLoginRequest( + email, + password + ); + } +} diff --git a/src/test/java/com/atwoz/admin/fixture/AdminTokenResponseFixture.java b/src/test/java/com/atwoz/admin/fixture/AdminTokenResponseFixture.java new file mode 100644 index 00000000..c9076a9e --- /dev/null +++ b/src/test/java/com/atwoz/admin/fixture/AdminTokenResponseFixture.java @@ -0,0 +1,24 @@ +package com.atwoz.admin.fixture; + +import com.atwoz.admin.application.auth.dto.AdminAccessTokenResponse; +import com.atwoz.admin.application.auth.dto.AdminTokenResponse; + +@SuppressWarnings("NonAsciiCharacters") +public class AdminTokenResponseFixture { + + private static final String ACCESS_TOKEN = "accessToken"; + private static final String REFRESH_TOKEN = "refreshToken"; + + public static AdminTokenResponse 관리자_토큰_생성_응답() { + return new AdminTokenResponse( + ACCESS_TOKEN, + REFRESH_TOKEN + ); + } + + public static AdminAccessTokenResponse 관리자_액세스_토큰_생성_응답() { + return new AdminAccessTokenResponse( + ACCESS_TOKEN + ); + } +} From 213b5a7ac2177849017edc86665b6ca47f721915 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:49:10 +0900 Subject: [PATCH 53/66] =?UTF-8?q?test:=20AdminJpaRepository=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/AdminJpaRepositoryTest.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepositoryTest.java diff --git a/src/test/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepositoryTest.java b/src/test/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepositoryTest.java new file mode 100644 index 00000000..ce5814e9 --- /dev/null +++ b/src/test/java/com/atwoz/admin/infrastructure/admin/AdminJpaRepositoryTest.java @@ -0,0 +1,65 @@ +package com.atwoz.admin.infrastructure.admin; + +import com.atwoz.admin.domain.admin.Admin; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import static com.atwoz.admin.fixture.AdminFixture.관리자_생성; +import static org.assertj.core.api.SoftAssertions.assertSoftly; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@DataJpaTest +class AdminJpaRepositoryTest { + + @Autowired + private AdminJpaRepository adminJpaRepository; + + private Admin admin; + + @BeforeEach + void setup() { + admin = 관리자_생성(); + adminJpaRepository.save(admin); + } + + @Nested + class 회원_조회 { + + @Test + void 아이디로_관리자를_찾는다() { + // given + Long adminId = admin.getId(); + + // when + Optional foundAdmin = adminJpaRepository.findById(adminId); + + // then + assertSoftly(softly -> { + softly.assertThat(foundAdmin).isPresent(); + softly.assertThat(foundAdmin.get()).usingRecursiveComparison().isEqualTo(admin); + }); + } + + @Test + void 이메일로_관리자를_찾는다() { + // given + String adminEmail = admin.getEmail(); + + // when + Optional foundAdmin = adminJpaRepository.findAdminByEmail(adminEmail); + + // then + assertSoftly(softly -> { + softly.assertThat(foundAdmin).isPresent(); + softly.assertThat(foundAdmin.get()).usingRecursiveComparison().isEqualTo(admin); + }); + } + } +} From 782cb536bc676b08bc55fd78d18720e0d7149648 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:49:37 +0900 Subject: [PATCH 54/66] =?UTF-8?q?test:=20AdminLoginValidCheckerInterceptor?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...AdminLoginValidCheckerInterceptorTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptorTest.java diff --git a/src/test/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptorTest.java b/src/test/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptorTest.java new file mode 100644 index 00000000..03ce531b --- /dev/null +++ b/src/test/java/com/atwoz/admin/ui/auth/interceptor/AdminLoginValidCheckerInterceptorTest.java @@ -0,0 +1,41 @@ +package com.atwoz.admin.ui.auth.interceptor; + +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.exception.exceptions.AdminLoginInvalidException; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationContext; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationExtractor; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AdminLoginValidCheckerInterceptorTest { + + private final HttpServletRequest req = mock(HttpServletRequest.class); + private final HttpServletResponse res = mock(HttpServletResponse.class); + private final AdminAuthenticationContext adminAuthenticationContext = mock(AdminAuthenticationContext.class); + private final AdminAuthenticationExtractor adminAuthenticationExtractor = mock(AdminAuthenticationExtractor.class); + private final AdminTokenProvider adminTokenProvider = mock(AdminTokenProvider.class); + + @Test + void token이_없다면_예외를_발생한다() { + // given + AdminLoginValidCheckerInterceptor adminLoginValidCheckerInterceptor = new AdminLoginValidCheckerInterceptor( + adminAuthenticationContext, + adminAuthenticationExtractor, + adminTokenProvider + ); + when(req.getHeader("any")).thenReturn(null); + + // when & then + assertThatThrownBy(() -> adminLoginValidCheckerInterceptor.preHandle(req, res, new Object())) + .isInstanceOf(AdminLoginInvalidException.class); + } +} From b9aa487daedb3c72d9fd75699021878db51666aa Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:49:53 +0900 Subject: [PATCH 55/66] =?UTF-8?q?test:=20Admin=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../atwoz/admin/domain/admin/AdminTest.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/test/java/com/atwoz/admin/domain/admin/AdminTest.java diff --git a/src/test/java/com/atwoz/admin/domain/admin/AdminTest.java b/src/test/java/com/atwoz/admin/domain/admin/AdminTest.java new file mode 100644 index 00000000..c6f88ae1 --- /dev/null +++ b/src/test/java/com/atwoz/admin/domain/admin/AdminTest.java @@ -0,0 +1,80 @@ +package com.atwoz.admin.domain.admin; + +import com.atwoz.admin.domain.admin.vo.AdminStatus; +import com.atwoz.admin.domain.admin.vo.Authority; +import com.atwoz.admin.domain.admin.vo.Department; +import com.atwoz.admin.exception.exceptions.InvalidPasswordException; +import com.atwoz.admin.exception.exceptions.PasswordMismatchException; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static com.atwoz.admin.fixture.AdminFixture.관리자_생성; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.SoftAssertions.assertSoftly; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AdminTest { + + private static final String EMAIL = "email@email.com"; + private static final String PASSWORD = "password"; + private static final String CONFIRM_PASSWORD = "password"; + private static final String NAME = "name"; + private static final String PHONE_NUMBER = "010-1234-5678"; + + @Nested + class 관리자_생성 { + + @Test + void 입력이_올바르면_관리자를_생성한다() { + // when + Admin admin = Admin.createWith( + EMAIL, + PASSWORD, + CONFIRM_PASSWORD, + NAME, + PHONE_NUMBER + ); + + // then + assertSoftly(softly -> { + softly.assertThat(admin.getEmail()).isEqualTo(EMAIL); + softly.assertThat(admin.getPassword()).isEqualTo(PASSWORD); + softly.assertThat(admin.getName()).isEqualTo(NAME); + softly.assertThat(admin.getPhoneNumber()).isEqualTo(PHONE_NUMBER); + softly.assertThat(admin.getAuthority()).isEqualTo(Authority.ADMIN); + softly.assertThat(admin.getDepartment()).isEqualTo(Department.OPERATION); + softly.assertThat(admin.getAdminStatus()).isEqualTo(AdminStatus.PENDING); + }); + + } + + @Test + void 회원_가입시_입력한_비밀번호와_확인_비밀번호가_다르면_예외가_발생한다() { + // given + String invalidConfirmPassword = "invalidConfirmPassword"; + + // when & then + assertThatThrownBy(() -> Admin.createWith( + EMAIL, + PASSWORD, + invalidConfirmPassword, + NAME, + PHONE_NUMBER + )).isInstanceOf(PasswordMismatchException.class); + } + } + + @Test + void 로그인시_입력한_비밀번호가_관리자의_비밀번호와_다르면_예외가_발생한다() { + // given + Admin admin = 관리자_생성(); + String invalidPassword = "invalidPassword"; + + // when & then + assertThatThrownBy(() -> admin.validatePassword(invalidPassword)) + .isInstanceOf(InvalidPasswordException.class); + } +} From fccd6530f461d2eaac107b1c3391559ed984de10 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:50:49 +0900 Subject: [PATCH 56/66] =?UTF-8?q?test:=20Member=20=EB=B0=94=EC=9A=B4?= =?UTF-8?q?=EB=94=94=EB=93=9C=20=EC=BB=A8=ED=85=8D=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HttpMethodTest.java | 3 +- .../PathContainerTest.java | 4 +- .../PathRequestTest.java | 4 +- .../com/atwoz/helper/MockBeanInjection.java | 82 ++++++++++++++----- ...ceTest.java => MemberAuthServiceTest.java} | 21 ++--- ...va => MemberAuthControllerWebMvcTest.java} | 10 +-- ...emberLoginValidCheckerInterceptorTest.java | 41 ++++++++++ .../MemberAuthenticationContextTest.java | 45 ++++++++++ .../MemberAuthenticationExtractorTest.java | 62 ++++++++++++++ .../support/{auth => }/OAuthPlatformTest.java | 2 +- .../{auth => }/OAuthPropertiesTest.java | 2 +- .../MemberControllerAcceptanceFixture.java | 6 +- ...erMissionsControllerAcceptanceFixture.java | 6 +- .../ui/ReportControllerAcceptanceFixture.java | 6 +- ...berSurveysControllerAcceptanceFixture.java | 8 +- .../SurveyControllerAcceptanceFixture.java | 6 +- 16 files changed, 250 insertions(+), 58 deletions(-) rename src/test/java/com/atwoz/{member/ui/auth/interceptor => global}/HttpMethodTest.java (87%) rename src/test/java/com/atwoz/{member/ui/auth/interceptor => global}/PathContainerTest.java (91%) rename src/test/java/com/atwoz/{member/ui/auth/interceptor => global}/PathRequestTest.java (83%) rename src/test/java/com/atwoz/member/application/auth/{AuthServiceTest.java => MemberAuthServiceTest.java} (61%) rename src/test/java/com/atwoz/member/ui/auth/{AuthControllerWebMvcTest.java => MemberAuthControllerWebMvcTest.java} (89%) create mode 100644 src/test/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptorTest.java create mode 100644 src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContextTest.java create mode 100644 src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractorTest.java rename src/test/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthPlatformTest.java (96%) rename src/test/java/com/atwoz/member/ui/auth/support/{auth => }/OAuthPropertiesTest.java (95%) diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/HttpMethodTest.java b/src/test/java/com/atwoz/global/HttpMethodTest.java similarity index 87% rename from src/test/java/com/atwoz/member/ui/auth/interceptor/HttpMethodTest.java rename to src/test/java/com/atwoz/global/HttpMethodTest.java index 524f43f6..3e3d1e28 100644 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/HttpMethodTest.java +++ b/src/test/java/com/atwoz/global/HttpMethodTest.java @@ -1,5 +1,6 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global; +import com.atwoz.global.config.interceptor.support.HttpMethod; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/PathContainerTest.java b/src/test/java/com/atwoz/global/PathContainerTest.java similarity index 91% rename from src/test/java/com/atwoz/member/ui/auth/interceptor/PathContainerTest.java rename to src/test/java/com/atwoz/global/PathContainerTest.java index 3776ec64..5c83cb7e 100644 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/PathContainerTest.java +++ b/src/test/java/com/atwoz/global/PathContainerTest.java @@ -1,5 +1,7 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global; +import com.atwoz.global.config.interceptor.support.HttpMethod; +import com.atwoz.global.config.interceptor.support.PathContainer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/PathRequestTest.java b/src/test/java/com/atwoz/global/PathRequestTest.java similarity index 83% rename from src/test/java/com/atwoz/member/ui/auth/interceptor/PathRequestTest.java rename to src/test/java/com/atwoz/global/PathRequestTest.java index 7c914b53..51deff64 100644 --- a/src/test/java/com/atwoz/member/ui/auth/interceptor/PathRequestTest.java +++ b/src/test/java/com/atwoz/global/PathRequestTest.java @@ -1,5 +1,7 @@ -package com.atwoz.member.ui.auth.interceptor; +package com.atwoz.global; +import com.atwoz.global.config.interceptor.support.HttpMethod; +import com.atwoz.global.config.interceptor.support.PathRequest; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/atwoz/helper/MockBeanInjection.java b/src/test/java/com/atwoz/helper/MockBeanInjection.java index b3e89b09..9eb8413f 100644 --- a/src/test/java/com/atwoz/helper/MockBeanInjection.java +++ b/src/test/java/com/atwoz/helper/MockBeanInjection.java @@ -1,15 +1,23 @@ package com.atwoz.helper; -import com.atwoz.member.application.auth.AuthService; +import com.atwoz.admin.application.auth.AdminAuthService; +import com.atwoz.admin.domain.admin.AdminTokenProvider; +import com.atwoz.admin.ui.auth.interceptor.AdminLoginValidCheckerInterceptor; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationContext; +import com.atwoz.admin.ui.auth.support.AdminAuthenticationExtractor; +import com.atwoz.admin.ui.auth.support.resolver.AdminAuthArgumentResolver; +import com.atwoz.admin.ui.auth.support.resolver.AdminRefreshTokenExtractionArgumentResolver; +import com.atwoz.member.application.auth.MemberAuthService; import com.atwoz.member.application.member.MemberQueryService; import com.atwoz.member.application.member.MemberService; -import com.atwoz.member.domain.auth.TokenProvider; -import com.atwoz.member.ui.auth.interceptor.LoginValidCheckerInterceptor; -import com.atwoz.member.ui.auth.interceptor.ParseMemberIdFromTokenInterceptor; -import com.atwoz.member.ui.auth.interceptor.TokenRegenerateInterceptor; -import com.atwoz.member.ui.auth.support.auth.AuthenticationContext; -import com.atwoz.member.ui.auth.support.auth.OAuthProperties; -import com.atwoz.member.ui.auth.support.resolver.AuthArgumentResolver; +import com.atwoz.member.domain.auth.JsonMapper; +import com.atwoz.member.domain.auth.MemberTokenProvider; +import com.atwoz.member.domain.member.MemberRepository; +import com.atwoz.member.ui.auth.interceptor.MemberLoginValidCheckerInterceptor; +import com.atwoz.member.ui.auth.support.MemberAuthenticationContext; +import com.atwoz.member.ui.auth.support.MemberAuthenticationExtractor; +import com.atwoz.member.ui.auth.support.OAuthProperties; +import com.atwoz.member.ui.auth.support.resolver.MemberAuthArgumentResolver; import com.atwoz.member.ui.auth.support.resolver.OAuthArgumentResolver; import com.atwoz.memberlike.application.MemberLikeQueryService; import com.atwoz.memberlike.application.MemberLikeService; @@ -27,33 +35,67 @@ @MockBean(JpaMetamodelMappingContext.class) public class MockBeanInjection { + // Member @MockBean - protected TokenProvider tokenProvider; + protected OAuthArgumentResolver oAuthArgumentResolver; + + @MockBean + protected MemberAuthArgumentResolver memberAuthArgumentResolver; + + @MockBean + protected MemberLoginValidCheckerInterceptor memberLoginValidCheckerInterceptor; @MockBean - protected AuthenticationContext authenticationContext; + protected MemberAuthenticationContext memberAuthenticationContext; @MockBean - protected AuthService authService; + protected MemberAuthenticationExtractor authenticationExtractor; @MockBean protected OAuthProperties oAuthProperties; @MockBean - protected OAuthArgumentResolver oAuthArgumentResolver; + protected MemberService memberService; + + @MockBean + protected MemberQueryService memberQueryService; + + @MockBean + protected MemberAuthService memberAuthService; + + @MockBean + protected MemberTokenProvider memberTokenProvider; + + @MockBean + protected MemberRepository memberRepository; @MockBean - protected AuthArgumentResolver authArgumentResolver; + protected JsonMapper jsonMapper; + // Admin @MockBean - protected ParseMemberIdFromTokenInterceptor parseMemberIdFromTokenInterceptor; + protected AdminAuthArgumentResolver adminAuthArgumentResolver; @MockBean - protected LoginValidCheckerInterceptor loginValidCheckerInterceptor; + protected AdminRefreshTokenExtractionArgumentResolver adminRefreshTokenExtractionArgumentResolver; @MockBean - protected TokenRegenerateInterceptor tokenRegenerateInterceptor; + protected AdminLoginValidCheckerInterceptor adminLoginValidCheckerInterceptor; + @MockBean + protected AdminAuthenticationContext adminAuthenticationContext; + + @MockBean + protected AdminAuthenticationExtractor adminAuthenticationExtractor; + + @MockBean + protected AdminAuthService adminAuthService; + + @MockBean + protected AdminTokenProvider adminTokenProvider; + + + // Mission @MockBean protected MissionService missionService; @@ -66,9 +108,7 @@ public class MockBeanInjection { @MockBean protected MemberMissionsQueryService memberMissionsQueryService; - @MockBean - protected MemberService memberService; - + // Survey @MockBean protected SurveyService surveyService; @@ -78,9 +118,7 @@ public class MockBeanInjection { @MockBean protected MemberSurveysQueryService memberSurveysQueryService; - @MockBean - protected MemberQueryService memberQueryService; - + // Report @MockBean protected ReportService reportService; diff --git a/src/test/java/com/atwoz/member/application/auth/AuthServiceTest.java b/src/test/java/com/atwoz/member/application/auth/MemberAuthServiceTest.java similarity index 61% rename from src/test/java/com/atwoz/member/application/auth/AuthServiceTest.java rename to src/test/java/com/atwoz/member/application/auth/MemberAuthServiceTest.java index f98d4965..2c7bf9ec 100644 --- a/src/test/java/com/atwoz/member/application/auth/AuthServiceTest.java +++ b/src/test/java/com/atwoz/member/application/auth/MemberAuthServiceTest.java @@ -1,12 +1,12 @@ package com.atwoz.member.application.auth; import com.atwoz.member.application.auth.dto.LoginRequest; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; import com.atwoz.member.infrastructure.auth.OAuthFakeRequester; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; +import com.atwoz.member.infrastructure.member.MemberFakeRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -14,21 +14,22 @@ import static com.atwoz.member.fixture.OAuthProviderFixture.인증_기관_생성; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.anyString; +import static org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@DisplayNameGeneration(ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") @ExtendWith(MockitoExtension.class) -class AuthServiceTest { +class MemberAuthServiceTest { @Mock - private TokenProvider tokenProvider; - private AuthService authService; + private MemberTokenProvider memberTokenProvider; + private MemberAuthService memberAuthService; @BeforeEach void setup() { - authService = new AuthService(tokenProvider, new OAuthFakeRequester()); + memberAuthService = new MemberAuthService(memberTokenProvider, new OAuthFakeRequester(), new MemberFakeRepository()); } @Test @@ -37,10 +38,10 @@ void setup() { LoginRequest loginRequest = new LoginRequest("kakao", "code"); OAuthProviderRequest oAuthProviderRequest = 인증_기관_생성(); String expectedToken = "token"; - when(tokenProvider.createTokenWithPhoneNumber(anyString())).thenReturn(expectedToken); + when(memberTokenProvider.createAccessToken(any())).thenReturn(expectedToken); // when - String token = authService.login(loginRequest, oAuthProviderRequest); + String token = memberAuthService.login(loginRequest, oAuthProviderRequest); // then assertThat(token).isEqualTo(expectedToken); diff --git a/src/test/java/com/atwoz/member/ui/auth/AuthControllerWebMvcTest.java b/src/test/java/com/atwoz/member/ui/auth/MemberAuthControllerWebMvcTest.java similarity index 89% rename from src/test/java/com/atwoz/member/ui/auth/AuthControllerWebMvcTest.java rename to src/test/java/com/atwoz/member/ui/auth/MemberAuthControllerWebMvcTest.java index d607ab70..84ee1e17 100644 --- a/src/test/java/com/atwoz/member/ui/auth/AuthControllerWebMvcTest.java +++ b/src/test/java/com/atwoz/member/ui/auth/MemberAuthControllerWebMvcTest.java @@ -26,8 +26,8 @@ @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") @AutoConfigureRestDocs -@WebMvcTest(AuthController.class) -class AuthControllerWebMvcTest extends MockBeanInjection { +@WebMvcTest(MemberAuthController.class) +class MemberAuthControllerWebMvcTest extends MockBeanInjection { @Autowired private MockMvc mockMvc; @@ -41,15 +41,15 @@ class AuthControllerWebMvcTest extends MockBeanInjection { OAuthProviderRequest oAuthProviderRequest = 인증_기관_생성(); LoginRequest loginRequest = new LoginRequest("kakao", "code"); String expectedToken = "token"; - when(authService.login(loginRequest, oAuthProviderRequest)).thenReturn(expectedToken); + when(memberAuthService.login(loginRequest, oAuthProviderRequest)).thenReturn(expectedToken); // when & then - mockMvc.perform(post("/api/auth/login") + mockMvc.perform(post("/api/members/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(loginRequest)) ).andExpect(status().isOk()) .andDo(print()) - .andDo(customDocument("do_signup", + .andDo(customDocument("유저_로그인", requestFields( fieldWithPath("provider").description("인증기관"), fieldWithPath("code").description("인증코드") diff --git a/src/test/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptorTest.java b/src/test/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptorTest.java new file mode 100644 index 00000000..0925fae8 --- /dev/null +++ b/src/test/java/com/atwoz/member/ui/auth/interceptor/MemberLoginValidCheckerInterceptorTest.java @@ -0,0 +1,41 @@ +package com.atwoz.member.ui.auth.interceptor; + +import com.atwoz.member.domain.auth.MemberTokenProvider; +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; +import com.atwoz.member.ui.auth.support.MemberAuthenticationContext; +import com.atwoz.member.ui.auth.support.MemberAuthenticationExtractor; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class MemberLoginValidCheckerInterceptorTest { + + private final HttpServletRequest req = mock(HttpServletRequest.class); + private final HttpServletResponse res = mock(HttpServletResponse.class); + private final MemberAuthenticationContext memberAuthenticationContext = mock(MemberAuthenticationContext.class); + private final MemberAuthenticationExtractor memberAuthenticationExtractor = mock(MemberAuthenticationExtractor.class); + private final MemberTokenProvider memberTokenProvider = mock(MemberTokenProvider.class); + + @Test + void token이_없다면_예외를_발생한다() { + // given + MemberLoginValidCheckerInterceptor memberLoginValidCheckerInterceptor = new MemberLoginValidCheckerInterceptor( + memberAuthenticationContext, + memberAuthenticationExtractor, + memberTokenProvider + ); + when(req.getHeader("any")).thenReturn(null); + + // when & then + assertThatThrownBy(() -> memberLoginValidCheckerInterceptor.preHandle(req, res, new Object())) + .isInstanceOf(MemberLoginInvalidException.class); + } +} diff --git a/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContextTest.java b/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContextTest.java new file mode 100644 index 00000000..b2b9b611 --- /dev/null +++ b/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationContextTest.java @@ -0,0 +1,45 @@ +package com.atwoz.member.ui.auth.support; + +import com.atwoz.member.exception.exceptions.auth.MemberLoginInvalidException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class MemberAuthenticationContextTest { + + private MemberAuthenticationContext memberAuthenticationContext; + + @BeforeEach + void setup() { + memberAuthenticationContext = new MemberAuthenticationContext(); + } + + @Test + void member_id를_반환한다() { + // given + memberAuthenticationContext.setAuthentication(1L); + + // when + Long result = memberAuthenticationContext.getPrincipal(); + + // then + assertThat(result).isEqualTo(1L); + } + + @Test + void member_id가_없다면_예외를_발생한다() { + // given + memberAuthenticationContext.setAuthentication(null); + + // when & then + assertThatThrownBy(() -> memberAuthenticationContext.getPrincipal()) + .isInstanceOf(MemberLoginInvalidException.class); + } +} + diff --git a/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractorTest.java b/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractorTest.java new file mode 100644 index 00000000..9b43d47a --- /dev/null +++ b/src/test/java/com/atwoz/member/ui/auth/support/MemberAuthenticationExtractorTest.java @@ -0,0 +1,62 @@ +package com.atwoz.member.ui.auth.support; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class MemberAuthenticationExtractorTest { + + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String BEARER = "Bearer"; + + private final HttpServletRequest request = mock(HttpServletRequest.class); + private MemberAuthenticationExtractor memberAuthenticationExtractor; + + @BeforeEach + void setup() { + memberAuthenticationExtractor = new MemberAuthenticationExtractor(); + } + + @Nested + class 요청에서_토큰_추출 { + + @Test + void 토큰이_정상적으로_조회된다() { + // given + String expectedResponseToken = BEARER + " tokenSignature"; + when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn(expectedResponseToken); + + // when + Optional result = memberAuthenticationExtractor.extractFromRequest(request); + + // then + assertSoftly(softly -> { + softly.assertThat(result).isPresent(); + softly.assertThat(result).isEqualTo(Optional.of("tokenSignature")); + }); + } + + @Test + void 토큰_헤더가_없다면_빈_값이_반환된다() { + // given + when(request.getHeader(AUTHORIZATION_HEADER)).thenReturn("InvalidType token"); + + // when + Optional result = memberAuthenticationExtractor.extractFromRequest(request); + + // then + assertThat(result).isEmpty(); + } + } +} diff --git a/src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatformTest.java b/src/test/java/com/atwoz/member/ui/auth/support/OAuthPlatformTest.java similarity index 96% rename from src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatformTest.java rename to src/test/java/com/atwoz/member/ui/auth/support/OAuthPlatformTest.java index a1ffd6d1..ea165058 100644 --- a/src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPlatformTest.java +++ b/src/test/java/com/atwoz/member/ui/auth/support/OAuthPlatformTest.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import com.atwoz.member.exception.exceptions.auth.OAuthPlatformNotFountException; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPropertiesTest.java b/src/test/java/com/atwoz/member/ui/auth/support/OAuthPropertiesTest.java similarity index 95% rename from src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPropertiesTest.java rename to src/test/java/com/atwoz/member/ui/auth/support/OAuthPropertiesTest.java index e9bd2b8a..5047b77c 100644 --- a/src/test/java/com/atwoz/member/ui/auth/support/auth/OAuthPropertiesTest.java +++ b/src/test/java/com/atwoz/member/ui/auth/support/OAuthPropertiesTest.java @@ -1,4 +1,4 @@ -package com.atwoz.member.ui.auth.support.auth; +package com.atwoz.member.ui.auth.support; import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.infrastructure.auth.dto.OAuthProviderRequest; diff --git a/src/test/java/com/atwoz/member/ui/member/MemberControllerAcceptanceFixture.java b/src/test/java/com/atwoz/member/ui/member/MemberControllerAcceptanceFixture.java index 0b8f0af2..4af22e8e 100644 --- a/src/test/java/com/atwoz/member/ui/member/MemberControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/member/ui/member/MemberControllerAcceptanceFixture.java @@ -3,7 +3,7 @@ import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.application.member.dto.MemberInitializeRequest; import com.atwoz.member.application.member.dto.MemberUpdateRequest; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; import com.atwoz.member.fixture.MemberRequestFixture; @@ -31,14 +31,14 @@ public class MemberControllerAcceptanceFixture extends IntegrationHelper { protected MemberRepository memberRepository; @Autowired - protected TokenProvider tokenProvider; + protected MemberTokenProvider memberTokenProvider; protected Member 회원_생성() { return memberRepository.save(일반_유저_생성()); } protected String 토큰_생성(final Member member) { - return tokenProvider.createTokenWithId(member.getId()); + return memberTokenProvider.createAccessToken(member.getId()); } protected String 회원_닉네임을_요청한다() { diff --git a/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java b/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java index f54c15ff..45e6210b 100644 --- a/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java @@ -4,7 +4,7 @@ import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; import com.atwoz.member.domain.member.profile.physical.vo.Gender; -import com.atwoz.member.infrastructure.auth.JwtTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtMemberTokenProvider; import com.atwoz.mission.domain.membermission.MemberMission; import com.atwoz.mission.domain.membermission.MemberMissions; import com.atwoz.mission.domain.membermission.MemberMissionsRepository; @@ -31,7 +31,7 @@ class MemberMissionsControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private JwtTokenProvider jwtTokenProvider; + private MemberJwtMemberTokenProvider memberJwtTokenProvider; @Autowired private MemberRepository memberRepository; @@ -47,7 +47,7 @@ class MemberMissionsControllerAcceptanceFixture extends IntegrationHelper { } protected String 토큰_생성(final Member member) { - return jwtTokenProvider.createTokenWithId(member.getId()); + return memberJwtTokenProvider.createAccessToken(member.getId()); } protected Mission 데일리_미션_생성() { diff --git a/src/test/java/com/atwoz/report/ui/ReportControllerAcceptanceFixture.java b/src/test/java/com/atwoz/report/ui/ReportControllerAcceptanceFixture.java index aa27bb9e..e49455a3 100644 --- a/src/test/java/com/atwoz/report/ui/ReportControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/report/ui/ReportControllerAcceptanceFixture.java @@ -1,7 +1,7 @@ package com.atwoz.report.ui; import com.atwoz.helper.IntegrationHelper; -import com.atwoz.member.domain.auth.TokenProvider; +import com.atwoz.member.domain.auth.MemberTokenProvider; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; import com.atwoz.report.application.dto.ReportCreateRequest; @@ -27,14 +27,14 @@ public class ReportControllerAcceptanceFixture extends IntegrationHelper { protected MemberRepository memberRepository; @Autowired - protected TokenProvider tokenProvider; + protected MemberTokenProvider memberTokenProvider; protected Member 회원_생성() { return memberRepository.save(일반_유저_생성()); } protected String 토큰_생성(final Member member) { - return tokenProvider.createTokenWithId(member.getId()); + return memberTokenProvider.createAccessToken(member.getId()); } protected ReportCreateRequest 신고_요청서_요청() { diff --git a/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java b/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java index de7becb0..4796f01e 100644 --- a/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java @@ -3,7 +3,7 @@ import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.infrastructure.auth.JwtTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtMemberTokenProvider; import com.atwoz.survey.application.membersurvey.dto.SurveySubmitRequest; import com.atwoz.survey.domain.survey.SurveyRepository; import com.atwoz.survey.infrastructure.membersurvey.dto.MemberSurveyResponse; @@ -11,12 +11,12 @@ import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; +import java.util.List; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; -import java.util.List; import static com.atwoz.member.fixture.MemberFixture.일반_유저_생성; import static com.atwoz.survey.fixture.SurveyFixture.연애고사_선택_과목_질문_두개씩; import static com.atwoz.survey.fixture.SurveyFixture.연애고사_필수_과목_질문_30개씩; @@ -30,7 +30,7 @@ class MemberSurveysControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private JwtTokenProvider jwtTokenProvider; + private MemberJwtMemberTokenProvider memberJwtTokenProvider; @Autowired private MemberRepository memberRepository; @@ -47,7 +47,7 @@ class MemberSurveysControllerAcceptanceFixture extends IntegrationHelper { } protected String 토큰_생성(final Member member) { - return jwtTokenProvider.createTokenWithId(member.getId()); + return memberJwtTokenProvider.createAccessToken(member.getId()); } protected void 연애고사_필수_과목_질문_두개씩_생성() { diff --git a/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java b/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java index ef6eeec6..14f99252 100644 --- a/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java @@ -3,7 +3,7 @@ import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.infrastructure.auth.JwtTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtMemberTokenProvider; import com.atwoz.survey.application.survey.dto.SurveyCreateRequest; import com.atwoz.survey.ui.survey.dto.SurveyCreateResponse; import io.restassured.RestAssured; @@ -24,7 +24,7 @@ class SurveyControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private JwtTokenProvider jwtTokenProvider; + private MemberJwtMemberTokenProvider memberJwtTokenProvider; @Autowired private MemberRepository memberRepository; @@ -34,7 +34,7 @@ class SurveyControllerAcceptanceFixture extends IntegrationHelper { } protected String 토큰_생성(final Member member) { - return jwtTokenProvider.createTokenWithId(member.getId()); + return memberJwtTokenProvider.createAccessToken(member.getId()); } protected ExtractableResponse 연애고사_과목_생성_요청(final String url, final String token, final SurveyCreateRequest request) { From ebbfec811b53d023aa8984e82943d28ca916470f Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 17:54:15 +0900 Subject: [PATCH 57/66] =?UTF-8?q?docs:=20develop=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EC=B9=98=EC=99=80=20=EB=B3=80=ED=99=A9=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EB=AC=B8=EC=84=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/auth.adoc | 25 ------------------- src/docs/asciidoc/index.adoc | 2 +- src/docs/asciidoc/member.adoc | 16 +++++++++++- ...vider.java => MemberJwtTokenProvider.java} | 0 4 files changed, 16 insertions(+), 27 deletions(-) delete mode 100644 src/docs/asciidoc/auth.adoc rename src/main/java/com/atwoz/member/infrastructure/auth/{MemberJwtMemberTokenProvider.java => MemberJwtTokenProvider.java} (100%) diff --git a/src/docs/asciidoc/auth.adoc b/src/docs/asciidoc/auth.adoc deleted file mode 100644 index 6835b9ac..00000000 --- a/src/docs/asciidoc/auth.adoc +++ /dev/null @@ -1,25 +0,0 @@ -:toc: left -:source-highlighter: highlightjs -:sectlinks: -:toclevels: 2 -:sectlinks: -:sectnums: - -== Auth - -=== 로그인 - -==== 요청 (POST api/auth/login) - -include::{snippets}/auth-controller-web-mvc-test/do_signup/http-request.adoc[] -include::{snippets}/auth-controller-web-mvc-test/do_signup/request-fields.adoc[] - - -==== 응답 -include::{snippets}/auth-controller-web-mvc-test/do_signup/http-response.adoc[] -include::{snippets}/auth-controller-web-mvc-test/do_signup/request-fields.adoc[] - - - - - diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index 0b4143a2..4f2c51d8 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -5,8 +5,8 @@ :sectlinks: == atwoz Server API -* link:auth.html[회원 API] * link:member.html[회원 정보 API] +* link:admin.html[관리자 정보 API] * link:mission.html[미션 API] * link:membermissions.html[회원 미션 API] * link:survey.html[연애고사 API] diff --git a/src/docs/asciidoc/member.adoc b/src/docs/asciidoc/member.adoc index 18984df6..5f93bd22 100644 --- a/src/docs/asciidoc/member.adoc +++ b/src/docs/asciidoc/member.adoc @@ -7,11 +7,25 @@ == Member +=== 로그인 + +==== 요청 (POST api/auth/login) + +include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/http-request.adoc[] +include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/request-fields.adoc[] + + +==== 응답 +include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/http-response.adoc[] +include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/request-fields.adoc[] + + === 닉네임 중복 확인 (GET /api/members/nickname/existence) ==== 요청 -include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/request-headers.adoc[] include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/http-request.adoc[] +include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/request-headers.adoc[] +include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/path-parameters.adoc[] ==== 응답 include::{snippets}/member-controller-web-mvc-test/닉네임_중복_확인/http-response.adoc[] diff --git a/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtMemberTokenProvider.java b/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtTokenProvider.java similarity index 100% rename from src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtMemberTokenProvider.java rename to src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtTokenProvider.java From 58160b3bdfb06e92278f215ecceec9995ed2f856 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 17:54:48 +0900 Subject: [PATCH 58/66] =?UTF-8?q?refactor:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/infrastructure/auth/MemberJwtTokenProvider.java | 2 +- src/main/java/com/atwoz/memberlike/ui/MemberLikeController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtTokenProvider.java b/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtTokenProvider.java index 1df22539..50f44b75 100644 --- a/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtTokenProvider.java +++ b/src/main/java/com/atwoz/member/infrastructure/auth/MemberJwtTokenProvider.java @@ -24,7 +24,7 @@ @NoArgsConstructor @Component -public class MemberJwtMemberTokenProvider implements MemberTokenProvider { +public class MemberJwtTokenProvider implements MemberTokenProvider { private static final String ID = "id"; private static final String TOKEN_TYPE = "token type"; diff --git a/src/main/java/com/atwoz/memberlike/ui/MemberLikeController.java b/src/main/java/com/atwoz/memberlike/ui/MemberLikeController.java index 0537173f..c5415c41 100644 --- a/src/main/java/com/atwoz/memberlike/ui/MemberLikeController.java +++ b/src/main/java/com/atwoz/memberlike/ui/MemberLikeController.java @@ -1,6 +1,6 @@ package com.atwoz.memberlike.ui; -import com.atwoz.member.ui.auth.support.auth.AuthMember; +import com.atwoz.member.ui.auth.support.AuthMember; import com.atwoz.memberlike.application.MemberLikeQueryService; import com.atwoz.memberlike.application.MemberLikeService; import com.atwoz.memberlike.application.dto.MemberLikeCreateRequest; From 2df5b04d7bb0e8abeced3dd9c061c7d627093970 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 17:55:08 +0900 Subject: [PATCH 59/66] =?UTF-8?q?test:=20=ED=94=84=EB=A1=9C=EB=8D=95?= =?UTF-8?q?=EC=85=98=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=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 --- .../ui/MemberLikeControllerAcceptanceFixture.java | 6 +++--- .../MemberMissionsControllerAcceptanceFixture.java | 4 ++-- .../MemberSurveysControllerAcceptanceFixture.java | 4 ++-- .../survey/ui/survey/SurveyControllerAcceptanceFixture.java | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/atwoz/memberlike/ui/MemberLikeControllerAcceptanceFixture.java b/src/test/java/com/atwoz/memberlike/ui/MemberLikeControllerAcceptanceFixture.java index 6ca7bb56..214c1ee4 100644 --- a/src/test/java/com/atwoz/memberlike/ui/MemberLikeControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/memberlike/ui/MemberLikeControllerAcceptanceFixture.java @@ -3,7 +3,7 @@ import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.infrastructure.auth.JwtTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtTokenProvider; import com.atwoz.memberlike.application.dto.MemberLikeCreateRequest; import com.atwoz.memberlike.domain.MemberLike; import com.atwoz.memberlike.domain.MemberLikeRepository; @@ -27,7 +27,7 @@ public class MemberLikeControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private JwtTokenProvider jwtTokenProvider; + private MemberJwtTokenProvider jwtTokenProvider; @Autowired private MemberRepository memberRepository; @@ -43,7 +43,7 @@ public class MemberLikeControllerAcceptanceFixture extends IntegrationHelper { } protected String 토큰_생성(final Member member) { - return jwtTokenProvider.createTokenWithId(member.getId()); + return jwtTokenProvider.createAccessToken(member.getId()); } protected void 보낸_호감_목록_생성(final Long memberId) { diff --git a/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java b/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java index 45e6210b..2655c117 100644 --- a/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/mission/ui/membermission/MemberMissionsControllerAcceptanceFixture.java @@ -4,7 +4,7 @@ import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; import com.atwoz.member.domain.member.profile.physical.vo.Gender; -import com.atwoz.member.infrastructure.auth.MemberJwtMemberTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtTokenProvider; import com.atwoz.mission.domain.membermission.MemberMission; import com.atwoz.mission.domain.membermission.MemberMissions; import com.atwoz.mission.domain.membermission.MemberMissionsRepository; @@ -31,7 +31,7 @@ class MemberMissionsControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private MemberJwtMemberTokenProvider memberJwtTokenProvider; + private MemberJwtTokenProvider memberJwtTokenProvider; @Autowired private MemberRepository memberRepository; diff --git a/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java b/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java index 4796f01e..d0a2d0ea 100644 --- a/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/survey/ui/membersurvey/MemberSurveysControllerAcceptanceFixture.java @@ -3,7 +3,7 @@ import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.infrastructure.auth.MemberJwtMemberTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtTokenProvider; import com.atwoz.survey.application.membersurvey.dto.SurveySubmitRequest; import com.atwoz.survey.domain.survey.SurveyRepository; import com.atwoz.survey.infrastructure.membersurvey.dto.MemberSurveyResponse; @@ -30,7 +30,7 @@ class MemberSurveysControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private MemberJwtMemberTokenProvider memberJwtTokenProvider; + private MemberJwtTokenProvider memberJwtTokenProvider; @Autowired private MemberRepository memberRepository; diff --git a/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java b/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java index 14f99252..a60fa50a 100644 --- a/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java +++ b/src/test/java/com/atwoz/survey/ui/survey/SurveyControllerAcceptanceFixture.java @@ -3,7 +3,7 @@ import com.atwoz.helper.IntegrationHelper; import com.atwoz.member.domain.member.Member; import com.atwoz.member.domain.member.MemberRepository; -import com.atwoz.member.infrastructure.auth.MemberJwtMemberTokenProvider; +import com.atwoz.member.infrastructure.auth.MemberJwtTokenProvider; import com.atwoz.survey.application.survey.dto.SurveyCreateRequest; import com.atwoz.survey.ui.survey.dto.SurveyCreateResponse; import io.restassured.RestAssured; @@ -24,7 +24,7 @@ class SurveyControllerAcceptanceFixture extends IntegrationHelper { @Autowired - private MemberJwtMemberTokenProvider memberJwtTokenProvider; + private MemberJwtTokenProvider memberJwtTokenProvider; @Autowired private MemberRepository memberRepository; From c08ec60e24438b90b3f3827181be08e2a58f6ffa Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 17:55:24 +0900 Subject: [PATCH 60/66] =?UTF-8?q?docs:=20=EC=BF=A0=ED=82=A4,=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EB=A7=8C=EB=A3=8C=EC=8B=9C=EA=B0=84=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 6 +++++- src/test/resources/application.yml | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c80ea683..95b1ca85 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,9 +21,13 @@ jasypt: bean: jasyptEncryptor password: ${ENCRYPT_KEY} +cookie: + max-age: ENC(sHye+cf7fS9Y+RwQggf9Zw==) + jwt: secret: ENC(Tnm4CPIFdSiqmH67nWcDfRgaKmpSr4EvRJYZAYLiwOXazIY9aZnLBMlxQnKC2C0j10l6zkOEbRMKIa2W4u7DtIRjCC7QEzCSCdtm1NCEntKRybirDvUH8g==) - expiration-period: ENC(wtkJPr944E3bs6eMwjj4lQ==) + access-token-expiration-period: ENC(5HXDSpYbD6maLp2tpbtqZQ====) + refresh-token-expiration-period: ENC(a9S7VJiFmXcmKn0k5a9rXA==) mail: host: ENC(2PviuayFL6dKe91WydIBx81bpSBoI3FU) diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index d56ed96f..cb2efbb7 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -24,9 +24,14 @@ jasypt: encryptor: password: password +cookie: + max-age: 10000 + + jwt: secret: fortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortest - expiration-period: 10000 + access-token-expiration-period: 10000 + refresh-token-expiration-period: 10000 mail: host: smtp.blabla.com From c78c9ea3d5fdd168dabec23861b76445e47d4e2b Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:52:03 +0900 Subject: [PATCH 61/66] =?UTF-8?q?docs:=20develop=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EC=B9=98=EC=99=80=EC=9D=98=20=EB=B3=91=ED=95=A9=20=EC=B6=A9?= =?UTF-8?q?=EB=8F=8C=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20=EB=B0=9C=EC=83=9D?= =?UTF-8?q?=ED=95=9C=20=EB=AC=B8=EC=84=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/admin.adoc | 47 +++++++++++++++++++++++++++++++++++ src/docs/asciidoc/member.adoc | 4 +-- 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/docs/asciidoc/admin.adoc diff --git a/src/docs/asciidoc/admin.adoc b/src/docs/asciidoc/admin.adoc new file mode 100644 index 00000000..2988bd97 --- /dev/null +++ b/src/docs/asciidoc/admin.adoc @@ -0,0 +1,47 @@ +:toc: left +:source-highlighter: highlightjs +:sectlinks: +:toclevels: 2 +:sectlinks: +:sectnums: + +== Admin (POST api/admins/auth/sign-up) + +=== 회원가입 + +==== 요청 + +include::{snippets}/admin-auth-controller-test/관리자_회원가입/http-request.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_회원가입/response-fields.adoc[] + +==== 응답 + +include::{snippets}/admin-auth-controller-test/관리자_회원가입/http-response.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_회원가입/response-headers.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_회원가입/response-fields.adoc[] + +=== 로그인 + +==== 요청 + +include::{snippets}/admin-auth-controller-test/관리자_로그인/http-request.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_로그인/request-fields.adoc[] + +==== 응답 +include::{snippets}/admin-auth-controller-test/관리자_로그인/http-response.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_로그인/response-headers.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_로그인/response-fields.adoc[] + + +=== 액세스 토큰 재발행 + +==== 요청 + +include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/http-request.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/request-headers.adoc[] + +==== 응답 + +include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/response-fields.adoc[] + + diff --git a/src/docs/asciidoc/member.adoc b/src/docs/asciidoc/member.adoc index 5f93bd22..4e2e18a8 100644 --- a/src/docs/asciidoc/member.adoc +++ b/src/docs/asciidoc/member.adoc @@ -7,9 +7,9 @@ == Member -=== 로그인 +=== 로그인 (POST api/members/auth/login) -==== 요청 (POST api/auth/login) +==== 요청 include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/http-request.adoc[] include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/request-fields.adoc[] From b85000f2a862f46b55db738a7d838e124eb33fd7 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:52:30 +0900 Subject: [PATCH 62/66] =?UTF-8?q?docs:=20admin=20api=20=EB=AC=B8=EC=84=9C?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/admin.adoc | 18 +++++++----------- src/docs/asciidoc/member.adoc | 2 -- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/docs/asciidoc/admin.adoc b/src/docs/asciidoc/admin.adoc index 2988bd97..794ef6ab 100644 --- a/src/docs/asciidoc/admin.adoc +++ b/src/docs/asciidoc/admin.adoc @@ -5,25 +5,23 @@ :sectlinks: :sectnums: -== Admin (POST api/admins/auth/sign-up) +== Admin -=== 회원가입 +=== 회원 가입(POST api/admins/auth/sign-up) ==== 요청 - include::{snippets}/admin-auth-controller-test/관리자_회원가입/http-request.adoc[] -include::{snippets}/admin-auth-controller-test/관리자_회원가입/response-fields.adoc[] +include::{snippets}/admin-auth-controller-test/관리자_회원가입/request-fields.adoc[] ==== 응답 - include::{snippets}/admin-auth-controller-test/관리자_회원가입/http-response.adoc[] include::{snippets}/admin-auth-controller-test/관리자_회원가입/response-headers.adoc[] include::{snippets}/admin-auth-controller-test/관리자_회원가입/response-fields.adoc[] -=== 로그인 -==== 요청 +=== 로그인(POST api/admins/auth/login) +==== 요청 include::{snippets}/admin-auth-controller-test/관리자_로그인/http-request.adoc[] include::{snippets}/admin-auth-controller-test/관리자_로그인/request-fields.adoc[] @@ -33,15 +31,13 @@ include::{snippets}/admin-auth-controller-test/관리자_로그인/response-head include::{snippets}/admin-auth-controller-test/관리자_로그인/response-fields.adoc[] -=== 액세스 토큰 재발행 +=== 엑세스 토큰 재발행(POST api/admins/auth/access-token-regeneration) ==== 요청 - include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/http-request.adoc[] include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/request-headers.adoc[] ==== 응답 - +include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/http-response.adoc[] include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/response-fields.adoc[] - diff --git a/src/docs/asciidoc/member.adoc b/src/docs/asciidoc/member.adoc index 4e2e18a8..b0bab758 100644 --- a/src/docs/asciidoc/member.adoc +++ b/src/docs/asciidoc/member.adoc @@ -10,11 +10,9 @@ === 로그인 (POST api/members/auth/login) ==== 요청 - include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/http-request.adoc[] include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/request-fields.adoc[] - ==== 응답 include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/http-response.adoc[] include::{snippets}/member-auth-controller-web-mvc-test/유저_로그인/request-fields.adoc[] From bd171df10bf659aa810afb49251c2d0a2e1ef4ec Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 16:54:15 +0900 Subject: [PATCH 63/66] =?UTF-8?q?docs:=20=ED=86=A0=ED=81=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=BF=A0=ED=82=A4=20=EB=A7=8C=EB=A3=8C=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 6 +++--- src/test/resources/application.yml | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 95b1ca85..74125ae3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -22,12 +22,12 @@ jasypt: password: ${ENCRYPT_KEY} cookie: - max-age: ENC(sHye+cf7fS9Y+RwQggf9Zw==) + max-age: ENC(LZMhucgSTnZxWG8aPhgclw==) jwt: secret: ENC(Tnm4CPIFdSiqmH67nWcDfRgaKmpSr4EvRJYZAYLiwOXazIY9aZnLBMlxQnKC2C0j10l6zkOEbRMKIa2W4u7DtIRjCC7QEzCSCdtm1NCEntKRybirDvUH8g==) - access-token-expiration-period: ENC(5HXDSpYbD6maLp2tpbtqZQ====) - refresh-token-expiration-period: ENC(a9S7VJiFmXcmKn0k5a9rXA==) + access-token-expiration-period: ENC(46U7S/gH1lH6kpaOwhVaow==) + refresh-token-expiration-period: ENC(kb9YVXMB9HqUuxoxcnMHXw==) mail: host: ENC(2PviuayFL6dKe91WydIBx81bpSBoI3FU) diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index cb2efbb7..20c85494 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -27,7 +27,6 @@ jasypt: cookie: max-age: 10000 - jwt: secret: fortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortestfortest access-token-expiration-period: 10000 From edc1577279e799bebc0123de15b1b5640904cb44 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 18:20:41 +0900 Subject: [PATCH 64/66] =?UTF-8?q?docs:=20=EA=B3=B5=EB=B0=B1=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/admin.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/docs/asciidoc/admin.adoc b/src/docs/asciidoc/admin.adoc index 794ef6ab..07e7ef82 100644 --- a/src/docs/asciidoc/admin.adoc +++ b/src/docs/asciidoc/admin.adoc @@ -40,4 +40,3 @@ include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발 ==== 응답 include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/http-response.adoc[] include::{snippets}/admin-auth-controller-test/관리자_액세스_토큰_재발행/response-fields.adoc[] - From 0741feb8dee605f363d27c214cca15d4895fe1d3 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 20:20:00 +0900 Subject: [PATCH 65/66] =?UTF-8?q?refactor:=20dto=EC=97=90=20validation=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 --- .../application/auth/dto/AdminProfileSignUpRequest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java b/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java index 112af4ab..77eab4c8 100644 --- a/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java +++ b/src/main/java/com/atwoz/admin/application/auth/dto/AdminProfileSignUpRequest.java @@ -1,7 +1,12 @@ package com.atwoz.admin.application.auth.dto; +import jakarta.validation.constraints.NotBlank; + public record AdminProfileSignUpRequest( + @NotBlank(message = "이름을 입력해주세요.") String name, + + @NotBlank(message = "전화번호를 입력해주세요.") String phoneNumber ) { } From 15e5a9330e18f5e7483bea82dab5fbab410c54d9 Mon Sep 17 00:00:00 2001 From: eom-tae-in Date: Sat, 6 Jul 2024 20:20:14 +0900 Subject: [PATCH 66/66] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java b/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java index 034763e5..8f162f8a 100644 --- a/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java +++ b/src/main/java/com/atwoz/admin/ui/auth/AdminAuthController.java @@ -53,7 +53,6 @@ public ResponseEntity login( @PostMapping("/access-token-regeneration") public ResponseEntity reGenerateAccessToken( @AdminRefreshToken final String refreshToken) { - System.out.println("hihi : " + refreshToken); return ResponseEntity.ok(adminAuthService.reGenerateAccessToken(refreshToken)); }