From 0a832ae5c0c089060e469617b687aa8d8cdc1192 Mon Sep 17 00:00:00 2001 From: kseysh Date: Thu, 4 Jul 2024 23:26:53 +0900 Subject: [PATCH 01/43] =?UTF-8?q?feat=20-=20#171=20AdminController=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20orderAdminLogin=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmh/domain/admin/controller/AdminApi.java | 11 +++++++ .../admin/controller/AdminController.java | 29 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java create mode 100644 src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java new file mode 100644 index 00000000..ac863117 --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java @@ -0,0 +1,11 @@ +package sopt.org.hmh.domain.admin.controller; + +import io.swagger.v3.oas.annotations.Operation; +import org.springframework.http.ResponseEntity; +import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; +import sopt.org.hmh.global.common.response.BaseResponse; + +public interface AdminApi { + @Operation(summary = "소셜 로그인") + ResponseEntity> orderAdminLogin(AdminLoginRequest request); +} diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java new file mode 100644 index 00000000..5bdaae4e --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java @@ -0,0 +1,29 @@ +package sopt.org.hmh.domain.admin.controller; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +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; +import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; +import sopt.org.hmh.domain.admin.exception.AdminSuccess; +import sopt.org.hmh.domain.admin.service.AdminFacade; +import sopt.org.hmh.global.common.response.BaseResponse; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/admin") +public class AdminController implements AdminApi{ + @Override + @PostMapping("/login") + public ResponseEntity> orderAdminLogin( + @RequestBody @Valid final AdminLoginRequest request) + { + return ResponseEntity + .status(AdminSuccess.ADMIN_LOGIN_SUCCESS.getHttpStatus()) + .body(BaseResponse.success(AdminSuccess.ADMIN_LOGIN_SUCCESS, AdminFacade.adminLogin(request.authCode()))); + } + +} From be36779d042031becab1207636c76abb39863cb4 Mon Sep 17 00:00:00 2001 From: kseysh Date: Thu, 4 Jul 2024 23:27:15 +0900 Subject: [PATCH 02/43] =?UTF-8?q?feat=20-=20#171=20Admin=20exception=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/admin/exception/AdminError.java | 31 +++++++++++++++++++ .../admin/exception/AdminException.java | 11 +++++++ .../domain/admin/exception/AdminSuccess.java | 31 +++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 src/main/java/sopt/org/hmh/domain/admin/exception/AdminError.java create mode 100644 src/main/java/sopt/org/hmh/domain/admin/exception/AdminException.java create mode 100644 src/main/java/sopt/org/hmh/domain/admin/exception/AdminSuccess.java diff --git a/src/main/java/sopt/org/hmh/domain/admin/exception/AdminError.java b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminError.java new file mode 100644 index 00000000..c078a957 --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminError.java @@ -0,0 +1,31 @@ +package sopt.org.hmh.domain.admin.exception; + +import lombok.AllArgsConstructor; +import org.springframework.http.HttpStatus; +import sopt.org.hmh.global.common.exception.base.ErrorBase; + +@AllArgsConstructor +public enum AdminError implements ErrorBase { + + // 401 UNAUTHORIZED + INVALID_PASSWORD(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다."), + ; + + private final HttpStatus status; + private final String errorMessage; + + @Override + public int getHttpStatusCode() { + return this.status.value(); + } + + @Override + public HttpStatus getHttpStatus() { + return this.status; + } + + @Override + public String getErrorMessage() { + return this.errorMessage; + } +} \ No newline at end of file diff --git a/src/main/java/sopt/org/hmh/domain/admin/exception/AdminException.java b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminException.java new file mode 100644 index 00000000..0a54ebeb --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminException.java @@ -0,0 +1,11 @@ +package sopt.org.hmh.domain.admin.exception; + +import sopt.org.hmh.domain.auth.exception.AuthError; +import sopt.org.hmh.global.common.exception.base.ExceptionBase; + +public class AdminException extends ExceptionBase { + + public AdminException(AuthError errorBase) { + super(errorBase); + } +} diff --git a/src/main/java/sopt/org/hmh/domain/admin/exception/AdminSuccess.java b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminSuccess.java new file mode 100644 index 00000000..147dcd22 --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminSuccess.java @@ -0,0 +1,31 @@ +package sopt.org.hmh.domain.admin.exception; + +import lombok.AllArgsConstructor; +import org.springframework.http.HttpStatus; +import sopt.org.hmh.global.common.exception.base.SuccessBase; + +@AllArgsConstructor +public enum AdminSuccess implements SuccessBase { + + // 200 OK + ADMIN_LOGIN_SUCCESS(HttpStatus.OK, "관리자 로그인에 성공했습니다."), + ; + + private final HttpStatus status; + private final String successMessage; + + @Override + public int getHttpStatusCode() { + return this.status.value(); + } + + @Override + public HttpStatus getHttpStatus() { + return this.status; + } + + @Override + public String getSuccessMessage() { + return this.successMessage; + } +} From 09e04d8e834f299dc877eb06696f8b23d01964e0 Mon Sep 17 00:00:00 2001 From: kseysh Date: Thu, 4 Jul 2024 23:27:29 +0900 Subject: [PATCH 03/43] =?UTF-8?q?feat=20-=20#171=20AdminLoginRequest=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 --- .../hmh/domain/admin/dto/request/AdminLoginRequest.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminLoginRequest.java diff --git a/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminLoginRequest.java b/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminLoginRequest.java new file mode 100644 index 00000000..a280bdab --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminLoginRequest.java @@ -0,0 +1,7 @@ +package sopt.org.hmh.domain.admin.dto.request; + +public record AdminLoginRequest( + String authCode +) { + +} From 22eae0c3e121302599dc3175a46262db62fd213f Mon Sep 17 00:00:00 2001 From: kseysh Date: Thu, 4 Jul 2024 23:48:17 +0900 Subject: [PATCH 04/43] =?UTF-8?q?modify=20-=20#171=20Admin=20exception=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EB=A9=94=EC=8B=9C=EC=A7=80=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 --- .../java/sopt/org/hmh/domain/admin/exception/AdminError.java | 2 +- .../sopt/org/hmh/domain/admin/exception/AdminException.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/sopt/org/hmh/domain/admin/exception/AdminError.java b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminError.java index c078a957..61bdcb71 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/exception/AdminError.java +++ b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminError.java @@ -8,7 +8,7 @@ public enum AdminError implements ErrorBase { // 401 UNAUTHORIZED - INVALID_PASSWORD(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다."), + INVALID_ADMIN_AUTH_CODE(HttpStatus.UNAUTHORIZED, "관리자 인증 번호가 일치하지 않습니다."), ; private final HttpStatus status; diff --git a/src/main/java/sopt/org/hmh/domain/admin/exception/AdminException.java b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminException.java index 0a54ebeb..7c0ecfd8 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/exception/AdminException.java +++ b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminException.java @@ -1,11 +1,10 @@ package sopt.org.hmh.domain.admin.exception; -import sopt.org.hmh.domain.auth.exception.AuthError; import sopt.org.hmh.global.common.exception.base.ExceptionBase; public class AdminException extends ExceptionBase { - public AdminException(AuthError errorBase) { + public AdminException(AdminError errorBase) { super(errorBase); } } From b898776c90f68968b2ab7635ab9284eccfbdd9ea Mon Sep 17 00:00:00 2001 From: kseysh Date: Thu, 4 Jul 2024 23:49:49 +0900 Subject: [PATCH 05/43] =?UTF-8?q?fix=20-=20#171=20=EC=9E=98=EB=AA=BB=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98=ED=95=9C=20controller=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmh/domain/admin/controller/AdminController.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java index 5bdaae4e..868b140a 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java @@ -15,15 +15,18 @@ @RestController @RequiredArgsConstructor @RequestMapping("/api/v1/admin") -public class AdminController implements AdminApi{ +public class AdminController implements AdminApi { + + private final AdminFacade adminFacade; + @Override @PostMapping("/login") public ResponseEntity> orderAdminLogin( - @RequestBody @Valid final AdminLoginRequest request) - { + @RequestBody @Valid final AdminLoginRequest request) { return ResponseEntity .status(AdminSuccess.ADMIN_LOGIN_SUCCESS.getHttpStatus()) - .body(BaseResponse.success(AdminSuccess.ADMIN_LOGIN_SUCCESS, AdminFacade.adminLogin(request.authCode()))); + .body(BaseResponse.success(AdminSuccess.ADMIN_LOGIN_SUCCESS, + adminFacade.adminLogin(request.authCode()))); } } From 9632cceb480cec1beaf58528602d864036be9fb7 Mon Sep 17 00:00:00 2001 From: kseysh Date: Thu, 4 Jul 2024 23:50:07 +0900 Subject: [PATCH 06/43] =?UTF-8?q?feat=20-=20#171=20AdminTokenResponse=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmh/domain/admin/dto/response/AdminTokenResponse.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/main/java/sopt/org/hmh/domain/admin/dto/response/AdminTokenResponse.java diff --git a/src/main/java/sopt/org/hmh/domain/admin/dto/response/AdminTokenResponse.java b/src/main/java/sopt/org/hmh/domain/admin/dto/response/AdminTokenResponse.java new file mode 100644 index 00000000..8c6458a1 --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/dto/response/AdminTokenResponse.java @@ -0,0 +1,6 @@ +package sopt.org.hmh.domain.admin.dto.response; + +public record AdminTokenResponse( + String accessToken +) { +} From 94d3c5f63dcb8713903be3e57ac5b67bc407f33b Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 00:14:52 +0900 Subject: [PATCH 07/43] =?UTF-8?q?feat=20-=20#171=20Admin=20Token=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/org/hmh/global/auth/jwt/JwtGenerator.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java index 5da40648..1c1758db 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java @@ -22,6 +22,8 @@ public class JwtGenerator { private Long ACCESS_TOKEN_EXPIRATION_TIME; @Value("${jwt.refresh-token-expiration-time}") private Long REFRESH_TOKEN_EXPIRATION_TIME; + @Value("${jwt.admin-access-token-expiration-time}") + private Long ADMIN_ACCESS_TOKEN_EXPIRATION_TIME; public String generateToken(Long userId, boolean isRefreshToken) { final Date now = generateNowDate(); @@ -36,6 +38,18 @@ public String generateToken(Long userId, boolean isRefreshToken) { .compact(); } + public String generateAdminToken() { + final Date now = generateNowDate(); + + return Jwts.builder() + .setHeaderParam(Header.TYPE, Header.JWT_TYPE) + .setSubject("ADMIN") + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + ADMIN_ACCESS_TOKEN_EXPIRATION_TIME)) + .signWith(getSigningKey()) + .compact(); + } + public JwtParser getJwtParser() { return Jwts.parserBuilder() .setSigningKey(getSigningKey()) From a746d7873a1c1414461e0abda36d23ed51fc1eb2 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 00:15:11 +0900 Subject: [PATCH 08/43] =?UTF-8?q?feat=20-=20#171=20JwtProvider=EC=97=90?= =?UTF-8?q?=EC=84=9C=20Admin=20Token=20=EC=A0=9C=EA=B3=B5=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java index a1933e0f..b55d5ac7 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java @@ -21,4 +21,8 @@ public Long getSubject(String token) { .getBody() .getSubject()); } + + public String issueAdminToken() { + return jwtGenerator.generateAdminToken(); + } } \ No newline at end of file From a18180234969de6c07571687a6eae2f1447a12fb Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 00:18:06 +0900 Subject: [PATCH 09/43] =?UTF-8?q?feat=20-=20#171=20JwtConstants=EC=97=90?= =?UTF-8?q?=EC=84=9C=20ADMIN=5FROLE=20=EC=83=81=EC=88=98=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/hmh/global/auth/jwt/JwtConstants.java | 1 + .../org/hmh/global/auth/jwt/JwtValidator.java | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtConstants.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtConstants.java index 792d2ee9..4e5ee2b8 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtConstants.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtConstants.java @@ -8,4 +8,5 @@ public abstract class JwtConstants { public static final String AUTHORIZATION = "Authorization"; public static final String BEARER = "Bearer "; public static final String CHARACTER_ENCODING = "UTF-8"; + public static final String ADMIN_ROLE = "ADMIN"; } \ No newline at end of file diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtValidator.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtValidator.java index b8ed8b24..03f35758 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtValidator.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtValidator.java @@ -1,6 +1,10 @@ package sopt.org.hmh.global.auth.jwt; +import static sopt.org.hmh.global.auth.jwt.JwtConstants.ADMIN_ROLE; + +import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jws; import io.jsonwebtoken.JwtParser; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -32,8 +36,15 @@ public void validateRefreshToken(String refreshToken) { } } - private void parseToken(String token) { + private Jws parseToken(String token) { JwtParser jwtParser = jwtGenerator.getJwtParser(); - jwtParser.parseClaimsJws(token); + return jwtParser.parseClaimsJws(token); + } + + public void validateAdminToken(String token) { + String subject = parseToken(token).getBody().getSubject(); + if (!subject.equals(ADMIN_ROLE)) { + throw new JwtException(JwtError.INVALID_ADMIN_TOKEN); + } } } \ No newline at end of file From 53cec3bbf89837b20d5723843bc3714bbcfefb94 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 15:21:11 +0900 Subject: [PATCH 10/43] =?UTF-8?q?feat=20-=20#171=20JwtError=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/sopt/org/hmh/global/auth/jwt/exception/JwtError.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/exception/JwtError.java b/src/main/java/sopt/org/hmh/global/auth/jwt/exception/JwtError.java index 845d98a6..9006d88c 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/exception/JwtError.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/exception/JwtError.java @@ -26,11 +26,14 @@ public enum JwtError implements ErrorBase { INVALID_IDENTITY_TOKEN_CLAIMS(HttpStatus.UNAUTHORIZED, "유효하지 않은 애플 아이덴티티 토큰 클레임입니다."), UNABLE_TO_CREATE_APPLE_PUBLIC_KEY(HttpStatus.UNAUTHORIZED, "애플 로그인 중 퍼블릭 키 생성에 문제가 발생했습니다."), + INVALID_ADMIN_TOKEN(HttpStatus.UNAUTHORIZED, "유효하지 않은 관리자 액세스 토큰입니다."), + // 404 NOT FOUND NOT_FOUND_REFRESH_TOKEN_ERROR(HttpStatus.NOT_FOUND, "존재하지 않는 리프레시 토큰입니다."), // 500 INTERNAL ERROR INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "서버 내부 오류입니다."); + private final HttpStatus status; private final String errorMessage; From d4e52a78248acc776962500e206caa20850d5d3b Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 15:21:31 +0900 Subject: [PATCH 11/43] =?UTF-8?q?feat=20-=20#171=20admin=20token=20?= =?UTF-8?q?=EB=B0=9C=EA=B8=89=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java b/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java index 64e2f6b9..e590c1f4 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java @@ -34,4 +34,8 @@ public TokenResponse issueToken(Long userId) { return jwtProvider.issueToken(userId); } + public String issueAdminToken() { + return jwtProvider.issueAdminToken(); + } + } From ecd41cf5ff951ccdcd5cc83680b021afe712dec8 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 15:34:35 +0900 Subject: [PATCH 12/43] =?UTF-8?q?feat=20-=20#171=20SecurityConfig=EC=97=90?= =?UTF-8?q?=20=EA=B4=80=EB=A6=AC=EC=9E=90=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?url=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/sopt/org/hmh/global/config/SecurityConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/sopt/org/hmh/global/config/SecurityConfig.java b/src/main/java/sopt/org/hmh/global/config/SecurityConfig.java index 5c7e1203..7a8a4908 100644 --- a/src/main/java/sopt/org/hmh/global/config/SecurityConfig.java +++ b/src/main/java/sopt/org/hmh/global/config/SecurityConfig.java @@ -38,6 +38,7 @@ public class SecurityConfig { // Authentication "/api/v1/user/login", + "/api/v1/admin/login", "/api/v1/user/reissue", "/api/v1/user/signup", "/api/v1/user/social/token/kakao", From 39dc44fc0ed91eb10d479d79d4907fe8390df822 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 15:35:26 +0900 Subject: [PATCH 13/43] =?UTF-8?q?refactor=20-=20#171=20=ED=95=98=EB=93=9C?= =?UTF-8?q?=20=EC=BD=94=EB=94=A9=EB=90=9C=20String=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java index 1c1758db..1b85849e 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java @@ -1,5 +1,7 @@ package sopt.org.hmh.global.auth.jwt; +import static sopt.org.hmh.global.auth.jwt.JwtConstants.ADMIN_ROLE; + import io.jsonwebtoken.Header; import io.jsonwebtoken.JwtParser; import io.jsonwebtoken.Jwts; @@ -43,7 +45,7 @@ public String generateAdminToken() { return Jwts.builder() .setHeaderParam(Header.TYPE, Header.JWT_TYPE) - .setSubject("ADMIN") + .setSubject(ADMIN_ROLE) .setIssuedAt(now) .setExpiration(new Date(now.getTime() + ADMIN_ACCESS_TOKEN_EXPIRATION_TIME)) .signWith(getSigningKey()) From c10203798d6f6085ebdc6f63b05aac42aeae35e8 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 15:36:12 +0900 Subject: [PATCH 14/43] =?UTF-8?q?feat=20-=20#171=20admin=20facade=EB=A5=BC?= =?UTF-8?q?=20=EC=9D=B4=EC=9A=A9=ED=95=B4=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmh/domain/admin/service/AdminFacade.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java diff --git a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java new file mode 100644 index 00000000..8c815ed2 --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java @@ -0,0 +1,30 @@ +package sopt.org.hmh.domain.admin.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; +import sopt.org.hmh.domain.admin.exception.AdminError; +import sopt.org.hmh.domain.admin.exception.AdminException; +import sopt.org.hmh.global.auth.jwt.TokenService; + +@Service +@RequiredArgsConstructor +public class AdminFacade { + + @Value("${jwt.admin-auth-code}") + private String adminAuthCode; + + private final TokenService tokenService; + + public AdminTokenResponse adminLogin(String authCode) { + validateAdminAuthCode(authCode); + return new AdminTokenResponse(tokenService.issueAdminToken()); + } + + private void validateAdminAuthCode(String authCode) { + if (!adminAuthCode.equals(authCode)) { + throw new AdminException(AdminError.INVALID_ADMIN_AUTH_CODE); + } + } +} From e5c7af4cec763f8f0f4164d6f4c70103a8a4bb43 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 15:42:56 +0900 Subject: [PATCH 15/43] =?UTF-8?q?feat=20-=20#171=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EC=97=90=20=EC=99=80=EC=9D=BC=EB=93=9C=20?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=EC=A7=80=EC=96=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/sopt/org/hmh/domain/admin/controller/AdminApi.java | 3 ++- .../sopt/org/hmh/domain/admin/controller/AdminController.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java index ac863117..17b7c311 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java @@ -3,9 +3,10 @@ import io.swagger.v3.oas.annotations.Operation; import org.springframework.http.ResponseEntity; import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; +import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.global.common.response.BaseResponse; public interface AdminApi { @Operation(summary = "소셜 로그인") - ResponseEntity> orderAdminLogin(AdminLoginRequest request); + ResponseEntity> orderAdminLogin(AdminLoginRequest request); } diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java index 868b140a..ba075c42 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; +import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.domain.admin.exception.AdminSuccess; import sopt.org.hmh.domain.admin.service.AdminFacade; import sopt.org.hmh.global.common.response.BaseResponse; @@ -21,7 +22,7 @@ public class AdminController implements AdminApi { @Override @PostMapping("/login") - public ResponseEntity> orderAdminLogin( + public ResponseEntity> orderAdminLogin( @RequestBody @Valid final AdminLoginRequest request) { return ResponseEntity .status(AdminSuccess.ADMIN_LOGIN_SUCCESS.getHttpStatus()) From 0d0980e5cbfa1ef8480804668165b8089dba02e8 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 15:43:43 +0900 Subject: [PATCH 16/43] =?UTF-8?q?feat=20-=20#171=20=EC=A6=89=EC=8B=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=EB=A5=BC=20=EC=82=AD=EC=A0=9C=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/sopt/org/hmh/domain/user/service/UserService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/sopt/org/hmh/domain/user/service/UserService.java b/src/main/java/sopt/org/hmh/domain/user/service/UserService.java index 12e2bfa9..ac1719e0 100644 --- a/src/main/java/sopt/org/hmh/domain/user/service/UserService.java +++ b/src/main/java/sopt/org/hmh/domain/user/service/UserService.java @@ -100,4 +100,9 @@ public IsLockTodayResponse checkIsTodayLock(Long userId, LocalDate lockCheckDate LocalDate userRecentLockDate = this.findByIdOrThrowException(userId).getRecentLockDate(); return new IsLockTodayResponse(lockCheckDate.equals(userRecentLockDate)); } + + @Transactional + public void withdrawImmediately(Long userId) { + userRepository.deleteById(userId); + } } \ No newline at end of file From 46fb3a51035bf3ca5b58cb5eb2e3ca67c5dea804 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 16:51:14 +0900 Subject: [PATCH 17/43] =?UTF-8?q?feat=20-=20#171=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=EC=9C=A0=EC=A0=80=20=EC=A6=89=EC=8B=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20controller=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmh/domain/admin/controller/AdminController.java | 11 ++++++++++- .../org/hmh/domain/admin/exception/AdminSuccess.java | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java index ba075c42..c7fd4a59 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java @@ -3,6 +3,7 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -23,11 +24,19 @@ public class AdminController implements AdminApi { @Override @PostMapping("/login") public ResponseEntity> orderAdminLogin( - @RequestBody @Valid final AdminLoginRequest request) { + @RequestBody final AdminLoginRequest request) { return ResponseEntity .status(AdminSuccess.ADMIN_LOGIN_SUCCESS.getHttpStatus()) .body(BaseResponse.success(AdminSuccess.ADMIN_LOGIN_SUCCESS, adminFacade.adminLogin(request.authCode()))); } + @Override + @DeleteMapping("/user") + public ResponseEntity orderAdminWithdrawImmediately(@RequestBody @Valid final Long userId) { + adminFacade.withdrawImmediately(userId); + return ResponseEntity + .noContent() + .build(); + } } diff --git a/src/main/java/sopt/org/hmh/domain/admin/exception/AdminSuccess.java b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminSuccess.java index 147dcd22..fc9ba43c 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/exception/AdminSuccess.java +++ b/src/main/java/sopt/org/hmh/domain/admin/exception/AdminSuccess.java @@ -9,6 +9,9 @@ public enum AdminSuccess implements SuccessBase { // 200 OK ADMIN_LOGIN_SUCCESS(HttpStatus.OK, "관리자 로그인에 성공했습니다."), + + // 204 NO CONTENT + ADMIN_WITHDRAW_IMMEDIATELY_SUCCESS(HttpStatus.NO_CONTENT, "관리자 권한으로 유저 즉시 삭제에 성공했습니다."), ; private final HttpStatus status; From 3e606ebc9eb46ba097f660f2778392bfe6f9a657 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 16:51:30 +0900 Subject: [PATCH 18/43] =?UTF-8?q?feat=20-=20#171=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=EC=9C=A0=EC=A0=80=20=EC=A6=89=EC=8B=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20AdminApi=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/sopt/org/hmh/domain/admin/controller/AdminApi.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java index 17b7c311..90c7fda5 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java @@ -7,6 +7,9 @@ import sopt.org.hmh.global.common.response.BaseResponse; public interface AdminApi { - @Operation(summary = "소셜 로그인") + @Operation(summary = "관리자 로그인") ResponseEntity> orderAdminLogin(AdminLoginRequest request); + + @Operation(summary = "관리자 권한으로 유저 즉시 삭제") + ResponseEntity orderAdminWithdrawImmediately(Long userId); } From 2b3df313bf69b5c35e41e40fb7b44eb2fdb233b0 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 16:52:06 +0900 Subject: [PATCH 19/43] =?UTF-8?q?feat=20-=20#171=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=EC=9C=A0=EC=A0=80=20=EC=A6=89=EC=8B=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20service=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/sopt/org/hmh/domain/admin/service/AdminFacade.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java index 8c815ed2..053db66c 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java +++ b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java @@ -6,6 +6,7 @@ import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.domain.admin.exception.AdminError; import sopt.org.hmh.domain.admin.exception.AdminException; +import sopt.org.hmh.domain.user.service.UserService; import sopt.org.hmh.global.auth.jwt.TokenService; @Service @@ -15,6 +16,7 @@ public class AdminFacade { @Value("${jwt.admin-auth-code}") private String adminAuthCode; + private final UserService userService; private final TokenService tokenService; public AdminTokenResponse adminLogin(String authCode) { @@ -27,4 +29,8 @@ private void validateAdminAuthCode(String authCode) { throw new AdminException(AdminError.INVALID_ADMIN_AUTH_CODE); } } + + public void withdrawImmediately(Long userId) { + userService.withdrawImmediately(userId); + } } From ea3eb9e220257c38cc7dae65c67fcad4d192485d Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 21:13:05 +0900 Subject: [PATCH 20/43] =?UTF-8?q?modify=20-=20#171=20doAuthentication?= =?UTF-8?q?=EC=8B=9C=EC=97=90=20subject=EB=A5=BC=20String=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/hmh/global/auth/UserIdArgumentResolver.java | 8 +++++--- .../sopt/org/hmh/global/auth/jwt/JwtGenerator.java | 4 ++-- .../sopt/org/hmh/global/auth/jwt/JwtProvider.java | 12 ++++++------ .../sopt/org/hmh/global/auth/jwt/TokenService.java | 6 +++--- .../auth/security/JwtAuthenticationFilter.java | 4 ++-- .../hmh/global/auth/security/UserAuthentication.java | 4 ++-- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/main/java/sopt/org/hmh/global/auth/UserIdArgumentResolver.java b/src/main/java/sopt/org/hmh/global/auth/UserIdArgumentResolver.java index 87c5dd1e..0318b423 100644 --- a/src/main/java/sopt/org/hmh/global/auth/UserIdArgumentResolver.java +++ b/src/main/java/sopt/org/hmh/global/auth/UserIdArgumentResolver.java @@ -21,9 +21,11 @@ public boolean supportsParameter(MethodParameter parameter) { } @Override - public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { - return SecurityContextHolder.getContext() + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + return Long.parseLong(SecurityContextHolder.getContext() .getAuthentication() - .getPrincipal(); + .getPrincipal() + .toString()); } } \ No newline at end of file diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java index 1b85849e..f30eba8e 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtGenerator.java @@ -27,13 +27,13 @@ public class JwtGenerator { @Value("${jwt.admin-access-token-expiration-time}") private Long ADMIN_ACCESS_TOKEN_EXPIRATION_TIME; - public String generateToken(Long userId, boolean isRefreshToken) { + public String generateToken(String subjectId, boolean isRefreshToken) { final Date now = generateNowDate(); final Date expiration = generateExpirationDate(isRefreshToken, now); return Jwts.builder() .setHeaderParam(Header.TYPE, Header.JWT_TYPE) - .setSubject(String.valueOf(userId)) + .setSubject(subjectId) .setIssuedAt(now) .setExpiration(expiration) .signWith(getSigningKey()) diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java index b55d5ac7..70c5babc 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java @@ -10,16 +10,16 @@ public class JwtProvider { private final JwtGenerator jwtGenerator; - public TokenResponse issueToken(Long userId) { - return new TokenResponse(jwtGenerator.generateToken(userId, false), - jwtGenerator.generateToken(userId, true)); + public TokenResponse issueToken(String subjectId) { + return new TokenResponse(jwtGenerator.generateToken(subjectId, false), + jwtGenerator.generateToken(subjectId, true)); } - public Long getSubject(String token) { + public String getSubject(String token) { JwtParser jwtParser = jwtGenerator.getJwtParser(); - return Long.valueOf(jwtParser.parseClaimsJws(token) + return jwtParser.parseClaimsJws(token) .getBody() - .getSubject()); + .getSubject(); } public String issueAdminToken() { diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java b/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java index e590c1f4..9abc4f36 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java @@ -17,7 +17,7 @@ public class TokenService { @Transactional public ReissueResponse reissueToken(String refreshToken) { String parsedRefreshToken = parseTokenString(refreshToken); - Long userId = jwtProvider.getSubject(parsedRefreshToken); + String userId = jwtProvider.getSubject(parsedRefreshToken); jwtValidator.validateRefreshToken(parsedRefreshToken); return ReissueResponse.of(jwtProvider.issueToken(userId)); } @@ -30,8 +30,8 @@ private String parseTokenString(String tokenString) { return parsedTokens[1]; } - public TokenResponse issueToken(Long userId) { - return jwtProvider.issueToken(userId); + public TokenResponse issueToken(String subjectId) { + return jwtProvider.issueToken(subjectId); } public String issueAdminToken() { diff --git a/src/main/java/sopt/org/hmh/global/auth/security/JwtAuthenticationFilter.java b/src/main/java/sopt/org/hmh/global/auth/security/JwtAuthenticationFilter.java index cffc553e..fe360d0c 100644 --- a/src/main/java/sopt/org/hmh/global/auth/security/JwtAuthenticationFilter.java +++ b/src/main/java/sopt/org/hmh/global/auth/security/JwtAuthenticationFilter.java @@ -41,8 +41,8 @@ private String getAccessToken(HttpServletRequest request) { throw new JwtException(JwtError.INVALID_ACCESS_TOKEN); } - private void doAuthentication(HttpServletRequest request, Long userId) { - UserAuthentication authentication = createUserAuthentication(userId); + private void doAuthentication(HttpServletRequest request, String subjectId) { + UserAuthentication authentication = createUserAuthentication(subjectId); createAndSetWebAuthenticationDetails(request, authentication); SecurityContext securityContext = SecurityContextHolder.getContext(); securityContext.setAuthentication(authentication); diff --git a/src/main/java/sopt/org/hmh/global/auth/security/UserAuthentication.java b/src/main/java/sopt/org/hmh/global/auth/security/UserAuthentication.java index 7f5d5983..e3be2a1b 100644 --- a/src/main/java/sopt/org/hmh/global/auth/security/UserAuthentication.java +++ b/src/main/java/sopt/org/hmh/global/auth/security/UserAuthentication.java @@ -10,7 +10,7 @@ private UserAuthentication(Object principal, Object credentials, Collection Date: Fri, 5 Jul 2024 21:14:27 +0900 Subject: [PATCH 21/43] =?UTF-8?q?modify=20-=20#171=20doAuthentication?= =?UTF-8?q?=EC=8B=9C=EC=97=90=20subject=EB=A5=BC=20String=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/sopt/org/hmh/domain/auth/service/AuthFacade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/sopt/org/hmh/domain/auth/service/AuthFacade.java b/src/main/java/sopt/org/hmh/domain/auth/service/AuthFacade.java index fbc2725a..5e314308 100644 --- a/src/main/java/sopt/org/hmh/domain/auth/service/AuthFacade.java +++ b/src/main/java/sopt/org/hmh/domain/auth/service/AuthFacade.java @@ -73,7 +73,7 @@ private LoginResponse performLogin(String socialAccessToken, SocialPlatform soci kakaoLoginService.updateUserInfoByKakao(loginUser, socialAccessToken); } Long userId = loginUser.getId(); - return new LoginResponse(userId, tokenService.issueToken(userId)); + return new LoginResponse(userId, tokenService.issueToken(userId.toString())); } public SocialAccessTokenResponse getSocialAccessTokenByAuthorizationCode(String code) { From 4f68e935735d1b2014728515964d7ee7928dc984 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 21:14:50 +0900 Subject: [PATCH 22/43] =?UTF-8?q?feat=20-=20#171=20admin=20=ED=83=88?= =?UTF-8?q?=ED=87=B4=20=EA=B8=B0=EB=8A=A5=20controller=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/sopt/org/hmh/domain/admin/controller/AdminApi.java | 3 ++- .../org/hmh/domain/admin/controller/AdminController.java | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java index 90c7fda5..208dcda0 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java @@ -3,6 +3,7 @@ import io.swagger.v3.oas.annotations.Operation; import org.springframework.http.ResponseEntity; import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; +import sopt.org.hmh.domain.admin.dto.request.AdminUserIdRequest; import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.global.common.response.BaseResponse; @@ -11,5 +12,5 @@ public interface AdminApi { ResponseEntity> orderAdminLogin(AdminLoginRequest request); @Operation(summary = "관리자 권한으로 유저 즉시 삭제") - ResponseEntity orderAdminWithdrawImmediately(Long userId); + ResponseEntity orderAdminWithdrawImmediately(AdminUserIdRequest request); } diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java index c7fd4a59..5ed17311 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; +import sopt.org.hmh.domain.admin.dto.request.AdminUserIdRequest; import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.domain.admin.exception.AdminSuccess; import sopt.org.hmh.domain.admin.service.AdminFacade; @@ -33,8 +34,9 @@ public ResponseEntity> orderAdminLogin( @Override @DeleteMapping("/user") - public ResponseEntity orderAdminWithdrawImmediately(@RequestBody @Valid final Long userId) { - adminFacade.withdrawImmediately(userId); + public ResponseEntity orderAdminWithdrawImmediately( + @RequestBody @Valid final AdminUserIdRequest request) { + adminFacade.withdrawImmediately(request.userId()); return ResponseEntity .noContent() .build(); From 31bd4d51ea6bc90a4aca2a7946f82d8bc898115f Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 21:15:02 +0900 Subject: [PATCH 23/43] =?UTF-8?q?feat=20-=20#171=20AdminUserIdRequest=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 --- .../hmh/domain/admin/dto/request/AdminUserIdRequest.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminUserIdRequest.java diff --git a/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminUserIdRequest.java b/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminUserIdRequest.java new file mode 100644 index 00000000..c1d513c3 --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminUserIdRequest.java @@ -0,0 +1,7 @@ +package sopt.org.hmh.domain.admin.dto.request; + +public record AdminUserIdRequest( + Long userId +) { + +} From b7f8e0a9ee12965f322c022b8e9312739ef4ac7f Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 21:24:41 +0900 Subject: [PATCH 24/43] =?UTF-8?q?modify=20-=20#171=20=EC=99=80=EC=9D=BC?= =?UTF-8?q?=EB=93=9C=20=EC=B9=B4=EB=93=9C=20=EC=A7=80=EC=96=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/sopt/org/hmh/domain/admin/controller/AdminApi.java | 2 +- .../sopt/org/hmh/domain/admin/controller/AdminController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java index 208dcda0..17ac83f9 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java @@ -12,5 +12,5 @@ public interface AdminApi { ResponseEntity> orderAdminLogin(AdminLoginRequest request); @Operation(summary = "관리자 권한으로 유저 즉시 삭제") - ResponseEntity orderAdminWithdrawImmediately(AdminUserIdRequest request); + ResponseEntity orderAdminWithdrawImmediately(AdminUserIdRequest request); } diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java index 5ed17311..f2eeb20e 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java @@ -34,7 +34,7 @@ public ResponseEntity> orderAdminLogin( @Override @DeleteMapping("/user") - public ResponseEntity orderAdminWithdrawImmediately( + public ResponseEntity orderAdminWithdrawImmediately( @RequestBody @Valid final AdminUserIdRequest request) { adminFacade.withdrawImmediately(request.userId()); return ResponseEntity From fe6a8f04db24df8184f901b247713a649a8bc6b3 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 21:49:23 +0900 Subject: [PATCH 25/43] =?UTF-8?q?modify=20-=20#171=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20=EC=9C=A0=EC=A0=80=EB=A5=BC=20?= =?UTF-8?q?=EC=B0=BE=EC=A7=80=20=EB=AA=BB=ED=95=98=EB=A9=B4=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=B0=9C=EC=83=9D=ED=95=98=EB=8F=84=EB=A1=9D=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 --- .../org/hmh/domain/admin/service/AdminFacade.java | 3 +++ .../sopt/org/hmh/domain/user/service/UserService.java | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java index 053db66c..0bb899f9 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java +++ b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.domain.admin.exception.AdminError; import sopt.org.hmh.domain.admin.exception.AdminException; @@ -30,7 +31,9 @@ private void validateAdminAuthCode(String authCode) { } } + @Transactional public void withdrawImmediately(Long userId) { + userService.checkIsExistUserId(userId); userService.withdrawImmediately(userId); } } diff --git a/src/main/java/sopt/org/hmh/domain/user/service/UserService.java b/src/main/java/sopt/org/hmh/domain/user/service/UserService.java index ac1719e0..992f4e29 100644 --- a/src/main/java/sopt/org/hmh/domain/user/service/UserService.java +++ b/src/main/java/sopt/org/hmh/domain/user/service/UserService.java @@ -85,6 +85,16 @@ public User findByIdOrThrowException(Long userId) { () -> new UserException(UserError.NOT_FOUND_USER)); } + private boolean isExistUserId(Long userId) { + return userRepository.existsById(userId); + } + + public void checkIsExistUserId(Long userId) { + if (isExistUserId(userId)) { + throw new UserException(UserError.NOT_FOUND_USER); + } + } + public Long getCurrentChallengeIdByUserId(Long userId) { return Optional.ofNullable(this.findByIdOrThrowException(userId).getCurrentChallengeId()) .orElseThrow(() -> new UserException(UserError.NOT_FOUND_CURRENT_CHALLENGE_ID)); @@ -101,7 +111,6 @@ public IsLockTodayResponse checkIsTodayLock(Long userId, LocalDate lockCheckDate return new IsLockTodayResponse(lockCheckDate.equals(userRecentLockDate)); } - @Transactional public void withdrawImmediately(Long userId) { userRepository.deleteById(userId); } From a8d3de9b6426763f667d1f9cc8eed9dd5417d8b0 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 21:49:55 +0900 Subject: [PATCH 26/43] =?UTF-8?q?modify=20-=20#171=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20=EC=9C=A0=EC=A0=80=EB=A5=BC=20?= =?UTF-8?q?=EC=B0=BE=EC=A7=80=20=EB=AA=BB=ED=95=98=EB=A9=B4=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=B0=9C=EC=83=9D=ED=95=98=EB=8F=84=EB=A1=9D=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 --- src/main/java/sopt/org/hmh/domain/user/service/UserService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/sopt/org/hmh/domain/user/service/UserService.java b/src/main/java/sopt/org/hmh/domain/user/service/UserService.java index 992f4e29..397c5252 100644 --- a/src/main/java/sopt/org/hmh/domain/user/service/UserService.java +++ b/src/main/java/sopt/org/hmh/domain/user/service/UserService.java @@ -90,7 +90,7 @@ private boolean isExistUserId(Long userId) { } public void checkIsExistUserId(Long userId) { - if (isExistUserId(userId)) { + if (!isExistUserId(userId)) { throw new UserException(UserError.NOT_FOUND_USER); } } From b522b85f12809f943cb84ba134dcd10de437656d Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 22:19:11 +0900 Subject: [PATCH 27/43] =?UTF-8?q?feat=20-=20#171=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EB=B3=80=EA=B2=BD=20controller=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 --- .../org/hmh/domain/admin/controller/AdminApi.java | 4 ++++ .../hmh/domain/admin/controller/AdminController.java | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java index 17ac83f9..7944cfdc 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java @@ -4,6 +4,7 @@ import org.springframework.http.ResponseEntity; import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; import sopt.org.hmh.domain.admin.dto.request.AdminUserIdRequest; +import sopt.org.hmh.domain.admin.dto.request.AdminUserInfoRequest; import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.global.common.response.BaseResponse; @@ -13,4 +14,7 @@ public interface AdminApi { @Operation(summary = "관리자 권한으로 유저 즉시 삭제") ResponseEntity orderAdminWithdrawImmediately(AdminUserIdRequest request); + + @Operation(summary = "관리자 권한으로 유저 정보 변경") + ResponseEntity orderAdminChangeUserInfo(AdminUserInfoRequest request); } diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java index f2eeb20e..80db9323 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java @@ -4,12 +4,14 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PatchMapping; 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; import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; import sopt.org.hmh.domain.admin.dto.request.AdminUserIdRequest; +import sopt.org.hmh.domain.admin.dto.request.AdminUserInfoRequest; import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.domain.admin.exception.AdminSuccess; import sopt.org.hmh.domain.admin.service.AdminFacade; @@ -41,4 +43,14 @@ public ResponseEntity orderAdminWithdrawImmediately( .noContent() .build(); } + + @Override + @PatchMapping("/user") + public ResponseEntity orderAdminChangeUserInfo( + @RequestBody @Valid final AdminUserInfoRequest request) { + adminFacade.ChangeUserInfo(request); + return ResponseEntity + .noContent() + .build(); + } } From 0cf8f929af271bd4d7a4ccb536289268ab39d2d6 Mon Sep 17 00:00:00 2001 From: kseysh Date: Fri, 5 Jul 2024 22:19:23 +0900 Subject: [PATCH 28/43] =?UTF-8?q?feat=20-=20#171=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EB=B3=80=EA=B2=BD=20request=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/admin/dto/request/AdminUserInfoRequest.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminUserInfoRequest.java diff --git a/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminUserInfoRequest.java b/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminUserInfoRequest.java new file mode 100644 index 00000000..ab7c2969 --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminUserInfoRequest.java @@ -0,0 +1,9 @@ +package sopt.org.hmh.domain.admin.dto.request; + +public record AdminUserInfoRequest( + Long userId, + String name, + Integer point +) { + +} From 6dbf1d9aa9fc73c4140c27061ebc1200536531f0 Mon Sep 17 00:00:00 2001 From: kseysh Date: Sat, 6 Jul 2024 02:13:03 +0900 Subject: [PATCH 29/43] =?UTF-8?q?refactor=20-=20#171=20code=20=EA=B0=80?= =?UTF-8?q?=EB=8F=85=EC=84=B1=20=ED=96=A5=EC=83=81=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=A4=84=20=EB=B0=94=EA=BF=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ChallengeController.java | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/sopt/org/hmh/domain/challenge/controller/ChallengeController.java b/src/main/java/sopt/org/hmh/domain/challenge/controller/ChallengeController.java index 6dd9f363..3c503397 100644 --- a/src/main/java/sopt/org/hmh/domain/challenge/controller/ChallengeController.java +++ b/src/main/java/sopt/org/hmh/domain/challenge/controller/ChallengeController.java @@ -25,9 +25,10 @@ public class ChallengeController implements ChallengeApi { @PostMapping @Override - public ResponseEntity> orderAddChallenge(@UserId final Long userId, - @RequestHeader("OS") final String os, - @RequestBody @Valid final ChallengeRequest request) { + public ResponseEntity> orderAddChallenge( + @UserId final Long userId, + @RequestHeader("OS") final String os, + @RequestBody @Valid final ChallengeRequest request) { challengeFacade.addChallenge(userId, request, os); return ResponseEntity @@ -37,8 +38,9 @@ public ResponseEntity> orderAddChallenge(@UserId final Long user @GetMapping @Override - public ResponseEntity> orderGetChallenge(@UserId final Long userId, - @RequestHeader("OS") final String os) { + public ResponseEntity> orderGetChallenge( + @UserId final Long userId, + @RequestHeader("OS") final String os) { return ResponseEntity .status(ChallengeSuccess.GET_CHALLENGE_SUCCESS.getHttpStatus()) .body(BaseResponse.success(ChallengeSuccess.GET_CHALLENGE_SUCCESS, @@ -47,8 +49,9 @@ public ResponseEntity> orderGetChallenge(@UserId @GetMapping("/home") @Override - public ResponseEntity> orderGetDailyChallenge(@UserId final Long userId, - @RequestHeader("OS") final String os) { + public ResponseEntity> orderGetDailyChallenge( + @UserId final Long userId, + @RequestHeader("OS") final String os) { return ResponseEntity .status(ChallengeSuccess.GET_DAILY_CHALLENGE_SUCCESS.getHttpStatus()) .body(BaseResponse.success(ChallengeSuccess.GET_DAILY_CHALLENGE_SUCCESS, @@ -57,9 +60,10 @@ public ResponseEntity> orderGetDailyChallen @PostMapping("/app") @Override - public ResponseEntity> orderAddApps(@UserId final Long userId, - @RequestHeader("OS") final String os, - @RequestBody @Valid final ChallengeAppArrayRequest requests) { + public ResponseEntity> orderAddApps( + @UserId final Long userId, + @RequestHeader("OS") final String os, + @RequestBody @Valid final ChallengeAppArrayRequest requests) { challengeFacade.addAppsToCurrentChallenge(userId, requests.apps(), os); return ResponseEntity @@ -70,9 +74,10 @@ public ResponseEntity> orderAddApps(@UserId final Long userId, @DeleteMapping("/app") @Override - public ResponseEntity> orderRemoveApp(@UserId final Long userId, - @RequestHeader("OS") final String os, - @RequestBody @Valid final AppRemoveRequest request) { + public ResponseEntity> orderRemoveApp( + @UserId final Long userId, + @RequestHeader("OS") final String os, + @RequestBody @Valid final AppRemoveRequest request) { challengeFacade.removeAppFromCurrentChallenge(userId, request.appCode(), os); return ResponseEntity From a98eb47f8535e077cd37be35ab4cf7452fedaf2b Mon Sep 17 00:00:00 2001 From: kseysh Date: Sat, 6 Jul 2024 05:27:20 +0900 Subject: [PATCH 30/43] =?UTF-8?q?feat=20-=20#171=20admin=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=EC=9D=B8=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20interceptor=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/ValidateAdminInterceptor.java | 23 +++++++++++++++++++ .../sopt/org/hmh/global/config/WebConfig.java | 15 ++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/main/java/sopt/org/hmh/global/auth/security/ValidateAdminInterceptor.java diff --git a/src/main/java/sopt/org/hmh/global/auth/security/ValidateAdminInterceptor.java b/src/main/java/sopt/org/hmh/global/auth/security/ValidateAdminInterceptor.java new file mode 100644 index 00000000..4a08fac4 --- /dev/null +++ b/src/main/java/sopt/org/hmh/global/auth/security/ValidateAdminInterceptor.java @@ -0,0 +1,23 @@ +package sopt.org.hmh.global.auth.security; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import sopt.org.hmh.global.auth.jwt.JwtConstants; +import sopt.org.hmh.global.auth.jwt.TokenService; + +@Component +@RequiredArgsConstructor +public class ValidateAdminInterceptor implements HandlerInterceptor { + + private final TokenService tokenService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + String accessToken = request.getHeader(JwtConstants.AUTHORIZATION); + tokenService.validateAdminToken(accessToken); + return true; + } +} diff --git a/src/main/java/sopt/org/hmh/global/config/WebConfig.java b/src/main/java/sopt/org/hmh/global/config/WebConfig.java index 63262f86..d4a64745 100644 --- a/src/main/java/sopt/org/hmh/global/config/WebConfig.java +++ b/src/main/java/sopt/org/hmh/global/config/WebConfig.java @@ -1,15 +1,23 @@ package sopt.org.hmh.global.config; 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.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import sopt.org.hmh.global.auth.UserIdArgumentResolver; +import sopt.org.hmh.global.auth.security.ValidateAdminInterceptor; @Configuration +@EnableWebMvc +@RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { + private final ValidateAdminInterceptor validateAdminInterceptor; + @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") @@ -23,4 +31,11 @@ public void addCorsMappings(CorsRegistry registry) { public void addArgumentResolvers(List resolvers) { resolvers.add(new UserIdArgumentResolver()); } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(validateAdminInterceptor) + .addPathPatterns("/api/v1/admin/**") + .excludePathPatterns("/api/v1/admin/login"); + } } \ No newline at end of file From 901c14c19b9658a98904636be6712a52b8ddd35f Mon Sep 17 00:00:00 2001 From: kseysh Date: Sat, 6 Jul 2024 05:29:02 +0900 Subject: [PATCH 31/43] =?UTF-8?q?feat=20-=20#171=20JwtPrefixExtractor=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 --- .../global/auth/jwt/JwtPrefixExtractor.java | 19 +++++++++++++++++++ .../security/JwtAuthenticationFilter.java | 9 +-------- 2 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 src/main/java/sopt/org/hmh/global/auth/jwt/JwtPrefixExtractor.java diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtPrefixExtractor.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtPrefixExtractor.java new file mode 100644 index 00000000..bf825e6b --- /dev/null +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtPrefixExtractor.java @@ -0,0 +1,19 @@ +package sopt.org.hmh.global.auth.jwt; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.springframework.util.StringUtils; +import sopt.org.hmh.global.auth.jwt.exception.JwtError; +import sopt.org.hmh.global.auth.jwt.exception.JwtException; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class JwtPrefixExtractor { + + public static String extractPrefix(String accessToken) { + if (StringUtils.hasText(accessToken) && accessToken.startsWith(JwtConstants.BEARER)) { + return accessToken.substring(JwtConstants.BEARER.length()); + } + throw new JwtException(JwtError.INVALID_ACCESS_TOKEN); + } + +} diff --git a/src/main/java/sopt/org/hmh/global/auth/security/JwtAuthenticationFilter.java b/src/main/java/sopt/org/hmh/global/auth/security/JwtAuthenticationFilter.java index fe360d0c..db01f72f 100644 --- a/src/main/java/sopt/org/hmh/global/auth/security/JwtAuthenticationFilter.java +++ b/src/main/java/sopt/org/hmh/global/auth/security/JwtAuthenticationFilter.java @@ -11,14 +11,11 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; import sopt.org.hmh.global.auth.jwt.JwtConstants; import sopt.org.hmh.global.auth.jwt.JwtProvider; import sopt.org.hmh.global.auth.jwt.JwtValidator; -import sopt.org.hmh.global.auth.jwt.exception.JwtError; -import sopt.org.hmh.global.auth.jwt.exception.JwtException; @RequiredArgsConstructor public class JwtAuthenticationFilter extends OncePerRequestFilter { @@ -34,11 +31,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse } private String getAccessToken(HttpServletRequest request) { - String accessToken = request.getHeader(JwtConstants.AUTHORIZATION); - if (StringUtils.hasText(accessToken) && accessToken.startsWith(JwtConstants.BEARER)) { - return accessToken.substring(JwtConstants.BEARER.length()); - } - throw new JwtException(JwtError.INVALID_ACCESS_TOKEN); + return request.getHeader(JwtConstants.AUTHORIZATION); } private void doAuthentication(HttpServletRequest request, String subjectId) { From 407978a73161379c11393082077f2e45f1bdf162 Mon Sep 17 00:00:00 2001 From: kseysh Date: Sat, 6 Jul 2024 05:29:30 +0900 Subject: [PATCH 32/43] =?UTF-8?q?feat=20-=20#171=20JwtPrefixExtractor=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 --- .../org/hmh/global/auth/jwt/JwtProvider.java | 5 ++++- .../org/hmh/global/auth/jwt/JwtValidator.java | 4 +++- .../org/hmh/global/auth/jwt/TokenService.java | 18 +++++++----------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java index 70c5babc..ade8b1df 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtProvider.java @@ -1,5 +1,7 @@ package sopt.org.hmh.global.auth.jwt; +import static sopt.org.hmh.global.auth.jwt.JwtPrefixExtractor.extractPrefix; + import io.jsonwebtoken.JwtParser; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -16,8 +18,9 @@ public TokenResponse issueToken(String subjectId) { } public String getSubject(String token) { + String extractedToken = extractPrefix(token); JwtParser jwtParser = jwtGenerator.getJwtParser(); - return jwtParser.parseClaimsJws(token) + return jwtParser.parseClaimsJws(extractedToken) .getBody() .getSubject(); } diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtValidator.java b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtValidator.java index 03f35758..c964c791 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/JwtValidator.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/JwtValidator.java @@ -1,6 +1,7 @@ package sopt.org.hmh.global.auth.jwt; import static sopt.org.hmh.global.auth.jwt.JwtConstants.ADMIN_ROLE; +import static sopt.org.hmh.global.auth.jwt.JwtPrefixExtractor.extractPrefix; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; @@ -37,8 +38,9 @@ public void validateRefreshToken(String refreshToken) { } private Jws parseToken(String token) { + String extractedToken = extractPrefix(token); JwtParser jwtParser = jwtGenerator.getJwtParser(); - return jwtParser.parseClaimsJws(token); + return jwtParser.parseClaimsJws(extractedToken); } public void validateAdminToken(String token) { diff --git a/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java b/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java index 9abc4f36..b589abac 100644 --- a/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java +++ b/src/main/java/sopt/org/hmh/global/auth/jwt/TokenService.java @@ -1,11 +1,11 @@ package sopt.org.hmh.global.auth.jwt; +import static sopt.org.hmh.global.auth.jwt.JwtPrefixExtractor.extractPrefix; + import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import sopt.org.hmh.domain.auth.dto.response.ReissueResponse; -import sopt.org.hmh.global.auth.jwt.exception.JwtError; -import sopt.org.hmh.global.auth.jwt.exception.JwtException; @Service @RequiredArgsConstructor @@ -16,20 +16,12 @@ public class TokenService { @Transactional public ReissueResponse reissueToken(String refreshToken) { - String parsedRefreshToken = parseTokenString(refreshToken); + String parsedRefreshToken = extractPrefix(refreshToken); String userId = jwtProvider.getSubject(parsedRefreshToken); jwtValidator.validateRefreshToken(parsedRefreshToken); return ReissueResponse.of(jwtProvider.issueToken(userId)); } - private String parseTokenString(String tokenString) { - String[] parsedTokens = tokenString.split(" "); - if (parsedTokens.length != 2) { - throw new JwtException(JwtError.INVALID_TOKEN_HEADER); - } - return parsedTokens[1]; - } - public TokenResponse issueToken(String subjectId) { return jwtProvider.issueToken(subjectId); } @@ -38,4 +30,8 @@ public String issueAdminToken() { return jwtProvider.issueAdminToken(); } + public void validateAdminToken(String token){ + jwtValidator.validateAdminToken(token); + } + } From 252a6fc291fc8c3ab60d373cd93e195a5f7c73f1 Mon Sep 17 00:00:00 2001 From: kseysh Date: Sat, 6 Jul 2024 05:41:08 +0900 Subject: [PATCH 33/43] =?UTF-8?q?feat=20-=20#171=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=ED=9A=8C=EC=9B=90=20=EC=A0=95=EB=B3=B4=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/admin/controller/AdminController.java | 2 +- .../org/hmh/domain/admin/service/AdminFacade.java | 14 ++++++++++++++ .../java/sopt/org/hmh/domain/user/domain/User.java | 8 ++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java index 80db9323..2ea375bb 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java @@ -48,7 +48,7 @@ public ResponseEntity orderAdminWithdrawImmediately( @PatchMapping("/user") public ResponseEntity orderAdminChangeUserInfo( @RequestBody @Valid final AdminUserInfoRequest request) { - adminFacade.ChangeUserInfo(request); + adminFacade.changeUserInfo(request); return ResponseEntity .noContent() .build(); diff --git a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java index 0bb899f9..022e41f5 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java +++ b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java @@ -1,12 +1,15 @@ package sopt.org.hmh.domain.admin.service; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import sopt.org.hmh.domain.admin.dto.request.AdminUserInfoRequest; import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.domain.admin.exception.AdminError; import sopt.org.hmh.domain.admin.exception.AdminException; +import sopt.org.hmh.domain.user.domain.User; import sopt.org.hmh.domain.user.service.UserService; import sopt.org.hmh.global.auth.jwt.TokenService; @@ -36,4 +39,15 @@ public void withdrawImmediately(Long userId) { userService.checkIsExistUserId(userId); userService.withdrawImmediately(userId); } + + @Transactional + public void changeUserInfo(AdminUserInfoRequest request) { + User user = userService.findByIdOrThrowException(request.userId()); + if (Objects.nonNull(request.point())) { + user.changePoint(request.point()); + } + if (Objects.nonNull(request.name())) { + user.changeName(request.name()); + } + } } diff --git a/src/main/java/sopt/org/hmh/domain/user/domain/User.java b/src/main/java/sopt/org/hmh/domain/user/domain/User.java index 0ed66780..fb831734 100644 --- a/src/main/java/sopt/org/hmh/domain/user/domain/User.java +++ b/src/main/java/sopt/org/hmh/domain/user/domain/User.java @@ -89,6 +89,14 @@ public Integer increasePoint(Integer earnedPoint) { return this.point; } + public void changePoint(Integer point) { + this.point = point; + } + + public void changeName(String name) { + this.name = name; + } + public void changeCurrentChallengeId(Long currentChallengeId) { this.currentChallengeId = currentChallengeId; } From 98efb1eeacfb27a70a4379fa4fb6d35173780efb Mon Sep 17 00:00:00 2001 From: kseysh Date: Sat, 6 Jul 2024 05:54:07 +0900 Subject: [PATCH 34/43] =?UTF-8?q?refactor=20-=20#171=20=EA=B0=80=EB=8F=85?= =?UTF-8?q?=EC=84=B1=20=ED=96=A5=EC=83=81=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EC=A4=84=EB=B0=94=EA=BF=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailychallenge/service/DailyChallengeFacade.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeFacade.java b/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeFacade.java index 122b52fc..b4ba716e 100644 --- a/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeFacade.java +++ b/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeFacade.java @@ -25,10 +25,12 @@ public class DailyChallengeFacade { @Transactional public void addFinishedDailyChallengeHistory(Long userId, FinishedDailyChallengeListRequest requests, String os) { Long currentChallengeId = userService.getCurrentChallengeIdByUserId(userId); - List currentChallengeApps = challengeService.getCurrentChallengeAppByChallengeId(currentChallengeId); + List currentChallengeApps = + challengeService.getCurrentChallengeAppByChallengeId(currentChallengeId); requests.finishedDailyChallenges().forEach(request -> { - DailyChallenge dailyChallenge = dailyChallengeService.findByChallengeDateAndUserIdOrThrowException(request.challengeDate(), userId); + DailyChallenge dailyChallenge = + dailyChallengeService.findByChallengeDateAndUserIdOrThrowException(request.challengeDate(), userId); dailyChallengeService.changeStatusByCurrentStatus(dailyChallenge); historyAppService.addHistoryApp(currentChallengeApps, request.apps(), dailyChallenge, os); }); @@ -37,12 +39,14 @@ public void addFinishedDailyChallengeHistory(Long userId, FinishedDailyChallenge @Transactional public void changeDailyChallengeStatusByIsSuccess(Long userId, FinishedDailyChallengeStatusListRequest requests) { requests.finishedDailyChallenges().forEach(request -> { - DailyChallenge dailyChallenge = dailyChallengeService.findByChallengeDateAndUserIdOrThrowException(request.challengeDate(), userId); + DailyChallenge dailyChallenge = + dailyChallengeService.findByChallengeDateAndUserIdOrThrowException(request.challengeDate(), userId); if (request.isSuccess()) { dailyChallengeService.validateDailyChallengeStatus(dailyChallenge.getStatus(), List.of(Status.NONE)); dailyChallenge.changeStatus(Status.UNEARNED); } else { - dailyChallengeService.validateDailyChallengeStatus(dailyChallenge.getStatus(), List.of(Status.NONE, Status.FAILURE)); + dailyChallengeService.validateDailyChallengeStatus( + dailyChallenge.getStatus(), List.of(Status.NONE, Status.FAILURE)); dailyChallenge.changeStatus(Status.FAILURE); } }); From f857322ad926893a1be9dd9becc107255bdabd01 Mon Sep 17 00:00:00 2001 From: kseysh Date: Sat, 6 Jul 2024 06:29:56 +0900 Subject: [PATCH 35/43] =?UTF-8?q?feat=20-=20#171=20AdminDailyChallengeRequ?= =?UTF-8?q?est=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/AdminDailyChallengeRequest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminDailyChallengeRequest.java diff --git a/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminDailyChallengeRequest.java b/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminDailyChallengeRequest.java new file mode 100644 index 00000000..ccd4e389 --- /dev/null +++ b/src/main/java/sopt/org/hmh/domain/admin/dto/request/AdminDailyChallengeRequest.java @@ -0,0 +1,12 @@ +package sopt.org.hmh.domain.admin.dto.request; + +import java.time.LocalDate; +import java.util.List; +import sopt.org.hmh.domain.dailychallenge.domain.Status; + +public record AdminDailyChallengeRequest( + Long userId, + LocalDate startDate, + List statuses +) { +} From 178f17ab35ce7bb3f0640ca7fb6629e4a212f16b Mon Sep 17 00:00:00 2001 From: kseysh Date: Sat, 6 Jul 2024 06:30:27 +0900 Subject: [PATCH 36/43] =?UTF-8?q?feat=20-=20#171=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=B1=8C=EB=A6=B0=EC=A7=80=20=EC=A0=95=EB=B3=B4=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20controller=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/hmh/domain/admin/controller/AdminApi.java | 4 ++++ .../hmh/domain/admin/controller/AdminController.java | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java index 7944cfdc..51b57e3f 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.Operation; import org.springframework.http.ResponseEntity; +import sopt.org.hmh.domain.admin.dto.request.AdminDailyChallengeRequest; import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; import sopt.org.hmh.domain.admin.dto.request.AdminUserIdRequest; import sopt.org.hmh.domain.admin.dto.request.AdminUserInfoRequest; @@ -17,4 +18,7 @@ public interface AdminApi { @Operation(summary = "관리자 권한으로 유저 정보 변경") ResponseEntity orderAdminChangeUserInfo(AdminUserInfoRequest request); + + @Operation(summary = "관리자 권한으로 유저 챌린지 정보 변경") + ResponseEntity orderAdminChangeDailyChallengeInfo(AdminDailyChallengeRequest request); } diff --git a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java index 2ea375bb..647cea23 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java +++ b/src/main/java/sopt/org/hmh/domain/admin/controller/AdminController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import sopt.org.hmh.domain.admin.dto.request.AdminDailyChallengeRequest; import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest; import sopt.org.hmh.domain.admin.dto.request.AdminUserIdRequest; import sopt.org.hmh.domain.admin.dto.request.AdminUserInfoRequest; @@ -53,4 +54,14 @@ public ResponseEntity orderAdminChangeUserInfo( .noContent() .build(); } + + @Override + @PatchMapping("/challenge/daily") + public ResponseEntity orderAdminChangeDailyChallengeInfo( + @RequestBody @Valid final AdminDailyChallengeRequest request) { + adminFacade.changeDailyChallengeInfo(request); + return ResponseEntity + .noContent() + .build(); + } } From 8bb97903910d824fd47a2253effbe6dfd7d570dd Mon Sep 17 00:00:00 2001 From: kseysh Date: Sun, 7 Jul 2024 18:09:33 +0900 Subject: [PATCH 37/43] =?UTF-8?q?feat=20-=20#171=20challenge=20id=EB=A1=9C?= =?UTF-8?q?=20dailyChallenge=EB=A5=BC=20=EC=B0=BE=EB=8A=94=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailychallenge/repository/DailyChallengeRepository.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/sopt/org/hmh/domain/dailychallenge/repository/DailyChallengeRepository.java b/src/main/java/sopt/org/hmh/domain/dailychallenge/repository/DailyChallengeRepository.java index e08921fd..ca5bd335 100644 --- a/src/main/java/sopt/org/hmh/domain/dailychallenge/repository/DailyChallengeRepository.java +++ b/src/main/java/sopt/org/hmh/domain/dailychallenge/repository/DailyChallengeRepository.java @@ -1,10 +1,14 @@ package sopt.org.hmh.domain.dailychallenge.repository; import java.time.LocalDate; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import sopt.org.hmh.domain.dailychallenge.domain.DailyChallenge; public interface DailyChallengeRepository extends JpaRepository { + Optional findByChallengeDateAndUserId(LocalDate challengeDate, Long userId); + + List findAllByChallengeId(Long challengeId); } \ No newline at end of file From 88726fee3a8526f149a7cb3f02c21685139f0a28 Mon Sep 17 00:00:00 2001 From: kseysh Date: Sun, 7 Jul 2024 18:10:12 +0900 Subject: [PATCH 38/43] =?UTF-8?q?feat=20-=20#171=20dailyChallenge=EC=9D=98?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=B0=94=EA=BE=B8=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailychallenge/domain/DailyChallenge.java | 5 +++- .../service/DailyChallengeService.java | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/sopt/org/hmh/domain/dailychallenge/domain/DailyChallenge.java b/src/main/java/sopt/org/hmh/domain/dailychallenge/domain/DailyChallenge.java index d62ac340..2d568237 100644 --- a/src/main/java/sopt/org/hmh/domain/dailychallenge/domain/DailyChallenge.java +++ b/src/main/java/sopt/org/hmh/domain/dailychallenge/domain/DailyChallenge.java @@ -9,7 +9,6 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.util.Assert; import sopt.org.hmh.domain.app.domain.HistoryApp; import sopt.org.hmh.global.common.domain.BaseTimeEntity; import sopt.org.hmh.domain.challenge.domain.Challenge; @@ -54,6 +53,10 @@ public class DailyChallenge extends BaseTimeEntity { this.status = Status.NONE; } + public void changeChallengeDate(LocalDate challengeDate) { + this.challengeDate = challengeDate; + } + public void changeStatus(Status status) { this.status = status; } diff --git a/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeService.java b/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeService.java index 7062cae1..76d81a8a 100644 --- a/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeService.java +++ b/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeService.java @@ -53,4 +53,28 @@ public void addDailyChallenge(Long userId, LocalDate startDate, Challenge challe .goalTime(challenge.getGoalTime()).build()) .toList()); } + + public List getDailyChallengesByChallengeId(Long challengeId) { + return dailyChallengeRepository.findAllByChallengeId(challengeId); + } + + public void changeInfoOfDailyChallenges(Long challengeId, List statuses, LocalDate challengeDate) { + List dailyChallenges = getDailyChallengesByChallengeId(challengeId); + changeStatusOfDailyChallenges(dailyChallenges, statuses); + changeChallengeDateOfDailyChallenges(dailyChallenges, challengeDate); + } + + private void changeStatusOfDailyChallenges(List dailyChallenges, List statuses) { + int challengePeriod = dailyChallenges.size(); + for (int i = 0; i < challengePeriod; i++) { + dailyChallenges.get(i).changeStatus(statuses.get(i)); + } + } + + private void changeChallengeDateOfDailyChallenges(List dailyChallenges, LocalDate challengeDate) { + int challengePeriod = dailyChallenges.size(); + for (int i = 0; i < challengePeriod; i++) { + dailyChallenges.get(i).changeChallengeDate(challengeDate.plusDays(i)); + } + } } \ No newline at end of file From 7ba10f46d2ebd8510c2f21b497ecd66b9bb09fc5 Mon Sep 17 00:00:00 2001 From: kseysh Date: Sun, 7 Jul 2024 18:10:25 +0900 Subject: [PATCH 39/43] =?UTF-8?q?feat=20-=20#171=20challenge=20=EA=B8=B0?= =?UTF-8?q?=EA=B0=84=EC=9D=84=20=EC=B0=BE=EB=8A=94=20=EB=A1=9C=EC=A7=81=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 --- .../org/hmh/domain/challenge/service/ChallengeService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/sopt/org/hmh/domain/challenge/service/ChallengeService.java b/src/main/java/sopt/org/hmh/domain/challenge/service/ChallengeService.java index 569a4684..efd2e311 100644 --- a/src/main/java/sopt/org/hmh/domain/challenge/service/ChallengeService.java +++ b/src/main/java/sopt/org/hmh/domain/challenge/service/ChallengeService.java @@ -31,4 +31,8 @@ public List getCurrentChallengeAppByChallengeId(Long challengeId) public Challenge save(Challenge challenge) { return challengeRepository.save(challenge); } + + public Integer getChallengePeriod(Long challengeId) { + return findByIdOrElseThrow(challengeId).getPeriod(); + } } From a1b41fbfe0be18ec363352c87ca9e6c565a137df Mon Sep 17 00:00:00 2001 From: kseysh Date: Sun, 7 Jul 2024 18:10:48 +0900 Subject: [PATCH 40/43] =?UTF-8?q?feat=20-=20#171=20dailyChallenge=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=B3=80=EA=B2=BD=ED=95=98?= =?UTF-8?q?=EB=8A=94=20facade=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmh/domain/admin/service/AdminFacade.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java index 022e41f5..fa1ff3b7 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java +++ b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java @@ -1,14 +1,22 @@ package sopt.org.hmh.domain.admin.service; +import java.time.LocalDate; +import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import sopt.org.hmh.domain.admin.dto.request.AdminDailyChallengeRequest; import sopt.org.hmh.domain.admin.dto.request.AdminUserInfoRequest; import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse; import sopt.org.hmh.domain.admin.exception.AdminError; import sopt.org.hmh.domain.admin.exception.AdminException; +import sopt.org.hmh.domain.challenge.domain.exception.ChallengeError; +import sopt.org.hmh.domain.challenge.domain.exception.ChallengeException; +import sopt.org.hmh.domain.challenge.service.ChallengeService; +import sopt.org.hmh.domain.dailychallenge.domain.Status; +import sopt.org.hmh.domain.dailychallenge.service.DailyChallengeService; import sopt.org.hmh.domain.user.domain.User; import sopt.org.hmh.domain.user.service.UserService; import sopt.org.hmh.global.auth.jwt.TokenService; @@ -22,6 +30,8 @@ public class AdminFacade { private final UserService userService; private final TokenService tokenService; + private final ChallengeService challengeService; + private final DailyChallengeService dailyChallengeService; public AdminTokenResponse adminLogin(String authCode) { validateAdminAuthCode(authCode); @@ -50,4 +60,21 @@ public void changeUserInfo(AdminUserInfoRequest request) { user.changeName(request.name()); } } + + @Transactional + public void changeDailyChallengeInfo(AdminDailyChallengeRequest request) { + Long currentChallengeId = userService.getCurrentChallengeIdByUserId(request.userId()); + List statuses = request.statuses(); + LocalDate challengeDate = request.startDate(); + + validateStatusesPeriod(currentChallengeId, statuses); + dailyChallengeService.changeInfoOfDailyChallenges(currentChallengeId, statuses, challengeDate); + } + + private void validateStatusesPeriod(Long challengeId, List statuses) { + Integer challengePeriod = challengeService.getChallengePeriod(challengeId); + if (challengePeriod != statuses.size()) { + throw new ChallengeException(ChallengeError.INVALID_PERIOD_NUMERIC); + } + } } From 16cb21e6e39dca70a89edb4c9c0584f12c3d2f23 Mon Sep 17 00:00:00 2001 From: kseysh Date: Sun, 7 Jul 2024 22:33:37 +0900 Subject: [PATCH 41/43] =?UTF-8?q?refactor=20-=20#171=20=EC=9C=A0=EC=A0=80?= =?UTF-8?q?=20=EC=95=84=EC=9D=B4=EB=94=94=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A1=9C=20=EC=97=AC=EB=9F=AC=20=EC=B1=8C=EB=A6=B0=EC=A7=80?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AD=EC=A0=9C=ED=95=98=EB=8A=94=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=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 --- .../org/hmh/domain/challenge/service/ChallengeService.java | 6 +++++- .../hmh/domain/user/service/ExpiredUserDeleteScheduler.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/sopt/org/hmh/domain/challenge/service/ChallengeService.java b/src/main/java/sopt/org/hmh/domain/challenge/service/ChallengeService.java index efd2e311..ccf0cf02 100644 --- a/src/main/java/sopt/org/hmh/domain/challenge/service/ChallengeService.java +++ b/src/main/java/sopt/org/hmh/domain/challenge/service/ChallengeService.java @@ -15,10 +15,14 @@ public class ChallengeService { private final ChallengeRepository challengeRepository; - public void deleteChallengeRelatedByUserId(List expiredUserIdList) { + public void deleteChallengeRelatedByUserIds(List expiredUserIdList) { challengeRepository.deleteByUserIdIn(expiredUserIdList); } + public void deleteChallengeRelatedByUserId(Long userId) { + challengeRepository.deleteByUserId(userId); + } + public Challenge findByIdOrElseThrow(Long challengeId) { return challengeRepository.findById(challengeId).orElseThrow( () -> new ChallengeException(ChallengeError.CHALLENGE_NOT_FOUND)); diff --git a/src/main/java/sopt/org/hmh/domain/user/service/ExpiredUserDeleteScheduler.java b/src/main/java/sopt/org/hmh/domain/user/service/ExpiredUserDeleteScheduler.java index 055fa30f..e3f096f8 100644 --- a/src/main/java/sopt/org/hmh/domain/user/service/ExpiredUserDeleteScheduler.java +++ b/src/main/java/sopt/org/hmh/domain/user/service/ExpiredUserDeleteScheduler.java @@ -25,6 +25,6 @@ public void deleteExpiredUser() { public void deleteExpiredUser(LocalDateTime currentDate) { List expiredUserList = userRepository.findIdByDeletedAtBeforeAndIsDeletedIsTrue(currentDate); userRepository.deleteAllById(expiredUserList); - challengeService.deleteChallengeRelatedByUserId(expiredUserList); + challengeService.deleteChallengeRelatedByUserIds(expiredUserList); } } From 65247c9a11bf67492af9a0e55cc7dbf9b565ea44 Mon Sep 17 00:00:00 2001 From: kseysh Date: Sun, 7 Jul 2024 22:34:53 +0900 Subject: [PATCH 42/43] =?UTF-8?q?modify=20-=20#171=20user=EB=A5=BC=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=ED=95=A0=20=EB=95=8C=20=EC=9C=A0=EC=A0=80?= =?UTF-8?q?=EC=99=80=20=EC=97=B0=EA=B4=80=EB=90=9C=20challenge=EB=8F=84=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=ED=95=98=EB=8F=84=EB=A1=9D=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 --- .../java/sopt/org/hmh/domain/admin/service/AdminFacade.java | 1 + .../hmh/domain/challenge/repository/ChallengeRepository.java | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java index fa1ff3b7..6fbdc22d 100644 --- a/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java +++ b/src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java @@ -47,6 +47,7 @@ private void validateAdminAuthCode(String authCode) { @Transactional public void withdrawImmediately(Long userId) { userService.checkIsExistUserId(userId); + challengeService.deleteChallengeRelatedByUserId(userId); userService.withdrawImmediately(userId); } diff --git a/src/main/java/sopt/org/hmh/domain/challenge/repository/ChallengeRepository.java b/src/main/java/sopt/org/hmh/domain/challenge/repository/ChallengeRepository.java index b426c20f..1126f585 100644 --- a/src/main/java/sopt/org/hmh/domain/challenge/repository/ChallengeRepository.java +++ b/src/main/java/sopt/org/hmh/domain/challenge/repository/ChallengeRepository.java @@ -10,4 +10,6 @@ public interface ChallengeRepository extends JpaRepository { Optional findById(Long id); void deleteByUserIdIn(List userId); + + void deleteByUserId(Long userId); } \ No newline at end of file From bbb95e8d194ba45b924f69be1c4e8a270e5614bf Mon Sep 17 00:00:00 2001 From: kseysh Date: Sun, 7 Jul 2024 22:54:15 +0900 Subject: [PATCH 43/43] =?UTF-8?q?refactor=20-=20#171=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20int=20=EB=B3=80=EC=88=98=EB=A5=BC=20for?= =?UTF-8?q?=EB=AC=B8=20=EC=95=88=EC=9C=BC=EB=A1=9C=20=EB=84=A3=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailychallenge/service/DailyChallengeService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeService.java b/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeService.java index 76d81a8a..c5ee346e 100644 --- a/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeService.java +++ b/src/main/java/sopt/org/hmh/domain/dailychallenge/service/DailyChallengeService.java @@ -65,15 +65,13 @@ public void changeInfoOfDailyChallenges(Long challengeId, List statuses, } private void changeStatusOfDailyChallenges(List dailyChallenges, List statuses) { - int challengePeriod = dailyChallenges.size(); - for (int i = 0; i < challengePeriod; i++) { + for (int i = 0; i < dailyChallenges.size(); i++) { dailyChallenges.get(i).changeStatus(statuses.get(i)); } } private void changeChallengeDateOfDailyChallenges(List dailyChallenges, LocalDate challengeDate) { - int challengePeriod = dailyChallenges.size(); - for (int i = 0; i < challengePeriod; i++) { + for (int i = 0; i < dailyChallenges.size(); i++) { dailyChallenges.get(i).changeChallengeDate(challengeDate.plusDays(i)); } }