diff --git a/build.gradle b/build.gradle index fc366cc9..bcfe5ce5 100644 --- a/build.gradle +++ b/build.gradle @@ -29,6 +29,11 @@ subprojects { } dependencies { + // Spring Security + + //Spring Security + implementation 'org.springframework.boot:spring-boot-starter-security' + // lombok compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/moonshot-api/build.gradle b/moonshot-api/build.gradle index 458f2724..ee1917f9 100644 --- a/moonshot-api/build.gradle +++ b/moonshot-api/build.gradle @@ -1,7 +1,6 @@ dependencies { // Spring Framework implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-actuator' diff --git a/moonshot-api/src/main/java/org/moonshot/keyresult/controller/KeyResultApi.java b/moonshot-api/src/main/java/org/moonshot/keyresult/controller/KeyResultApi.java index 1c30fca0..351b8b45 100644 --- a/moonshot-api/src/main/java/org/moonshot/keyresult/controller/KeyResultApi.java +++ b/moonshot-api/src/main/java/org/moonshot/keyresult/controller/KeyResultApi.java @@ -7,11 +7,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -import java.security.Principal; import org.moonshot.keyresult.dto.request.KeyResultCreateRequestDto; import org.moonshot.keyresult.dto.request.KeyResultModifyRequestDto; import org.moonshot.keyresult.dto.response.KRDetailResponseDto; import org.moonshot.response.MoonshotResponse; +import org.moonshot.user.model.LoginUser; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -27,7 +27,7 @@ public interface KeyResultApi { @ApiResponse(responseCode = "404", description = "존재하지 않는 Objective입니다\t\n존재하지 않는 KeyResult입니다", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "KeyResult 데이터 생성") - public ResponseEntity> createKeyResult(Principal principal, @RequestBody @Valid KeyResultCreateRequestDto request); + public ResponseEntity> createKeyResult(@LoginUser Long userId, @RequestBody @Valid KeyResultCreateRequestDto request); @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "KeyResult 삭제를 성공하였습니다"), @@ -36,7 +36,7 @@ public interface KeyResultApi { @ApiResponse(responseCode = "404", description = "존재하지 않는 KeyResult입니다", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "KeyResult 데이터 삭제") - public ResponseEntity deleteKeyResult(Principal principal, @PathVariable("keyResultId") Long keyResultId); + public ResponseEntity deleteKeyResult(@LoginUser Long userId, @PathVariable("keyResultId") Long keyResultId); @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "KeyResult 수정 후 목표를 달성하였습니다\t\nKeyResult 수정을 성공하였습니다"), @@ -46,7 +46,7 @@ public interface KeyResultApi { @ApiResponse(responseCode = "404", description = "존재하지 않는 KeyResult입니다\t\n존재하지 않는 Log입니다", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "KeyResult 데이터 수정") - public ResponseEntity> modifyKeyResult(Principal principal, @RequestBody @Valid KeyResultModifyRequestDto request); + public ResponseEntity> modifyKeyResult(@LoginUser Long userId, @RequestBody @Valid KeyResultModifyRequestDto request); @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "O-KR을 생성을 성공하였습니다"), @@ -56,5 +56,5 @@ public interface KeyResultApi { @ApiResponse(responseCode = "404", description = "존재하지 않는 유저입니다", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "KeyResult 상세 조회 (사이드바)") - public ResponseEntity> getKRDetails(Principal principal, @PathVariable("keyResultId") Long keyResultId); + public ResponseEntity> getKRDetails(@LoginUser Long userId, @PathVariable("keyResultId") Long keyResultId); } diff --git a/moonshot-api/src/main/java/org/moonshot/keyresult/controller/KeyResultController.java b/moonshot-api/src/main/java/org/moonshot/keyresult/controller/KeyResultController.java index 2194830b..5b87f188 100644 --- a/moonshot-api/src/main/java/org/moonshot/keyresult/controller/KeyResultController.java +++ b/moonshot-api/src/main/java/org/moonshot/keyresult/controller/KeyResultController.java @@ -6,10 +6,8 @@ import static org.moonshot.response.SuccessType.POST_KEY_RESULT_SUCCESS; import jakarta.validation.Valid; -import java.security.Principal; import java.util.Optional; import lombok.RequiredArgsConstructor; -import org.moonshot.jwt.JwtTokenProvider; import org.moonshot.keyresult.dto.request.KeyResultCreateRequestDto; import org.moonshot.keyresult.dto.request.KeyResultModifyRequestDto; import org.moonshot.keyresult.dto.response.KRDetailResponseDto; @@ -18,6 +16,7 @@ import org.moonshot.model.Logging; import org.moonshot.response.MoonshotResponse; import org.moonshot.response.SuccessType; +import org.moonshot.user.model.LoginUser; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -38,22 +37,22 @@ public class KeyResultController implements KeyResultApi { @PostMapping @Logging(item = "KeyResult", action = "Post") - public ResponseEntity> createKeyResult(final Principal principal, @RequestBody @Valid final KeyResultCreateRequestDto request) { - keyResultService.createKeyResult(request, JwtTokenProvider.getUserIdFromPrincipal(principal)); + public ResponseEntity> createKeyResult(@LoginUser Long userId, @RequestBody @Valid final KeyResultCreateRequestDto request) { + keyResultService.createKeyResult(request, userId); return ResponseEntity.status(HttpStatus.CREATED).body(MoonshotResponse.success(POST_KEY_RESULT_SUCCESS)); } @DeleteMapping("/{keyResultId}") @Logging(item = "KeyResult", action = "Delete") - public ResponseEntity deleteKeyResult(final Principal principal, @PathVariable("keyResultId") final Long keyResultId) { - keyResultService.deleteKeyResult(keyResultId, JwtTokenProvider.getUserIdFromPrincipal(principal)); + public ResponseEntity deleteKeyResult(@LoginUser Long userId, @PathVariable("keyResultId") final Long keyResultId) { + keyResultService.deleteKeyResult(keyResultId, userId); return ResponseEntity.noContent().build(); } @PatchMapping @Logging(item = "KeyResult", action = "Patch") - public ResponseEntity> modifyKeyResult(final Principal principal, @RequestBody @Valid final KeyResultModifyRequestDto request) { - Optional response = keyResultService.modifyKeyResult(request, JwtTokenProvider.getUserIdFromPrincipal(principal)); + public ResponseEntity> modifyKeyResult(@LoginUser Long userId, @RequestBody @Valid final KeyResultModifyRequestDto request) { + Optional response = keyResultService.modifyKeyResult(request, userId); if (response.isPresent()) { return ResponseEntity.ok(MoonshotResponse.success(PATCH_KR_ACHIEVE_SUCCESS, response)); } @@ -62,9 +61,8 @@ public ResponseEntity> modifyKeyResult(final Principal princ @GetMapping("/{keyResultId}") @Logging(item = "KeyResult", action = "Get") - public ResponseEntity> getKRDetails(final Principal principal, @PathVariable("keyResultId") final Long keyResultId) { - return ResponseEntity.ok(MoonshotResponse.success(SuccessType.GET_KR_DETAIL_SUCCESS, keyResultService.getKRDetails( - JwtTokenProvider.getUserIdFromPrincipal(principal), keyResultId))); + public ResponseEntity> getKRDetails(@LoginUser Long userId, @PathVariable("keyResultId") final Long keyResultId) { + return ResponseEntity.ok(MoonshotResponse.success(SuccessType.GET_KR_DETAIL_SUCCESS, keyResultService.getKRDetails(userId, keyResultId))); } } diff --git a/moonshot-api/src/main/java/org/moonshot/keyresult/dto/request/KeyResultCreateRequestInfoDto.java b/moonshot-api/src/main/java/org/moonshot/keyresult/dto/request/KeyResultCreateRequestInfoDto.java index a0a46af6..f216fe85 100644 --- a/moonshot-api/src/main/java/org/moonshot/keyresult/dto/request/KeyResultCreateRequestInfoDto.java +++ b/moonshot-api/src/main/java/org/moonshot/keyresult/dto/request/KeyResultCreateRequestInfoDto.java @@ -10,19 +10,19 @@ public record KeyResultCreateRequestInfoDto( @Size(min = 1, max = 30, message = "KR은 30자 이하여야 합니다.") - String title, + String krTitle, @NotNull(message = "KR 시작 날짜를 선택해주세요.") - LocalDate startAt, + LocalDate krStartAt, @NotNull(message = "KR 종료 날짜를 선택해주세요.") - LocalDate expireAt, + LocalDate krExpireAt, @NotNull(message = "KR의 순서를 입력해주세요.") @Range(min = 0, max = 2, message = "KeyResult의 순서는 0부터 2까지로 설정할 수 있습니다.") - Integer idx, + Integer krIdx, @NotNull(message = "KR 목표 수치를 입력해주세요.") @Range(min = 1, max = 999999L, message = "수치는 999,999 이하여야 합니다.") - Long target, + Long krTarget, @NotNull(message = "KR 목표 수치의 단위를 입력해주세요.") - String metric, + String krMetric, @Valid @Size(max = 3, message = "Task 개수는 최대 3개로 제한되어 있습니다.") List taskList ) { diff --git a/moonshot-api/src/main/java/org/moonshot/keyresult/dto/response/KeyResultResponseDto.java b/moonshot-api/src/main/java/org/moonshot/keyresult/dto/response/KeyResultResponseDto.java index dde41bb1..1d0c15ce 100644 --- a/moonshot-api/src/main/java/org/moonshot/keyresult/dto/response/KeyResultResponseDto.java +++ b/moonshot-api/src/main/java/org/moonshot/keyresult/dto/response/KeyResultResponseDto.java @@ -5,9 +5,9 @@ import org.moonshot.task.dto.response.TaskResponseDto; public record KeyResultResponseDto( - Long keyResultId, - String keyResultTitle, - Integer idx, + Long krId, + String krTitle, + Integer krIdx, List taskList ) { public static List of(List krList) { diff --git a/moonshot-api/src/main/java/org/moonshot/keyresult/service/KeyResultService.java b/moonshot-api/src/main/java/org/moonshot/keyresult/service/KeyResultService.java index 48cea8ee..49bc5931 100644 --- a/moonshot-api/src/main/java/org/moonshot/keyresult/service/KeyResultService.java +++ b/moonshot-api/src/main/java/org/moonshot/keyresult/service/KeyResultService.java @@ -1,7 +1,19 @@ package org.moonshot.keyresult.service; -import static org.moonshot.keyresult.service.validator.KeyResultValidator.*; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.hasChange; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.hasDateChange; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.hasKeyResultTask; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.isKeyResultAchieved; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.validateActiveKRSizeExceeded; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.validateIndex; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.validateIndexUnderMaximum; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.validateKRPeriodWithInObjPeriod; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.validateKeyResultIndex; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.validateKeyResultPeriod; import static org.moonshot.log.service.validator.LogValidator.validateLogNum; +import static org.moonshot.response.ErrorType.NOT_FOUND_KEY_RESULT; +import static org.moonshot.response.ErrorType.NOT_FOUND_OBJECTIVE; +import static org.moonshot.response.ErrorType.REQUIRED_KEY_RESULT_VALUE; import static org.moonshot.task.service.validator.TaskValidator.validateTaskIndex; import static org.moonshot.user.service.validator.UserValidator.validateUserAuthorization; import static org.moonshot.validator.IndexValidator.isIndexIncreased; @@ -13,10 +25,8 @@ import java.util.Optional; import lombok.RequiredArgsConstructor; import org.moonshot.common.model.Period; -import org.moonshot.exception.keyresult.KeyResultNotFoundException; -import org.moonshot.exception.keyresult.KeyResultRequiredException; -import org.moonshot.exception.log.LogNotFoundException; -import org.moonshot.exception.objective.ObjectiveNotFoundException; +import org.moonshot.exception.BadRequestException; +import org.moonshot.exception.NotFoundException; import org.moonshot.keyresult.dto.request.KeyResultCreateRequestDto; import org.moonshot.keyresult.dto.request.KeyResultCreateRequestInfoDto; import org.moonshot.keyresult.dto.request.KeyResultModifyRequestDto; @@ -54,15 +64,15 @@ public void createInitKRWithObjective(final Objective objective, final List nonNullRequests = requests.stream().filter(Objects::nonNull).toList(); for (int i = 0; i < nonNullRequests.size(); i++) { KeyResultCreateRequestInfoDto dto = nonNullRequests.get(i); - validateKeyResultIndex(i, dto.idx()); - validateKRPeriodWithInObjPeriod(objective.getPeriod(), dto.startAt(), dto.expireAt()); + validateKeyResultIndex(i, dto.krIdx()); + validateKRPeriodWithInObjPeriod(objective.getPeriod(), dto.krStartAt(), dto.krExpireAt()); KeyResult keyResult = keyResultRepository.save(KeyResult.builder() - .title(dto.title()) - .period(Period.of(dto.startAt(), dto.expireAt())) - .idx(dto.idx()) - .target(dto.target()) - .metric(dto.metric()) + .title(dto.krTitle()) + .period(Period.of(dto.krStartAt(), dto.krExpireAt())) + .idx(dto.krIdx()) + .target(dto.krTarget()) + .metric(dto.krMetric()) .objective(objective) .build()); logService.createKRLog(dto, keyResult.getId()); @@ -75,7 +85,7 @@ public void createInitKRWithObjective(final Objective objective, final List new NotFoundException(NOT_FOUND_OBJECTIVE)); validateUserAuthorization(objective.getUser().getId(), userId); List krList = keyResultRepository.findAllByObjective(objective); @@ -92,12 +102,12 @@ public void createKeyResult(final KeyResultCreateRequestDto request, final Long .idx(request.idx()) .target(request.target()) .metric(request.metric()).build()); - logService.createKRLog(request, keyResult.getId()); + logService.createKRLog(request, keyResult.getId()); } public void deleteKeyResult(final Long keyResultId, final Long userId) { KeyResult keyResult = keyResultRepository.findKeyResultAndObjective(keyResultId) - .orElseThrow(KeyResultNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_KEY_RESULT)); validateUserAuthorization(keyResult.getObjective().getUser().getId(), userId); logRepository.deleteAllInBatch(logRepository.findAllByKeyResult(keyResult)); @@ -127,7 +137,7 @@ public void deleteAllKeyResult(List objectiveList) { public Optional modifyKeyResult(final KeyResultModifyRequestDto request, final Long userId) { KeyResult keyResult = keyResultRepository.findKeyResultAndObjective(request.keyResultId()) - .orElseThrow(KeyResultNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_KEY_RESULT)); validateUserAuthorization(keyResult.getObjective().getUser().getId(), userId); if (hasChange(request.title())) { @@ -149,7 +159,7 @@ public Optional modifyKeyResult(final KeyResultModifyRequest } if (request.target() == null || request.logContent() == null){ - throw new KeyResultRequiredException(); + throw new BadRequestException(REQUIRED_KEY_RESULT_VALUE); } Log updateLog = logService.createUpdateLog(request, keyResult.getId()); @@ -173,7 +183,7 @@ public Optional modifyKeyResult(final KeyResultModifyRequest @Override public void modifyIdx(final ModifyIndexRequestDto request, final Long userId) { KeyResult keyResult = keyResultRepository.findKeyResultAndObjective(request.id()) - .orElseThrow(KeyResultNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_KEY_RESULT)); validateUserAuthorization(keyResult.getObjective().getUser().getId(), userId); Long krCount = keyResultRepository.countAllByObjectiveId(keyResult.getObjective().getId()); @@ -195,7 +205,7 @@ public void modifyIdx(final ModifyIndexRequestDto request, final Long userId) { @Transactional(readOnly = true) public KRDetailResponseDto getKRDetails(final Long userId, final Long keyResultId) { KeyResult keyResult = keyResultRepository.findKeyResultAndObjective(keyResultId) - .orElseThrow(KeyResultNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_KEY_RESULT)); validateUserAuthorization(keyResult.getObjective().getUser().getId(), userId); List logList = logService.getLogList(keyResult); @@ -220,7 +230,7 @@ private void saveTasks(final KeyResult keyResult, final List nonNullTaskList = taskList.stream().filter(Objects::nonNull).toList(); for (int i = 0; i < nonNullTaskList.size(); i++) { TaskCreateRequestDto taskDto = nonNullTaskList.get(i); - validateTaskIndex(i, taskDto.idx()); + validateTaskIndex(i, taskDto.taskIdx()); taskService.saveTask(keyResult, taskDto); } } diff --git a/moonshot-api/src/main/java/org/moonshot/keyresult/service/converter/KRStateConverter.java b/moonshot-api/src/main/java/org/moonshot/keyresult/service/converter/KRStateConverter.java index adc65c1a..be25b8b3 100644 --- a/moonshot-api/src/main/java/org/moonshot/keyresult/service/converter/KRStateConverter.java +++ b/moonshot-api/src/main/java/org/moonshot/keyresult/service/converter/KRStateConverter.java @@ -1,6 +1,6 @@ package org.moonshot.keyresult.service.converter; -import org.moonshot.exception.global.common.MoonshotException; +import org.moonshot.exception.MoonshotException; import org.moonshot.keyresult.model.KRState; import org.moonshot.response.ErrorType; import org.springframework.core.convert.converter.Converter; diff --git a/moonshot-api/src/main/java/org/moonshot/keyresult/service/validator/KeyResultValidator.java b/moonshot-api/src/main/java/org/moonshot/keyresult/service/validator/KeyResultValidator.java index 83a4b698..ea7d891e 100644 --- a/moonshot-api/src/main/java/org/moonshot/keyresult/service/validator/KeyResultValidator.java +++ b/moonshot-api/src/main/java/org/moonshot/keyresult/service/validator/KeyResultValidator.java @@ -1,11 +1,13 @@ package org.moonshot.keyresult.service.validator; +import static org.moonshot.response.ErrorType.ACTIVE_KEY_RESULT_NUMBER_EXCEEDED; +import static org.moonshot.response.ErrorType.INVALID_KEY_RESULT_INDEX; +import static org.moonshot.response.ErrorType.INVALID_KEY_RESULT_PERIOD; + import java.time.LocalDate; import java.util.List; import org.moonshot.common.model.Period; -import org.moonshot.exception.keyresult.KeyResultInvalidIndexException; -import org.moonshot.exception.keyresult.KeyResultInvalidPeriodException; -import org.moonshot.exception.keyresult.KeyResultNumberExceededException; +import org.moonshot.exception.BadRequestException; public class KeyResultValidator { @@ -13,39 +15,39 @@ public class KeyResultValidator { public static void validateKeyResultIndex(final int index, final int requestIndex) { if (index != requestIndex) { - throw new KeyResultInvalidIndexException(); + throw new BadRequestException(INVALID_KEY_RESULT_INDEX); } } public static void validateKRPeriodWithInObjPeriod(final Period objPeriod, final LocalDate start, final LocalDate end) { if (start.isBefore(objPeriod.getStartAt()) || end.isAfter(objPeriod.getExpireAt()) || start.isAfter(objPeriod.getExpireAt()) || start.isAfter(end)) { - throw new KeyResultInvalidPeriodException(); + throw new BadRequestException(INVALID_KEY_RESULT_PERIOD); } } public static void validateActiveKRSizeExceeded(final int krListSize) { if (krListSize >= ACTIVE_KEY_RESULT_NUMBER) { - throw new KeyResultNumberExceededException(); + throw new BadRequestException(ACTIVE_KEY_RESULT_NUMBER_EXCEEDED); } } public static void validateIndexUnderMaximum(final int requestIndex, final int totalKRListSize) { if (requestIndex > totalKRListSize) { - throw new KeyResultInvalidIndexException(); + throw new BadRequestException(INVALID_KEY_RESULT_INDEX); } } public static void validateKeyResultPeriod(final Period objPeriod, final LocalDate start, final LocalDate end) { if (start.isAfter(end) || start.isBefore(objPeriod.getStartAt()) || start.isAfter(objPeriod.getExpireAt()) || end.isBefore(start) || end.isBefore(objPeriod.getStartAt()) || end.isAfter(objPeriod.getExpireAt())) { - throw new KeyResultInvalidPeriodException(); + throw new BadRequestException(INVALID_KEY_RESULT_PERIOD); } } public static void validateIndex(final Long keyResultCount, final Integer requestIndex) { if (keyResultCount <= requestIndex || requestIndex < 0) { - throw new KeyResultInvalidIndexException(); + throw new BadRequestException(INVALID_KEY_RESULT_INDEX); } } diff --git a/moonshot-api/src/main/java/org/moonshot/log/controller/LogApi.java b/moonshot-api/src/main/java/org/moonshot/log/controller/LogApi.java index c0eca92a..ff986bd7 100644 --- a/moonshot-api/src/main/java/org/moonshot/log/controller/LogApi.java +++ b/moonshot-api/src/main/java/org/moonshot/log/controller/LogApi.java @@ -9,9 +9,9 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -import java.security.Principal; import org.moonshot.log.dto.request.LogCreateRequestDto; import org.moonshot.response.MoonshotResponse; +import org.moonshot.user.model.LoginUser; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; @@ -26,7 +26,7 @@ public interface LogApi { content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "Log 생성") - public ResponseEntity> create(Principal principal, + public ResponseEntity> create(@LoginUser Long userId, @Parameter(in = ParameterIn.DEFAULT, name = "TaskSingleCreateRequest", description = "task 추가 요청 body") @RequestBody @Valid LogCreateRequestDto logCreateRequestDto); diff --git a/moonshot-api/src/main/java/org/moonshot/log/controller/LogController.java b/moonshot-api/src/main/java/org/moonshot/log/controller/LogController.java index 660b2d1e..fd37c665 100644 --- a/moonshot-api/src/main/java/org/moonshot/log/controller/LogController.java +++ b/moonshot-api/src/main/java/org/moonshot/log/controller/LogController.java @@ -1,16 +1,15 @@ package org.moonshot.log.controller; import jakarta.validation.Valid; -import java.security.Principal; import java.util.Optional; import lombok.RequiredArgsConstructor; -import org.moonshot.jwt.JwtTokenProvider; import org.moonshot.log.dto.request.LogCreateRequestDto; import org.moonshot.log.dto.response.AchieveResponseDto; import org.moonshot.log.service.LogService; import org.moonshot.model.Logging; import org.moonshot.response.MoonshotResponse; import org.moonshot.response.SuccessType; +import org.moonshot.user.model.LoginUser; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -27,11 +26,11 @@ public class LogController implements LogApi { @PostMapping @Logging(item = "Log", action = "Post") - public ResponseEntity> create(final Principal principal, @RequestBody @Valid final LogCreateRequestDto logCreateRequestDto) { - Optional response = logService.createRecordLog(JwtTokenProvider.getUserIdFromPrincipal(principal), logCreateRequestDto); + public ResponseEntity> create(@LoginUser Long userId, @RequestBody @Valid final LogCreateRequestDto logCreateRequestDto) { + Optional response = logService.createRecordLog(userId, logCreateRequestDto); + if (response.isPresent()) { - return ResponseEntity.status(HttpStatus.CREATED).body( - MoonshotResponse.success(SuccessType.POST_LOG_ACHIEVE_SUCCESS, response)); + return ResponseEntity.status(HttpStatus.CREATED).body(MoonshotResponse.success(SuccessType.POST_LOG_ACHIEVE_SUCCESS, response)); } return ResponseEntity.status(HttpStatus.CREATED).body(MoonshotResponse.success(SuccessType.POST_LOG_SUCCESS)); } diff --git a/moonshot-api/src/main/java/org/moonshot/log/service/LogService.java b/moonshot-api/src/main/java/org/moonshot/log/service/LogService.java index 14379f21..ae2b37a8 100644 --- a/moonshot-api/src/main/java/org/moonshot/log/service/LogService.java +++ b/moonshot-api/src/main/java/org/moonshot/log/service/LogService.java @@ -1,12 +1,17 @@ package org.moonshot.log.service; +import static org.moonshot.keyresult.service.validator.KeyResultValidator.isKeyResultAchieved; +import static org.moonshot.log.service.validator.LogValidator.isCreateLog; +import static org.moonshot.log.service.validator.LogValidator.validateLogNum; +import static org.moonshot.response.ErrorType.NOT_FOUND_KEY_RESULT; +import static org.moonshot.user.service.validator.UserValidator.validateUserAuthorization; + import java.text.NumberFormat; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; -import org.moonshot.exception.keyresult.KeyResultNotFoundException; -import org.moonshot.exception.log.InvalidLogValueException; +import org.moonshot.exception.NotFoundException; import org.moonshot.keyresult.dto.request.KeyResultCreateRequestDto; import org.moonshot.keyresult.dto.request.KeyResultCreateRequestInfoDto; import org.moonshot.keyresult.dto.request.KeyResultModifyRequestDto; @@ -22,11 +27,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import static org.moonshot.keyresult.service.validator.KeyResultValidator.isKeyResultAchieved; -import static org.moonshot.log.service.validator.LogValidator.isCreateLog; -import static org.moonshot.log.service.validator.LogValidator.validateLogNum; -import static org.moonshot.user.service.validator.UserValidator.validateUserAuthorization; - @Service @Transactional @@ -38,7 +38,7 @@ public class LogService { public Optional createRecordLog(final Long userId, final LogCreateRequestDto request) { KeyResult keyResult = keyResultRepository.findKeyResultAndObjective(request.keyResultId()) - .orElseThrow(KeyResultNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_KEY_RESULT)); validateUserAuthorization(keyResult.getObjective().getUser().getId(), userId); Optional prevLog = logRepository.findLatestLogByKeyResultId(LogState.RECORD, request.keyResultId()); long prevNum = -1; @@ -64,7 +64,7 @@ public Optional createRecordLog(final Long userId, final Log public Log createUpdateLog(final KeyResultModifyRequestDto request, final Long keyResultId) { KeyResult keyResult = keyResultRepository.findById(keyResultId) - .orElseThrow(KeyResultNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_KEY_RESULT)); return logRepository.save(Log.builder() .date(LocalDateTime.now()) .state(LogState.UPDATE) @@ -77,14 +77,14 @@ public Log createUpdateLog(final KeyResultModifyRequestDto request, final Long k public void createKRLog(final Object request, final Long keyResultId) { KeyResult keyResult = keyResultRepository.findById(keyResultId) - .orElseThrow(KeyResultNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_KEY_RESULT)); if (request instanceof KeyResultCreateRequestInfoDto) { KeyResultCreateRequestInfoDto dto = (KeyResultCreateRequestInfoDto) request; logRepository.save(Log.builder() .date(LocalDateTime.now()) .state(LogState.CREATE) - .currNum(dto.target()) + .currNum(dto.krTarget()) .content("") .keyResult(keyResult) .build()); diff --git a/moonshot-api/src/main/java/org/moonshot/log/service/validator/LogValidator.java b/moonshot-api/src/main/java/org/moonshot/log/service/validator/LogValidator.java index 364963f9..e073a19b 100644 --- a/moonshot-api/src/main/java/org/moonshot/log/service/validator/LogValidator.java +++ b/moonshot-api/src/main/java/org/moonshot/log/service/validator/LogValidator.java @@ -1,13 +1,14 @@ package org.moonshot.log.service.validator; -import org.moonshot.exception.log.InvalidLogValueException; +import org.moonshot.exception.BadRequestException; import org.moonshot.log.model.LogState; +import org.moonshot.response.ErrorType; public class LogValidator { public static void validateLogNum(Long requestNum, Long originNum) { if (requestNum.equals(originNum)) { - throw new InvalidLogValueException(); + throw new BadRequestException(ErrorType.INVALID_LOG_VALUE); } } diff --git a/moonshot-api/src/main/java/org/moonshot/objective/controller/IndexApi.java b/moonshot-api/src/main/java/org/moonshot/objective/controller/IndexApi.java index d2d0f9ce..3727ae08 100644 --- a/moonshot-api/src/main/java/org/moonshot/objective/controller/IndexApi.java +++ b/moonshot-api/src/main/java/org/moonshot/objective/controller/IndexApi.java @@ -7,9 +7,9 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -import java.security.Principal; import org.moonshot.objective.dto.request.ModifyIndexRequestDto; import org.moonshot.response.MoonshotResponse; +import org.moonshot.user.model.LoginUser; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; @@ -24,6 +24,6 @@ public interface IndexApi { @ApiResponse(responseCode = "404", description = "존재하지 않는 Objective입니다\t\n존재하지 않는 KeyResult입니다\t\n존재하지 않는 Task입니다", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "Objective, KeyResult, Task Index 변경") - public ResponseEntity> modifyIdx(Principal principal, @RequestBody @Valid ModifyIndexRequestDto request); + public ResponseEntity> modifyIdx(@LoginUser Long userId, @RequestBody @Valid ModifyIndexRequestDto request); } diff --git a/moonshot-api/src/main/java/org/moonshot/objective/controller/IndexController.java b/moonshot-api/src/main/java/org/moonshot/objective/controller/IndexController.java index 06e18448..1ff2f679 100644 --- a/moonshot-api/src/main/java/org/moonshot/objective/controller/IndexController.java +++ b/moonshot-api/src/main/java/org/moonshot/objective/controller/IndexController.java @@ -1,13 +1,12 @@ package org.moonshot.objective.controller; import jakarta.validation.Valid; -import java.security.Principal; import lombok.RequiredArgsConstructor; -import org.moonshot.jwt.JwtTokenProvider; import org.moonshot.objective.dto.request.ModifyIndexRequestDto; import org.moonshot.objective.model.IndexService; import org.moonshot.objective.service.IndexTargetProvider; import org.moonshot.response.MoonshotResponse; +import org.moonshot.user.model.LoginUser; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -22,9 +21,9 @@ public class IndexController implements IndexApi { private final IndexTargetProvider indexTargetProvider; @PatchMapping - public ResponseEntity> modifyIdx(final Principal principal, @RequestBody @Valid final ModifyIndexRequestDto request) { + public ResponseEntity> modifyIdx(@LoginUser Long userId, @RequestBody @Valid final ModifyIndexRequestDto request) { IndexService indexService = indexTargetProvider.getIndexService(request.target()); - indexService.modifyIdx(request, JwtTokenProvider.getUserIdFromPrincipal(principal)); + indexService.modifyIdx(request, userId); return ResponseEntity.noContent().build(); } diff --git a/moonshot-api/src/main/java/org/moonshot/objective/controller/ObjectiveApi.java b/moonshot-api/src/main/java/org/moonshot/objective/controller/ObjectiveApi.java index 03327ff8..c24bb36b 100644 --- a/moonshot-api/src/main/java/org/moonshot/objective/controller/ObjectiveApi.java +++ b/moonshot-api/src/main/java/org/moonshot/objective/controller/ObjectiveApi.java @@ -1,8 +1,6 @@ package org.moonshot.objective.controller; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -10,7 +8,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Nullable; import jakarta.validation.Valid; -import java.security.Principal; import org.moonshot.objective.dto.request.ModifyObjectiveRequestDto; import org.moonshot.objective.dto.request.OKRCreateRequestDto; import org.moonshot.objective.dto.response.DashboardResponseDto; @@ -18,6 +15,7 @@ import org.moonshot.objective.model.Category; import org.moonshot.objective.model.Criteria; import org.moonshot.response.MoonshotResponse; +import org.moonshot.user.model.LoginUser; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -33,8 +31,7 @@ interface ObjectiveApi { @ApiResponse(responseCode = "404", description = "존재하지 않는 유저입니다", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "O-KR 데이터 생성") - ResponseEntity> createObjective(@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Access Token", required = true, schema = @Schema(type = "string")) final Principal principal, - @RequestBody @Valid final OKRCreateRequestDto request); + ResponseEntity> createObjective(@LoginUser Long userId, @RequestBody @Valid final OKRCreateRequestDto request); @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "O-KR 트리 삭제를 성공하였습니다"), @@ -43,8 +40,7 @@ ResponseEntity> createObjective(@Parameter(in = ParameterIn. @ApiResponse(responseCode = "404", description = "존재하지 않는 Objective입니다", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "O-KR 데이터 삭제") - ResponseEntity> deleteObjective(@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Access Token", required = true, schema = @Schema(type = "string")) final Principal principal, - @PathVariable("objectiveId") final Long objectiveId); + ResponseEntity> deleteObjective(@LoginUser Long userId, @PathVariable("objectiveId") final Long objectiveId); @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Objective 수정에 성공하였습니다"), @@ -54,8 +50,7 @@ ResponseEntity> deleteObjective(@Paramete @ApiResponse(responseCode = "404", description = "존재하지 않는 Objective입니다", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "Objective 데이터 수정") - ResponseEntity modifyObjective(@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Access Token", required = true, schema = @Schema(type = "string")) final Principal principal, - @RequestBody final ModifyObjectiveRequestDto request); + ResponseEntity modifyObjective(@LoginUser Long userId, @RequestBody final ModifyObjectiveRequestDto request); @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "O-KR 목록 조회에 성공하였습니다"), @@ -64,8 +59,7 @@ ResponseEntity modifyObjective(@Parameter(in = ParameterIn.HEADER, name = "Au @ApiResponse(responseCode = "404", description = "존재하지 않는 Objective입니다", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "O-KR 목록 조회") - ResponseEntity> getObjectiveInDashboard(@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Access Token", required = true, schema = @Schema(type = "string")) final Principal principal, - @Nullable @RequestParam("objectiveId") final Long objectiveId); + ResponseEntity> getObjectiveInDashboard(@LoginUser Long userId, @Nullable @RequestParam("objectiveId") final Long objectiveId); @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "히스토리 조회에 성공하였습니다."), @@ -73,7 +67,7 @@ ResponseEntity> getObjectiveInDashboard(@ @ApiResponse(responseCode = "403", description = "해당 자원에 접근 권한이 없습니다.", content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))), }) @Operation(summary = "히스토리 목록 조회") - ResponseEntity> getObjectiveHistory(final Principal principal, @RequestParam(required = false) final Integer year, + ResponseEntity> getObjectiveHistory(@LoginUser Long userId, @RequestParam(required = false) final Integer year, @RequestParam(required = false) final Category category, @RequestParam(required = false) final Criteria criteria); diff --git a/moonshot-api/src/main/java/org/moonshot/objective/controller/ObjectiveController.java b/moonshot-api/src/main/java/org/moonshot/objective/controller/ObjectiveController.java index a7e6cc4d..3e95cef3 100644 --- a/moonshot-api/src/main/java/org/moonshot/objective/controller/ObjectiveController.java +++ b/moonshot-api/src/main/java/org/moonshot/objective/controller/ObjectiveController.java @@ -2,10 +2,8 @@ import jakarta.annotation.Nullable; import jakarta.validation.Valid; -import java.security.Principal; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.moonshot.jwt.JwtTokenProvider; import org.moonshot.model.Logging; import org.moonshot.objective.dto.request.ModifyObjectiveRequestDto; import org.moonshot.objective.dto.request.OKRCreateRequestDto; @@ -16,6 +14,7 @@ import org.moonshot.objective.service.ObjectiveService; import org.moonshot.response.MoonshotResponse; import org.moonshot.response.SuccessType; +import org.moonshot.user.model.LoginUser; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -38,38 +37,38 @@ public class ObjectiveController implements ObjectiveApi { @PostMapping @Logging(item = "Objective", action = "Post") - public ResponseEntity> createObjective(final Principal principal, @RequestBody @Valid final OKRCreateRequestDto request) { - objectiveService.createObjective(JwtTokenProvider.getUserIdFromPrincipal(principal), request); + public ResponseEntity> createObjective(@LoginUser Long userId, @RequestBody @Valid final OKRCreateRequestDto request) { + objectiveService.createObjective(userId, request); return ResponseEntity.status(HttpStatus.CREATED).body(MoonshotResponse.success(SuccessType.POST_OKR_SUCCESS)); } @DeleteMapping("/{objectiveId}") @Logging(item = "Objective", action = "Delete") - public ResponseEntity> deleteObjective(final Principal principal, @PathVariable("objectiveId") final Long objectiveId) { - DashboardResponseDto response = objectiveService.deleteObjective(JwtTokenProvider.getUserIdFromPrincipal(principal), objectiveId); + public ResponseEntity> deleteObjective(@LoginUser Long userId, @PathVariable("objectiveId") final Long objectiveId) { + DashboardResponseDto response = objectiveService.deleteObjective(userId, objectiveId); return ResponseEntity.ok(MoonshotResponse.success(SuccessType.DELETE_OBJECTIVE_SUCCESS, response)); } @PatchMapping @Logging(item = "Objective", action = "Patch") - public ResponseEntity modifyObjective(final Principal principal, @RequestBody final ModifyObjectiveRequestDto request) { - objectiveService.modifyObjective(JwtTokenProvider.getUserIdFromPrincipal(principal), request); + public ResponseEntity modifyObjective(@LoginUser Long userId, @RequestBody final ModifyObjectiveRequestDto request) { + objectiveService.modifyObjective(userId, request); return ResponseEntity.noContent().build(); } @GetMapping @Logging(item = "Objective", action = "Get") - public ResponseEntity> getObjectiveInDashboard(final Principal principal, @Nullable @RequestParam("objectiveId") final Long objectiveId) { - DashboardResponseDto response = objectiveService.getObjectiveInDashboard(JwtTokenProvider.getUserIdFromPrincipal(principal), objectiveId); + public ResponseEntity> getObjectiveInDashboard(@LoginUser Long userId, @Nullable @RequestParam("objectiveId") final Long objectiveId) { + DashboardResponseDto response = objectiveService.getObjectiveInDashboard(userId, objectiveId); return ResponseEntity.ok(MoonshotResponse.success(SuccessType.GET_OKR_LIST_SUCCESS, response)); } @GetMapping("/history") @Logging(item = "Objective", action = "Get") - public ResponseEntity> getObjectiveHistory(final Principal principal, @RequestParam(required = false) final Integer year, - @RequestParam(required = false) final Category category, - @RequestParam(required = false) final Criteria criteria) { - HistoryResponseDto response = objectiveService.getObjectiveHistory(JwtTokenProvider.getUserIdFromPrincipal(principal), year, category, criteria); + public ResponseEntity> getObjectiveHistory(@LoginUser Long userId, @RequestParam(required = false, name = "year") final Integer year, + @RequestParam(required = false, name = "category") final Category category, + @RequestParam(required = false, name = "criteria") final Criteria criteria) { + HistoryResponseDto response = objectiveService.getObjectiveHistory(userId, year, category, criteria); return ResponseEntity.ok(MoonshotResponse.success(SuccessType.OK, response)); } diff --git a/moonshot-api/src/main/java/org/moonshot/objective/dto/response/HistoryObjectiveListDto.java b/moonshot-api/src/main/java/org/moonshot/objective/dto/response/HistoryObjectiveListDto.java index 19bb8e27..2461b514 100644 --- a/moonshot-api/src/main/java/org/moonshot/objective/dto/response/HistoryObjectiveListDto.java +++ b/moonshot-api/src/main/java/org/moonshot/objective/dto/response/HistoryObjectiveListDto.java @@ -6,9 +6,9 @@ public record HistoryObjectiveListDto( Long objId, - String title, + String objTitle, String objCategory, - int progress, + int objProgress, String objPeriod, int objIdx, List krList diff --git a/moonshot-api/src/main/java/org/moonshot/objective/service/ObjectiveService.java b/moonshot-api/src/main/java/org/moonshot/objective/service/ObjectiveService.java index 43c02510..3c8b9281 100644 --- a/moonshot-api/src/main/java/org/moonshot/objective/service/ObjectiveService.java +++ b/moonshot-api/src/main/java/org/moonshot/objective/service/ObjectiveService.java @@ -1,7 +1,12 @@ package org.moonshot.objective.service; -import static org.moonshot.objective.service.validator.ObjectiveValidator.*; -import static org.moonshot.user.service.validator.UserValidator.*; +import static org.moonshot.objective.service.validator.ObjectiveValidator.validateActiveObjectiveSizeExceeded; +import static org.moonshot.objective.service.validator.ObjectiveValidator.validateIndexWithInRange; +import static org.moonshot.response.ErrorType.INVALID_EXPIRE_AT; +import static org.moonshot.response.ErrorType.NOT_FOUND_OBJECTIVE; +import static org.moonshot.response.ErrorType.NOT_FOUND_USER; +import static org.moonshot.response.ErrorType.REQUIRED_EXPIRE_AT; +import static org.moonshot.user.service.validator.UserValidator.validateUserAuthorization; import static org.moonshot.validator.IndexValidator.isIndexIncreased; import static org.moonshot.validator.IndexValidator.isSameIndex; @@ -13,10 +18,8 @@ import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.moonshot.common.model.Period; -import org.moonshot.exception.objective.DateInputRequiredException; -import org.moonshot.exception.objective.InvalidExpiredAtException; -import org.moonshot.exception.objective.ObjectiveNotFoundException; -import org.moonshot.exception.user.UserNotFoundException; +import org.moonshot.exception.BadRequestException; +import org.moonshot.exception.NotFoundException; import org.moonshot.keyresult.service.KeyResultService; import org.moonshot.objective.dto.request.ModifyIndexRequestDto; import org.moonshot.objective.dto.request.ModifyObjectiveRequestDto; @@ -24,7 +27,10 @@ import org.moonshot.objective.dto.response.DashboardResponseDto; import org.moonshot.objective.dto.response.HistoryResponseDto; import org.moonshot.objective.dto.response.ObjectiveGroupByYearDto; -import org.moonshot.objective.model.*; +import org.moonshot.objective.model.Category; +import org.moonshot.objective.model.Criteria; +import org.moonshot.objective.model.IndexService; +import org.moonshot.objective.model.Objective; import org.moonshot.objective.repository.ObjectiveRepository; import org.moonshot.user.model.User; import org.moonshot.user.repository.UserRepository; @@ -42,7 +48,7 @@ public class ObjectiveService implements IndexService { public void createObjective(final Long userId, final OKRCreateRequestDto request) { User user = userRepository.findById(userId) - .orElseThrow(UserNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_USER)); List objectives = objectiveRepository.findAllByUserId(userId); validateActiveObjectiveSizeExceeded(objectives.size()); @@ -60,7 +66,7 @@ public void createObjective(final Long userId, final OKRCreateRequestDto request public DashboardResponseDto deleteObjective(final Long userId, final Long objectiveId) { Objective objective = objectiveRepository.findObjectiveAndUserById(objectiveId) - .orElseThrow(ObjectiveNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_OBJECTIVE)); validateUserAuthorization(objective.getUser().getId(), userId); keyResultService.deleteKeyResult(objective); @@ -76,15 +82,15 @@ public void deleteAllObjective(final List userList) { public void modifyObjective(final Long userId, final ModifyObjectiveRequestDto request) { Objective objective = objectiveRepository.findObjectiveAndUserById(request.objectiveId()) - .orElseThrow(ObjectiveNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_OBJECTIVE)); validateUserAuthorization(objective.getUser().getId(), userId); objective.modifyClosed(request.isClosed()); if (!request.isClosed()) { if (request.expireAt() == null) { - throw new DateInputRequiredException(); + throw new BadRequestException(REQUIRED_EXPIRE_AT); } else if (request.expireAt().isBefore(LocalDate.now())) { - throw new InvalidExpiredAtException(); + throw new BadRequestException(INVALID_EXPIRE_AT); } objective.modifyPeriod(Period.of(objective.getPeriod().getStartAt(), request.expireAt())); } @@ -95,13 +101,13 @@ public DashboardResponseDto getObjectiveInDashboard(final Long userId, final Lon List objList = objectiveRepository.findAllByUserId(userId); if (objList.isEmpty()) { User user = userRepository.findById(userId) - .orElseThrow(UserNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_USER)); return DashboardResponseDto.ofNull(user.getNickname()); } Long treeId = objectiveId == null ? objList.get(0).getId() : objectiveId; Objective objective = objectiveRepository.findByIdWithKeyResultsAndTasks(treeId) - .orElseThrow(ObjectiveNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_OBJECTIVE)); validateUserAuthorization(objective.getUser().getId(), userId); return DashboardResponseDto.of(objective, objList, objective.getUser().getNickname()); @@ -143,7 +149,7 @@ public void modifyIdx(final ModifyIndexRequestDto request, final Long userId) { validateIndexWithInRange(objectiveCount, request.idx()); Objective objective = objectiveRepository.findObjectiveAndUserById(request.id()) - .orElseThrow(ObjectiveNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_OBJECTIVE)); validateUserAuthorization(objective.getUser().getId(), userId); int prevIdx = objective.getIdx(); diff --git a/moonshot-api/src/main/java/org/moonshot/objective/service/converter/CategoryConverter.java b/moonshot-api/src/main/java/org/moonshot/objective/service/converter/CategoryConverter.java index f3faecd7..7a7ccc4b 100644 --- a/moonshot-api/src/main/java/org/moonshot/objective/service/converter/CategoryConverter.java +++ b/moonshot-api/src/main/java/org/moonshot/objective/service/converter/CategoryConverter.java @@ -1,6 +1,6 @@ package org.moonshot.objective.service.converter; -import org.moonshot.exception.global.common.MoonshotException; +import org.moonshot.exception.MoonshotException; import org.moonshot.objective.model.Category; import org.moonshot.response.ErrorType; import org.springframework.core.convert.converter.Converter; diff --git a/moonshot-api/src/main/java/org/moonshot/objective/service/converter/CriteriaConverter.java b/moonshot-api/src/main/java/org/moonshot/objective/service/converter/CriteriaConverter.java index 0a8ce843..b3f15ab9 100644 --- a/moonshot-api/src/main/java/org/moonshot/objective/service/converter/CriteriaConverter.java +++ b/moonshot-api/src/main/java/org/moonshot/objective/service/converter/CriteriaConverter.java @@ -1,6 +1,6 @@ package org.moonshot.objective.service.converter; -import org.moonshot.exception.global.common.MoonshotException; +import org.moonshot.exception.MoonshotException; import org.moonshot.objective.model.Criteria; import org.moonshot.response.ErrorType; import org.springframework.core.convert.converter.Converter; diff --git a/moonshot-api/src/main/java/org/moonshot/objective/service/validator/ObjectiveValidator.java b/moonshot-api/src/main/java/org/moonshot/objective/service/validator/ObjectiveValidator.java index 994eb5dd..73a0a545 100644 --- a/moonshot-api/src/main/java/org/moonshot/objective/service/validator/ObjectiveValidator.java +++ b/moonshot-api/src/main/java/org/moonshot/objective/service/validator/ObjectiveValidator.java @@ -1,7 +1,9 @@ package org.moonshot.objective.service.validator; -import org.moonshot.exception.objective.ObjectiveInvalidIndexException; -import org.moonshot.exception.objective.ObjectiveNumberExceededException; +import static org.moonshot.response.ErrorType.ACTIVE_OBJECTIVE_NUMBER_EXCEEDED; +import static org.moonshot.response.ErrorType.INVALID_OBJECTIVE_INDEX; + +import org.moonshot.exception.BadRequestException; public class ObjectiveValidator { @@ -9,13 +11,13 @@ public class ObjectiveValidator { public static void validateIndexWithInRange(final Long objectiveCount, final int idx) { if ((objectiveCount <= idx) || (idx < 0)) { - throw new ObjectiveInvalidIndexException(); + throw new BadRequestException(INVALID_OBJECTIVE_INDEX); } } public static void validateActiveObjectiveSizeExceeded(final int objListSize) { if (objListSize >= ACTIVE_OBJECTIVE_NUMBER) { - throw new ObjectiveNumberExceededException(); + throw new BadRequestException(ACTIVE_OBJECTIVE_NUMBER_EXCEEDED); } } diff --git a/moonshot-api/src/main/java/org/moonshot/task/controller/TaskApi.java b/moonshot-api/src/main/java/org/moonshot/task/controller/TaskApi.java index b207fa96..2b75ca57 100644 --- a/moonshot-api/src/main/java/org/moonshot/task/controller/TaskApi.java +++ b/moonshot-api/src/main/java/org/moonshot/task/controller/TaskApi.java @@ -9,9 +9,9 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -import java.security.Principal; import org.moonshot.response.MoonshotResponse; import org.moonshot.task.dto.request.TaskSingleCreateRequestDto; +import org.moonshot.user.model.LoginUser; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -25,7 +25,7 @@ public interface TaskApi { content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "Task 추가") - public ResponseEntity> createTask(Principal principal, + public ResponseEntity> createTask(@LoginUser Long userId, @Parameter(in = ParameterIn.DEFAULT, name = "TaskSingleCreateRequest", description = "task 추가 요청 body") @RequestBody @Valid TaskSingleCreateRequestDto request); @@ -36,7 +36,7 @@ public ResponseEntity> createTask(Principal principal, content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "Task 삭제") - public ResponseEntity deleteTask(Principal principal, @PathVariable("taskId") Long taskId); + public ResponseEntity deleteTask(@LoginUser Long userId, @PathVariable("taskId") Long taskId); } diff --git a/moonshot-api/src/main/java/org/moonshot/task/controller/TaskController.java b/moonshot-api/src/main/java/org/moonshot/task/controller/TaskController.java index 0c8bc7a7..226a033a 100644 --- a/moonshot-api/src/main/java/org/moonshot/task/controller/TaskController.java +++ b/moonshot-api/src/main/java/org/moonshot/task/controller/TaskController.java @@ -3,16 +3,20 @@ import static org.moonshot.response.SuccessType.POST_TASK_SUCCESS; import jakarta.validation.Valid; -import java.security.Principal; import lombok.RequiredArgsConstructor; -import org.moonshot.jwt.JwtTokenProvider; import org.moonshot.model.Logging; import org.moonshot.response.MoonshotResponse; import org.moonshot.task.dto.request.TaskSingleCreateRequestDto; import org.moonshot.task.service.TaskService; +import org.moonshot.user.model.LoginUser; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +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; @RestController @RequiredArgsConstructor @@ -23,15 +27,15 @@ public class TaskController implements TaskApi { @PostMapping @Logging(item = "Task", action = "Post") - public ResponseEntity> createTask(final Principal principal, @RequestBody @Valid final TaskSingleCreateRequestDto request) { - taskService.createTask(request, JwtTokenProvider.getUserIdFromPrincipal(principal)); + public ResponseEntity> createTask(@LoginUser Long userId, @RequestBody @Valid final TaskSingleCreateRequestDto request) { + taskService.createTask(request, userId); return ResponseEntity.status(HttpStatus.CREATED).body(MoonshotResponse.success(POST_TASK_SUCCESS)); } @DeleteMapping("/{taskId}") @Logging(item = "Task", action = "Delete") - public ResponseEntity deleteTask (final Principal principal, @PathVariable("taskId") final Long taskId) { - taskService.deleteTask(JwtTokenProvider.getUserIdFromPrincipal(principal), taskId); + public ResponseEntity deleteTask (@LoginUser Long userId, @PathVariable("taskId") final Long taskId) { + taskService.deleteTask(userId, taskId); return ResponseEntity.noContent().build(); } diff --git a/moonshot-api/src/main/java/org/moonshot/task/dto/request/TaskCreateRequestDto.java b/moonshot-api/src/main/java/org/moonshot/task/dto/request/TaskCreateRequestDto.java index 873b1925..17b8fc0c 100644 --- a/moonshot-api/src/main/java/org/moonshot/task/dto/request/TaskCreateRequestDto.java +++ b/moonshot-api/src/main/java/org/moonshot/task/dto/request/TaskCreateRequestDto.java @@ -6,9 +6,9 @@ public record TaskCreateRequestDto( @Size(max = 30, message = "Task는 30자 이하여야 합니다.") - String title, + String taskTitle, @NotNull(message = "KR 순서를 입력해주세요") @Range(min = 0, max = 2, message = "Task의 순서는 0부터 2까지로 설정할 수 있습니다.") - Integer idx + Integer taskIdx ) { } diff --git a/moonshot-api/src/main/java/org/moonshot/task/dto/response/TaskResponseDto.java b/moonshot-api/src/main/java/org/moonshot/task/dto/response/TaskResponseDto.java index 3016c22b..78991e30 100644 --- a/moonshot-api/src/main/java/org/moonshot/task/dto/response/TaskResponseDto.java +++ b/moonshot-api/src/main/java/org/moonshot/task/dto/response/TaskResponseDto.java @@ -4,9 +4,9 @@ import org.moonshot.task.model.Task; public record TaskResponseDto( - Long id, - String title, - Integer idx + Long taskId, + String taskTitle, + Integer taskIdx ) { public static List of(List taskList) { return taskList.stream().map(task -> new TaskResponseDto( diff --git a/moonshot-api/src/main/java/org/moonshot/task/service/TaskService.java b/moonshot-api/src/main/java/org/moonshot/task/service/TaskService.java index 6fa3c143..b11fe20d 100644 --- a/moonshot-api/src/main/java/org/moonshot/task/service/TaskService.java +++ b/moonshot-api/src/main/java/org/moonshot/task/service/TaskService.java @@ -1,8 +1,17 @@ package org.moonshot.task.service; +import static org.moonshot.response.ErrorType.NOT_FOUND_KEY_RESULT; +import static org.moonshot.response.ErrorType.NOT_FOUND_TASK; +import static org.moonshot.task.service.validator.TaskValidator.validateActiveTaskSizeExceeded; +import static org.moonshot.task.service.validator.TaskValidator.validateIndex; +import static org.moonshot.task.service.validator.TaskValidator.validateIndexUnderMaximum; +import static org.moonshot.user.service.validator.UserValidator.validateUserAuthorization; +import static org.moonshot.validator.IndexValidator.isIndexIncreased; +import static org.moonshot.validator.IndexValidator.isSameIndex; + import java.util.List; import lombok.RequiredArgsConstructor; -import org.moonshot.exception.task.TaskNotFoundException; +import org.moonshot.exception.NotFoundException; import org.moonshot.keyresult.model.KeyResult; import org.moonshot.keyresult.repository.KeyResultRepository; import org.moonshot.objective.dto.request.ModifyIndexRequestDto; @@ -14,11 +23,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import static org.moonshot.task.service.validator.TaskValidator.*; -import static org.moonshot.user.service.validator.UserValidator.validateUserAuthorization; -import static org.moonshot.validator.IndexValidator.isIndexIncreased; -import static org.moonshot.validator.IndexValidator.isSameIndex; - @Service @Transactional @RequiredArgsConstructor @@ -28,7 +32,7 @@ public class TaskService implements IndexService { private final TaskRepository taskRepository; public void createTask(final TaskSingleCreateRequestDto request, final Long userId) { KeyResult keyResult = keyResultRepository.findKeyResultAndObjective(request.keyResultId()) - .orElseThrow(); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_KEY_RESULT)); validateUserAuthorization(keyResult.getObjective().getUser().getId(), userId); List taskList = taskRepository.findAllByKeyResultOrderByIdx(keyResult); @@ -50,10 +54,10 @@ public void saveTask(final KeyResult keyResult, final TaskSingleCreateRequestDto } public void saveTask(final KeyResult keyResult, final TaskCreateRequestDto request) { - if (!request.title().isEmpty()) { + if (!request.taskTitle().isEmpty()) { taskRepository.save(Task.builder() - .title(request.title()) - .idx(request.idx()) + .title(request.taskTitle()) + .idx(request.taskIdx()) .keyResult(keyResult) .build()); } @@ -62,7 +66,7 @@ public void saveTask(final KeyResult keyResult, final TaskCreateRequestDto reque @Override public void modifyIdx(final ModifyIndexRequestDto request, final Long userId) { Task task = taskRepository.findTaskWithFetchJoin(request.id()) - .orElseThrow(TaskNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_TASK)); validateUserAuthorization(task.getKeyResult().getObjective().getUser().getId(), userId); Long taskCount = taskRepository.countAllByKeyResultId(task.getKeyResult().getId()); @@ -82,7 +86,7 @@ public void modifyIdx(final ModifyIndexRequestDto request, final Long userId) { public void deleteTask(final Long userId, Long taskId) { Task task = taskRepository.findTaskWithFetchJoin(taskId) - .orElseThrow(TaskNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_TASK)); validateUserAuthorization(task.getKeyResult().getObjective().getUser().getId(), userId); taskRepository.deleteById(taskId); diff --git a/moonshot-api/src/main/java/org/moonshot/task/service/validator/TaskValidator.java b/moonshot-api/src/main/java/org/moonshot/task/service/validator/TaskValidator.java index 091cc4d0..4ea68005 100644 --- a/moonshot-api/src/main/java/org/moonshot/task/service/validator/TaskValidator.java +++ b/moonshot-api/src/main/java/org/moonshot/task/service/validator/TaskValidator.java @@ -1,7 +1,9 @@ package org.moonshot.task.service.validator; -import org.moonshot.exception.task.TaskInvalidIndexException; -import org.moonshot.exception.task.TaskNumberExceededException; +import static org.moonshot.response.ErrorType.ACTIVE_TASK_NUMBER_EXCEEDED; +import static org.moonshot.response.ErrorType.INVALID_TASK_INDEX; + +import org.moonshot.exception.BadRequestException; public class TaskValidator { @@ -9,25 +11,25 @@ public class TaskValidator { public static void validateTaskIndex(final int index, final int requestIndex) { if (index != requestIndex) { - throw new TaskInvalidIndexException(); + throw new BadRequestException(INVALID_TASK_INDEX); } } public static void validateActiveTaskSizeExceeded(final int taskListSize) { if (taskListSize >= ACTIVE_TASK_NUMBER) { - throw new TaskNumberExceededException(); + throw new BadRequestException(ACTIVE_TASK_NUMBER_EXCEEDED); } } public static void validateIndexUnderMaximum(final int requestIndex, final int totalTaskListSize) { if (requestIndex > totalTaskListSize) { - throw new TaskInvalidIndexException(); + throw new BadRequestException(INVALID_TASK_INDEX); } } public static void validateIndex(final Long taskCount, final Integer requestIndex) { if (taskCount <= requestIndex || requestIndex < 0) { - throw new TaskInvalidIndexException(); + throw new BadRequestException(INVALID_TASK_INDEX); } } diff --git a/moonshot-api/src/main/java/org/moonshot/user/controller/UserApi.java b/moonshot-api/src/main/java/org/moonshot/user/controller/UserApi.java index 7129829a..030dc22c 100644 --- a/moonshot-api/src/main/java/org/moonshot/user/controller/UserApi.java +++ b/moonshot-api/src/main/java/org/moonshot/user/controller/UserApi.java @@ -12,13 +12,13 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import java.io.IOException; -import java.security.Principal; import org.moonshot.jwt.TokenResponse; import org.moonshot.response.MoonshotResponse; import org.moonshot.user.dto.request.SocialLoginRequest; import org.moonshot.user.dto.request.UserInfoRequest; import org.moonshot.user.dto.response.SocialLoginResponse; import org.moonshot.user.dto.response.UserInfoResponse; +import org.moonshot.user.model.LoginUser; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; @@ -38,7 +38,7 @@ public ResponseEntity> login(@Parameter(in @ApiResponse(responseCode = "200", description = "로그아웃에 성공하였습니다.") @Operation(summary = "로그아웃") - public ResponseEntity> logout(Principal principal); + public ResponseEntity> logout(@LoginUser Long userId); @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "로그아웃에 성공하였습니다."), @@ -46,7 +46,7 @@ public ResponseEntity> login(@Parameter(in content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "로그아웃") - public ResponseEntity withdrawal(Principal principal); + public ResponseEntity withdrawal(@LoginUser Long userId); @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "사용자 프로필 업데이트에 성공하였습니다."), @@ -54,7 +54,7 @@ public ResponseEntity> login(@Parameter(in content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "프로필 수정") - public ResponseEntity modifyProfile(Principal principal, + public ResponseEntity modifyProfile(@LoginUser Long userId, @Parameter(in = ParameterIn.DEFAULT, name = "UserInfoRequest", description = "유저 정보 요청 body") @Valid @RequestBody UserInfoRequest userInfoRequest); @@ -64,10 +64,6 @@ public ResponseEntity modifyProfile(Principal principal, content = @Content(mediaType = "application/json", schema = @Schema(implementation = MoonshotResponse.class))) }) @Operation(summary = "프로필 조회") - public ResponseEntity> getMyProfile(Principal principal); - - @ApiResponse(responseCode = "200", description = "구글 로그인에 성공하였습니다.") - @Operation(summary = "구글 로그인") - public String authTest(HttpServletRequest request, HttpServletResponse response); + public ResponseEntity> getMyProfile(@LoginUser Long userId); } diff --git a/moonshot-api/src/main/java/org/moonshot/user/controller/UserController.java b/moonshot-api/src/main/java/org/moonshot/user/controller/UserController.java index c9e73539..0f7586bc 100644 --- a/moonshot-api/src/main/java/org/moonshot/user/controller/UserController.java +++ b/moonshot-api/src/main/java/org/moonshot/user/controller/UserController.java @@ -4,10 +4,8 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import java.io.IOException; -import java.security.Principal; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.moonshot.jwt.JwtTokenProvider; import org.moonshot.jwt.TokenResponse; import org.moonshot.model.Logging; import org.moonshot.response.MoonshotResponse; @@ -16,6 +14,7 @@ import org.moonshot.user.dto.request.UserInfoRequest; import org.moonshot.user.dto.response.SocialLoginResponse; import org.moonshot.user.dto.response.UserInfoResponse; +import org.moonshot.user.model.LoginUser; import org.moonshot.user.service.UserService; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; @@ -33,14 +32,6 @@ @RequiredArgsConstructor @RequestMapping("/v1/user") public class UserController implements UserApi { - @Value("${google.client-id}") - private String googleClientId; - - @Value("${google.client-secret}") - private String googleClientSecret; - - @Value("${google.redirect-url}") - private String googleRedirectUrl; private final UserService userService; @@ -59,51 +50,29 @@ public ResponseEntity> reissue(@RequestHeader("A @PostMapping("/log-out") @Logging(item = "User", action = "Post") - public ResponseEntity> logout(final Principal principal) { - userService.logout(JwtTokenProvider.getUserIdFromPrincipal(principal)); + public ResponseEntity> logout(@LoginUser Long userId) { + userService.logout(userId); return ResponseEntity.ok(MoonshotResponse.success(SuccessType.POST_LOGOUT_SUCCESS)); } @DeleteMapping("/withdrawal") @Logging(item = "User", action = "Delete") - public ResponseEntity withdrawal(final Principal principal) { - userService.withdrawal(JwtTokenProvider.getUserIdFromPrincipal(principal)); + public ResponseEntity withdrawal(@LoginUser Long userId) { + userService.withdrawal(userId); return ResponseEntity.noContent().build(); } @PatchMapping("/profile") @Logging(item = "User", action = "Patch") - public ResponseEntity modifyProfile(final Principal principal, @Valid @RequestBody final UserInfoRequest userInfoRequest) { - userService.modifyProfile(JwtTokenProvider.getUserIdFromPrincipal(principal), userInfoRequest); + public ResponseEntity modifyProfile(@LoginUser Long userId, @Valid @RequestBody final UserInfoRequest userInfoRequest) { + userService.modifyProfile(userId, userInfoRequest); return ResponseEntity.noContent().build(); } @GetMapping("/mypage") @Logging(item = "User", action = "Get") - public ResponseEntity> getMyProfile(final Principal principal) { - return ResponseEntity.ok(MoonshotResponse.success(SuccessType.GET_PROFILE_SUCCESS, userService.getMyProfile(JwtTokenProvider.getUserIdFromPrincipal(principal)))); + public ResponseEntity> getMyProfile(@LoginUser Long userId) { + return ResponseEntity.ok(MoonshotResponse.success(SuccessType.GET_PROFILE_SUCCESS, userService.getMyProfile(userId))); } - @GetMapping("/googleLogin") - @Logging(item = "User", action = "Get") - public String authTest(final HttpServletRequest request, final HttpServletResponse response) { - String redirectURL = "https://accounts.google.com/o/oauth2/v2/auth?client_id=" + googleClientId - + "&redirect_uri=" + googleRedirectUrl + "&response_type=code&scope=email profile"; - try { - response.sendRedirect(redirectURL); - } catch (Exception e) { - log.info("authTest = {}", e); - } - - return "SUCCESS"; - } - -// @GetMapping("/login/oauth2/code/kakao") -// public String kakaoSuccess(@RequestParam String code) { -// return code; -// } -// -// @GetMapping("/login/oauth2/code/google") -// public String googleSuccess(@RequestParam String code, @RequestParam String scope, @RequestParam String prompt) { return code; } - } \ No newline at end of file diff --git a/moonshot-api/src/main/java/org/moonshot/user/service/UserService.java b/moonshot-api/src/main/java/org/moonshot/user/service/UserService.java index 342ef5f6..c0b28c98 100644 --- a/moonshot-api/src/main/java/org/moonshot/user/service/UserService.java +++ b/moonshot-api/src/main/java/org/moonshot/user/service/UserService.java @@ -1,18 +1,19 @@ package org.moonshot.user.service; -import static org.moonshot.user.service.validator.UserValidator.*; +import static org.moonshot.response.ErrorType.NOT_FOUND_USER; +import static org.moonshot.user.service.validator.UserValidator.hasChange; +import static org.moonshot.user.service.validator.UserValidator.isNewUser; +import static org.moonshot.user.service.validator.UserValidator.validateUserAuthorization; import static org.moonshot.util.MDCUtil.USER_REQUEST_ORIGIN; import static org.moonshot.util.MDCUtil.get; -import java.io.IOException; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.moonshot.discord.DiscordAppender; -import org.moonshot.exception.global.external.discord.ErrorLogAppenderException; -import org.moonshot.exception.user.UserNotFoundException; +import org.moonshot.discord.SignUpEvent; +import org.moonshot.exception.NotFoundException; import org.moonshot.jwt.JwtTokenProvider; import org.moonshot.jwt.TokenResponse; import org.moonshot.objective.service.ObjectiveService; @@ -24,7 +25,6 @@ import org.moonshot.openfeign.google.GoogleAuthApiClient; import org.moonshot.openfeign.kakao.KakaoApiClient; import org.moonshot.openfeign.kakao.KakaoAuthApiClient; -import org.moonshot.security.UserAuthentication; import org.moonshot.user.dto.request.SocialLoginRequest; import org.moonshot.user.dto.request.UserInfoRequest; import org.moonshot.user.dto.response.SocialLoginResponse; @@ -32,6 +32,7 @@ import org.moonshot.user.model.User; import org.moonshot.user.repository.UserRepository; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -59,6 +60,7 @@ public class UserService { private final UserRepository userRepository; private final ObjectiveService objectiveService; + private final ApplicationEventPublisher eventPublisher; private final GoogleAuthApiClient googleAuthApiClient; private final GoogleApiClient googleApiClient; @@ -66,7 +68,7 @@ public class UserService { private final KakaoApiClient kakaoApiClient; private final JwtTokenProvider jwtTokenProvider; - public SocialLoginResponse login(final SocialLoginRequest request) throws IOException { + public SocialLoginResponse login(final SocialLoginRequest request) { return switch (request.socialPlatform().getValue()) { case "google" -> googleLogin(request); case "kakao" -> kakaoLogin(request); @@ -74,7 +76,7 @@ public SocialLoginResponse login(final SocialLoginRequest request) throws IOExce }; } - public SocialLoginResponse googleLogin(final SocialLoginRequest request) throws IOException { + public SocialLoginResponse googleLogin(final SocialLoginRequest request) { GoogleTokenResponse tokenResponse = googleAuthApiClient.googleAuth( request.code(), googleClientId, @@ -94,13 +96,12 @@ public SocialLoginResponse googleLogin(final SocialLoginRequest request) throws .email(userResponse.email()) .build()); user = newUser; - sendDiscordAlert(newUser); + publishSignUpEvent(newUser); } else { user = findUser.get(); user.resetDeleteAt(); } - UserAuthentication userAuthentication = new UserAuthentication(user.getId(), null, null); - TokenResponse token = new TokenResponse(jwtTokenProvider.generateAccessToken(userAuthentication), jwtTokenProvider.generateRefreshToken(userAuthentication)); + TokenResponse token = new TokenResponse(jwtTokenProvider.generateAccessToken(user.getId()), jwtTokenProvider.generateRefreshToken(user.getId())); return SocialLoginResponse.of(user.getId(), user.getName(), token); } @@ -124,13 +125,12 @@ public SocialLoginResponse kakaoLogin(final SocialLoginRequest request) { .email(null) .build()); user = newUser; - sendDiscordAlert(newUser); + publishSignUpEvent(newUser); } else { user = findUser.get(); user.resetDeleteAt(); } - UserAuthentication userAuthentication = new UserAuthentication(user.getId(), null, null); - TokenResponse token = new TokenResponse(jwtTokenProvider.generateAccessToken(userAuthentication), jwtTokenProvider.generateRefreshToken(userAuthentication)); + TokenResponse token = new TokenResponse(jwtTokenProvider.generateAccessToken(user.getId()), jwtTokenProvider.generateRefreshToken(user.getId())); return SocialLoginResponse.of(user.getId(), user.getName(), token); } @@ -138,13 +138,12 @@ public TokenResponse reissue(final String refreshToken) { String token = refreshToken.substring("Bearer ".length()); Long userId = jwtTokenProvider.validateRefreshToken(token); jwtTokenProvider.deleteRefreshToken(userId); - UserAuthentication userAuthentication = new UserAuthentication(userId, null, null); - return jwtTokenProvider.reissuedToken(userAuthentication); + return jwtTokenProvider.reissuedToken(userId); } public void logout(final Long userId) { User user = userRepository.findById(userId) - .orElseThrow(UserNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_USER)); validateUserAuthorization(user.getId(), userId); jwtTokenProvider.deleteRefreshToken(userId); @@ -152,7 +151,7 @@ public void logout(final Long userId) { public void withdrawal(final Long userId) { User user = userRepository.findById(userId) - .orElseThrow(UserNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_USER)); validateUserAuthorization(user.getId(), userId); user.setDeleteAt(); @@ -160,7 +159,7 @@ public void withdrawal(final Long userId) { public void modifyProfile(final Long userId, final UserInfoRequest request) { User user = userRepository.findById(userId) - .orElseThrow(UserNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_USER)); validateUserAuthorization(user.getId(), userId); if (hasChange(request.nickname())) { @@ -173,18 +172,19 @@ public void modifyProfile(final Long userId, final UserInfoRequest request) { public UserInfoResponse getMyProfile(final Long userId) { User user = userRepository.findById(userId) - .orElseThrow(UserNotFoundException::new); + .orElseThrow(() -> new NotFoundException(NOT_FOUND_USER)); return UserInfoResponse.of(user); } @Transactional(propagation = Propagation.REQUIRES_NEW) - public void sendDiscordAlert(final User user) { - try { - DiscordAppender discordAppender = new DiscordAppender(); - discordAppender.signInAppend(user.getName(), user.getEmail() == null ? "" : user.getEmail(), user.getSocialPlatform().getValue(), LocalDateTime.now(), user.getProfileImage()); - } catch (ErrorLogAppenderException e) { - log.error("{}", e.getErrorType().getMessage()); - } + public void publishSignUpEvent(final User user) { + eventPublisher.publishEvent(SignUpEvent.of( + user.getName(), + user.getEmail() == null ? "" : user.getEmail(), + user.getSocialPlatform().toString(), + LocalDateTime.now(), + user.getProfileImage() + )); } public void softDeleteUser(LocalDateTime currentDate) { diff --git a/moonshot-api/src/main/java/org/moonshot/user/service/validator/UserValidator.java b/moonshot-api/src/main/java/org/moonshot/user/service/validator/UserValidator.java index ee46a7aa..0dde45ad 100644 --- a/moonshot-api/src/main/java/org/moonshot/user/service/validator/UserValidator.java +++ b/moonshot-api/src/main/java/org/moonshot/user/service/validator/UserValidator.java @@ -1,6 +1,6 @@ package org.moonshot.user.service.validator; -import org.moonshot.exception.global.auth.AccessDeniedException; +import org.moonshot.exception.ForbiddenException; import org.moonshot.user.model.User; import java.util.Optional; @@ -9,7 +9,7 @@ public class UserValidator { public static void validateUserAuthorization(final Long userEntityId, final Long userId) { if (!userEntityId.equals(userId)) { - throw new AccessDeniedException(); + throw new ForbiddenException(); } } diff --git a/moonshot-api/src/test/java/org/moonshot/objective/service/ObjectiveServiceTest.java b/moonshot-api/src/test/java/org/moonshot/objective/service/ObjectiveServiceTest.java index 865cdfd5..52a40ca5 100644 --- a/moonshot-api/src/test/java/org/moonshot/objective/service/ObjectiveServiceTest.java +++ b/moonshot-api/src/test/java/org/moonshot/objective/service/ObjectiveServiceTest.java @@ -198,7 +198,7 @@ static void setUp() { ObjectiveGroupByYearDto dto = response.groups().get(0); assertThat(dto.year()).isEqualTo(2023); assertThat(dto.objList().size()).isEqualTo(2); - assertThat(dto.objList().get(0).title()).isEqualTo("Objective 2"); + assertThat(dto.objList().get(0).objTitle()).isEqualTo("Objective 2"); } } \ No newline at end of file diff --git a/moonshot-auth/build.gradle b/moonshot-auth/build.gradle index 181573b7..effb204d 100644 --- a/moonshot-auth/build.gradle +++ b/moonshot-auth/build.gradle @@ -3,13 +3,11 @@ jar { enabled = true } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' //External API implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' - //Spring Security - implementation 'org.springframework.boot:spring-boot-starter-security' - //JWT implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5' implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5' @@ -19,6 +17,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-redis:3.2.1' implementation project(":moonshot-common") + implementation project(":moonshot-domain") } ext { diff --git a/moonshot-auth/src/main/java/org/moonshot/jwt/JwtTokenProvider.java b/moonshot-auth/src/main/java/org/moonshot/jwt/JwtTokenProvider.java index cbb95d8d..969e0ac9 100644 --- a/moonshot-auth/src/main/java/org/moonshot/jwt/JwtTokenProvider.java +++ b/moonshot-auth/src/main/java/org/moonshot/jwt/JwtTokenProvider.java @@ -1,5 +1,13 @@ package org.moonshot.jwt; +import static org.moonshot.response.ErrorType.DISCORD_LOG_APPENDER; +import static org.moonshot.response.ErrorType.EXPIRED_TOKEN; +import static org.moonshot.response.ErrorType.INVALID_REFRESH_TOKEN; +import static org.moonshot.response.ErrorType.UNKNOWN_TOKEN; +import static org.moonshot.response.ErrorType.UNSUPPORTED_TOKEN; +import static org.moonshot.response.ErrorType.WRONG_SIGNATURE_TOKEN; +import static org.moonshot.response.ErrorType.WRONG_TYPE_TOKEN; + import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Header; @@ -10,19 +18,18 @@ import io.jsonwebtoken.security.SignatureException; import jakarta.annotation.PostConstruct; import java.nio.charset.StandardCharsets; -import java.security.Principal; import java.util.Base64; import java.util.Date; -import java.util.Objects; import java.util.concurrent.TimeUnit; import javax.crypto.SecretKey; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.moonshot.constants.JWTConstants; -import org.moonshot.exception.global.auth.InvalidAuthException; -import org.moonshot.exception.global.auth.InvalidRefreshTokenException; -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; +import org.moonshot.exception.InternalServerException; +import org.moonshot.exception.UnauthorizedException; +import org.moonshot.security.UserAuthentication; +import org.moonshot.security.service.UserPrincipalDetailsService; +import org.moonshot.user.model.UserPrincipal; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; @@ -36,6 +43,7 @@ public class JwtTokenProvider { private final RedisTemplate redisTemplate; + private final UserPrincipalDetailsService userPrincipalDetailsService; @Value("${jwt.secret}") private String JWT_SECRET; @@ -45,19 +53,20 @@ protected void init() { JWT_SECRET = Base64.getEncoder().encodeToString(JWT_SECRET.getBytes(StandardCharsets.UTF_8)); } - public TokenResponse reissuedToken(Authentication authentication) { + public TokenResponse reissuedToken(Long userId) { return TokenResponse.of( - generateAccessToken(authentication), - generateRefreshToken(authentication)); + generateAccessToken(userId), + generateRefreshToken(userId)); } - public String generateAccessToken(Authentication authentication) { + public String generateAccessToken(Long userId) { final Date now = new Date(); final Claims claims = Jwts.claims() .setIssuedAt(now) .setExpiration(new Date(now.getTime() + JWTConstants.ACCESS_TOKEN_EXPIRATION_TIME)); - claims.put(JWTConstants.USER_ID, authentication.getPrincipal()); + claims.put(JWTConstants.USER_ID, userId); + claims.put(JWTConstants.TOKEN_TYPE, JWTConstants.ACCESS_TOKEN); return Jwts.builder() .setHeaderParam(Header.TYPE, Header.JWT_TYPE) @@ -66,13 +75,14 @@ public String generateAccessToken(Authentication authentication) { .compact(); } - public String generateRefreshToken(Authentication authentication) { + public String generateRefreshToken(Long userId) { final Date now = new Date(); final Claims claims = Jwts.claims() .setIssuedAt(now) .setExpiration(new Date(now.getTime() + JWTConstants.REFRESH_TOKEN_EXPIRATION_TIME)); - claims.put(JWTConstants.USER_ID, authentication.getPrincipal()); + claims.put(JWTConstants.USER_ID, userId); + claims.put(JWTConstants.TOKEN_TYPE, JWTConstants.REFRESH_TOKEN); String refreshToken = Jwts.builder() .setHeaderParam(Header.TYPE, Header.JWT_TYPE) @@ -81,7 +91,7 @@ public String generateRefreshToken(Authentication authentication) { .compact(); redisTemplate.opsForValue().set( - authentication.getName(), + String.valueOf(userId), refreshToken, JWTConstants.REFRESH_TOKEN_EXPIRATION_TIME, TimeUnit.MILLISECONDS @@ -94,29 +104,35 @@ private SecretKey getSigningKey() { return Keys.hmacShaKeyFor(encodedKey.getBytes()); } - public JwtValidationType validateAccessToken(String token) { + public Long validateRefreshToken(String refreshToken) { + validateToken(refreshToken); + Long userId = getUserFromJwt(refreshToken); + if (redisTemplate.hasKey(String.valueOf(userId))) { + return userId; + } else { + throw new UnauthorizedException(INVALID_REFRESH_TOKEN); + } + } + + public JwtValidationType validateToken(String token) { try { final Claims claims = getBody(token); - return JwtValidationType.VALID_JWT; + if (claims.get(JWTConstants.TOKEN_TYPE).toString().equals(JWTConstants.ACCESS_TOKEN)) { + return JwtValidationType.VALID_ACCESS; + } else if (claims.get(JWTConstants.TOKEN_TYPE).toString().equals(JWTConstants.REFRESH_TOKEN)) { + return JwtValidationType.VALID_REFRESH; + } + throw new UnauthorizedException(WRONG_TYPE_TOKEN); } catch (MalformedJwtException e) { - throw new MoonshotException(ErrorType.WRONG_TYPE_TOKEN_ERROR); + throw new UnauthorizedException(WRONG_TYPE_TOKEN); } catch (ExpiredJwtException e) { - throw new MoonshotException(ErrorType.EXPIRED_TOKEN_ERROR); + throw new UnauthorizedException(EXPIRED_TOKEN); } catch (IllegalArgumentException e) { - throw new MoonshotException(ErrorType.UNKNOWN_TOKEN_ERROR); + throw new UnauthorizedException(UNKNOWN_TOKEN); } catch (UnsupportedJwtException e) { - throw new MoonshotException(ErrorType.UNSUPPORTED_TOKEN_ERROR); + throw new UnauthorizedException(UNSUPPORTED_TOKEN); } catch (SignatureException e) { - throw new MoonshotException(ErrorType.WRONG_SIGNATURE_TOKEN_ERROR); - } - } - - public Long validateRefreshToken(String refreshToken) { - Long userId = getUserFromJwt(refreshToken); - if (redisTemplate.hasKey(String.valueOf(userId))) { - return userId; - } else { - throw new InvalidRefreshTokenException(); + throw new UnauthorizedException(WRONG_SIGNATURE_TOKEN); } } @@ -126,18 +142,9 @@ public void deleteRefreshToken(Long userId) { String refreshToken = valueOperations.get(String.valueOf(userId)); redisTemplate.delete(refreshToken); } else { - throw new InvalidRefreshTokenException(); - } - } - - private Claims parseClaims(String accessToken) { - try { - return Jwts.parserBuilder().setSigningKey(JWT_SECRET).build().parseClaimsJws(accessToken).getBody(); - } catch (ExpiredJwtException e) { - return e.getClaims(); + throw new InternalServerException(DISCORD_LOG_APPENDER); } } - private Claims getBody(final String token) { return Jwts.parserBuilder() .setSigningKey(getSigningKey()) @@ -151,11 +158,9 @@ public Long getUserFromJwt(String token) { return Long.parseLong(claims.get(JWTConstants.USER_ID).toString()); } - public static Long getUserIdFromPrincipal(Principal principal) { - if (Objects.isNull(principal)) { - throw new InvalidAuthException(); - } - return Long.valueOf(principal.getName()); + public Authentication getAuthentication(Long userId) { + UserPrincipal userDetails = (UserPrincipal) userPrincipalDetailsService.loadUserByUsername(String.valueOf(userId)); + return new UserAuthentication(userDetails); } } \ No newline at end of file diff --git a/moonshot-auth/src/main/java/org/moonshot/jwt/JwtValidationType.java b/moonshot-auth/src/main/java/org/moonshot/jwt/JwtValidationType.java index ef12b913..c430780e 100644 --- a/moonshot-auth/src/main/java/org/moonshot/jwt/JwtValidationType.java +++ b/moonshot-auth/src/main/java/org/moonshot/jwt/JwtValidationType.java @@ -1,7 +1,8 @@ package org.moonshot.jwt; public enum JwtValidationType { - VALID_JWT, + VALID_ACCESS, + VALID_REFRESH, INVALID_JWT_SIGNATURE, INVALID_JWT_TOKEN, EXPIRED_JWT_TOKEN, diff --git a/moonshot-auth/src/main/java/org/moonshot/security/JwtAuthenticationFilter.java b/moonshot-auth/src/main/java/org/moonshot/security/JwtAuthenticationFilter.java index ddb91376..a892d6e7 100644 --- a/moonshot-auth/src/main/java/org/moonshot/security/JwtAuthenticationFilter.java +++ b/moonshot-auth/src/main/java/org/moonshot/security/JwtAuthenticationFilter.java @@ -8,11 +8,12 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.moonshot.constants.JWTConstants; import org.moonshot.constants.WhiteListConstants; import org.moonshot.jwt.JwtTokenProvider; import org.moonshot.jwt.JwtValidationType; +import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; @@ -33,12 +34,11 @@ protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull Ht } } final String token = getJwtFromRequest(request); - if (jwtTokenProvider.validateAccessToken(token) == JwtValidationType.VALID_JWT) { - Long userId = jwtTokenProvider.getUserFromJwt(token); - UserAuthentication authentication = new UserAuthentication(userId, null, null); - authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - SecurityContextHolder.getContext().setAuthentication(authentication); - } + jwtTokenProvider.validateToken(token); + + Long userId = jwtTokenProvider.getUserFromJwt(token); + Authentication authentication = jwtTokenProvider.getAuthentication(userId); + SecurityContextHolder.getContext().setAuthentication(authentication); filterChain.doFilter(request, response); } diff --git a/moonshot-auth/src/main/java/org/moonshot/security/JwtExceptionFilter.java b/moonshot-auth/src/main/java/org/moonshot/security/JwtExceptionFilter.java index e2407557..ee7c86f2 100644 --- a/moonshot-auth/src/main/java/org/moonshot/security/JwtExceptionFilter.java +++ b/moonshot-auth/src/main/java/org/moonshot/security/JwtExceptionFilter.java @@ -9,7 +9,7 @@ import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.moonshot.exception.global.common.MoonshotException; +import org.moonshot.exception.MoonshotException; import org.moonshot.response.ErrorType; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; @@ -28,16 +28,16 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse try { filterChain.doFilter(request, response); } catch (MoonshotException e) { - if(e.getErrorType().equals(ErrorType.UNKNOWN_TOKEN_ERROR)) { - setErrorResponse(response, ErrorType.UNKNOWN_TOKEN_ERROR); - } else if(e.getErrorType().equals(ErrorType.WRONG_TYPE_TOKEN_ERROR)) { - setErrorResponse(response, ErrorType.WRONG_TYPE_TOKEN_ERROR); - } else if(e.getErrorType().equals(ErrorType.EXPIRED_TOKEN_ERROR)) { - setErrorResponse(response, ErrorType.EXPIRED_TOKEN_ERROR); - } else if(e.getErrorType().equals(ErrorType.UNSUPPORTED_TOKEN_ERROR)) { - setErrorResponse(response, ErrorType.UNSUPPORTED_TOKEN_ERROR); - } else if(e.getErrorType().equals(ErrorType.WRONG_SIGNATURE_TOKEN_ERROR)) { - setErrorResponse(response, ErrorType.WRONG_SIGNATURE_TOKEN_ERROR); + if(e.getErrorType().equals(ErrorType.UNKNOWN_TOKEN)) { + setErrorResponse(response, ErrorType.UNKNOWN_TOKEN); + } else if(e.getErrorType().equals(ErrorType.WRONG_TYPE_TOKEN)) { + setErrorResponse(response, ErrorType.WRONG_TYPE_TOKEN); + } else if(e.getErrorType().equals(ErrorType.EXPIRED_TOKEN)) { + setErrorResponse(response, ErrorType.EXPIRED_TOKEN); + } else if(e.getErrorType().equals(ErrorType.UNSUPPORTED_TOKEN)) { + setErrorResponse(response, ErrorType.UNSUPPORTED_TOKEN); + } else if(e.getErrorType().equals(ErrorType.WRONG_SIGNATURE_TOKEN)) { + setErrorResponse(response, ErrorType.WRONG_SIGNATURE_TOKEN); } } } @@ -45,7 +45,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse private void setErrorResponse(HttpServletResponse response, ErrorType errorType) { response.setStatus(errorType.getHttpStatus().value()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); - ErrorResponse errorResponse = new ErrorResponse(errorType.getHttpStatusCode(), errorType.getMessage()); + ErrorResponse errorResponse = new ErrorResponse(errorType.getHttpStatusCode(), errorType.getCode(), errorType.getMessage()); try { response.getWriter().write(objectMapper.writeValueAsString(errorResponse)); } catch (IOException e) { @@ -55,7 +55,8 @@ private void setErrorResponse(HttpServletResponse response, ErrorType errorType) @Data public static class ErrorResponse { - private final Integer code; + private final Integer status; + private final int code; private final String message; } diff --git a/moonshot-auth/src/main/java/org/moonshot/security/UserAuthentication.java b/moonshot-auth/src/main/java/org/moonshot/security/UserAuthentication.java index ae130a59..ee4f53e7 100644 --- a/moonshot-auth/src/main/java/org/moonshot/security/UserAuthentication.java +++ b/moonshot-auth/src/main/java/org/moonshot/security/UserAuthentication.java @@ -1,14 +1,26 @@ package org.moonshot.security; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; -import java.util.Collection; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.userdetails.UserDetails; -public class UserAuthentication extends UsernamePasswordAuthenticationToken { +public class UserAuthentication extends AbstractAuthenticationToken { - public UserAuthentication(Object principal, Object credentials, Collection authorities) { - super(principal, credentials, authorities); + private final UserDetails userPrincipal; + + public UserAuthentication(UserDetails userPrincipal) { + super(userPrincipal.getAuthorities()); + super.setAuthenticated(true); + this.userPrincipal = userPrincipal; + } + + @Override + public Object getCredentials() { + return null; } + @Override + public Object getPrincipal() { + return userPrincipal; + } } \ No newline at end of file diff --git a/moonshot-auth/src/main/java/org/moonshot/security/service/UserPrincipalDetailsService.java b/moonshot-auth/src/main/java/org/moonshot/security/service/UserPrincipalDetailsService.java new file mode 100644 index 00000000..027d9d3a --- /dev/null +++ b/moonshot-auth/src/main/java/org/moonshot/security/service/UserPrincipalDetailsService.java @@ -0,0 +1,25 @@ +package org.moonshot.security.service; + +import lombok.RequiredArgsConstructor; +import org.moonshot.exception.UnauthorizedException; +import org.moonshot.user.model.UserPrincipal; +import org.moonshot.user.repository.UserRepository; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserPrincipalDetailsService implements UserDetailsService { + + private final UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + return userRepository.findById(Long.parseLong(username)) + .map(UserPrincipal::new) + .orElseThrow(UnauthorizedException::new); + } + +} diff --git a/moonshot-common/src/main/java/org/moonshot/constants/JWTConstants.java b/moonshot-common/src/main/java/org/moonshot/constants/JWTConstants.java index 58a191df..4ce1890d 100644 --- a/moonshot-common/src/main/java/org/moonshot/constants/JWTConstants.java +++ b/moonshot-common/src/main/java/org/moonshot/constants/JWTConstants.java @@ -3,7 +3,10 @@ public class JWTConstants { public static final String USER_ID = "userId"; + public static final String TOKEN_TYPE = "type"; + public static final String ACCESS_TOKEN = "access"; + public static final String REFRESH_TOKEN = "refresh"; public static final Long ACCESS_TOKEN_EXPIRATION_TIME = 60 * 1000L * 20; public static final Long REFRESH_TOKEN_EXPIRATION_TIME = 60 * 1000L * 60 * 24 * 7 * 2; -} +} \ No newline at end of file diff --git a/moonshot-common/src/main/java/org/moonshot/exception/BadRequestException.java b/moonshot-common/src/main/java/org/moonshot/exception/BadRequestException.java new file mode 100644 index 00000000..53fe1574 --- /dev/null +++ b/moonshot-common/src/main/java/org/moonshot/exception/BadRequestException.java @@ -0,0 +1,15 @@ +package org.moonshot.exception; + +import org.moonshot.response.ErrorType; + +public class BadRequestException extends MoonshotException { + + public BadRequestException() { + super(ErrorType.BAD_REQUEST); + } + + public BadRequestException(ErrorType errorType) { + super(errorType); + } + +} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/ForbiddenException.java b/moonshot-common/src/main/java/org/moonshot/exception/ForbiddenException.java new file mode 100644 index 00000000..eafbc9b2 --- /dev/null +++ b/moonshot-common/src/main/java/org/moonshot/exception/ForbiddenException.java @@ -0,0 +1,14 @@ +package org.moonshot.exception; + +import org.moonshot.response.ErrorType; + +public class ForbiddenException extends MoonshotException { + + public ForbiddenException() { + super(ErrorType.FORBIDDEN); + } + + public ForbiddenException(ErrorType errorType) { + super(errorType); + } +} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/InternalServerException.java b/moonshot-common/src/main/java/org/moonshot/exception/InternalServerException.java new file mode 100644 index 00000000..36ac601e --- /dev/null +++ b/moonshot-common/src/main/java/org/moonshot/exception/InternalServerException.java @@ -0,0 +1,15 @@ +package org.moonshot.exception; + +import org.moonshot.response.ErrorType; + +public class InternalServerException extends MoonshotException { + + public InternalServerException() { + super(ErrorType.INTERNAL_SERVER); + } + + public InternalServerException(ErrorType errorType) { + super(errorType); + } + +} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/global/common/MoonshotControllerAdvice.java b/moonshot-common/src/main/java/org/moonshot/exception/MoonshotControllerAdvice.java similarity index 87% rename from moonshot-common/src/main/java/org/moonshot/exception/global/common/MoonshotControllerAdvice.java rename to moonshot-common/src/main/java/org/moonshot/exception/MoonshotControllerAdvice.java index 25a044ac..6bad3b7d 100644 --- a/moonshot-common/src/main/java/org/moonshot/exception/global/common/MoonshotControllerAdvice.java +++ b/moonshot-common/src/main/java/org/moonshot/exception/MoonshotControllerAdvice.java @@ -1,4 +1,4 @@ -package org.moonshot.exception.global.common; +package org.moonshot.exception; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.ConstraintDefinitionException; @@ -40,7 +40,7 @@ public ResponseEntity> handleMethodArgumentNotValidException validateDetails.put(validKeyName, error.getDefaultMessage()); } log.error(e.getMessage(), e); - return new ResponseEntity<>(MoonshotResponse.error(ErrorType.REQUEST_VALIDATION_EXCEPTION, validateDetails), e.getStatusCode()); + return new ResponseEntity<>(MoonshotResponse.error(ErrorType.REQUEST_VALIDATION, validateDetails), e.getStatusCode()); } @ExceptionHandler(UnexpectedTypeException.class) @@ -70,7 +70,7 @@ public ResponseEntity> handlerHttpMessageNotReadableExceptio @ExceptionHandler(HttpRequestMethodNotSupportedException.class) public ResponseEntity> handlerHttpRequestMethodNotSupportedException(final HttpRequestMethodNotSupportedException e) { log.error(e.getMessage(), e); - return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INVALID_HTTP_METHOD), e.getStatusCode()); + return new ResponseEntity<>(MoonshotResponse.error(ErrorType.METHOD_NOT_ALLOWED), e.getStatusCode()); } @ExceptionHandler(ConstraintDefinitionException.class) @@ -78,40 +78,31 @@ protected ResponseEntity> handlerConstraintDefinitionExcepti return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INVALID_HTTP_REQUEST, e.toString()), HttpStatus.BAD_REQUEST); } - /** - * 401 UNAUTHROZIED - */ -// @ExceptionHandler(FeignException.class) -// public ResponseEntity> handlerFeignException(final FeignException e) { -// log.error(e.getMessage(), e); -// return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INVALID_AUTHORIZATION_ERROR), HttpStatus.UNAUTHORIZED); -// } - /** * 500 INTERNEL_SERVER */ @ExceptionHandler(Exception.class) public ResponseEntity> handleException(final Exception e, final HttpServletRequest request) throws IOException { log.error(e.getMessage(), e); - return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INTERNAL_SERVER_ERROR), HttpStatus.INTERNAL_SERVER_ERROR); + return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INTERNAL_SERVER), HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(IllegalArgumentException.class) public ResponseEntity> handlerIllegalArgumentException(final IllegalArgumentException e, final HttpServletRequest request) { log.error(e.getMessage(), e); - return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INTERNAL_SERVER_ERROR), HttpStatus.INTERNAL_SERVER_ERROR); + return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INTERNAL_SERVER), HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(IOException.class) public ResponseEntity> handlerIOException(final IOException e, final HttpServletRequest request) { log.error(e.getMessage(), e); - return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INTERNAL_SERVER_ERROR), HttpStatus.INTERNAL_SERVER_ERROR); + return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INTERNAL_SERVER), HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(RuntimeException.class) public ResponseEntity> handlerRuntimeException(final RuntimeException e, final HttpServletRequest request) { log.error(e.getMessage(), e); - return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INTERNAL_SERVER_ERROR), HttpStatus.INTERNAL_SERVER_ERROR); + return new ResponseEntity<>(MoonshotResponse.error(ErrorType.INTERNAL_SERVER), HttpStatus.INTERNAL_SERVER_ERROR); } /** diff --git a/moonshot-common/src/main/java/org/moonshot/exception/global/common/MoonshotException.java b/moonshot-common/src/main/java/org/moonshot/exception/MoonshotException.java similarity index 89% rename from moonshot-common/src/main/java/org/moonshot/exception/global/common/MoonshotException.java rename to moonshot-common/src/main/java/org/moonshot/exception/MoonshotException.java index a482bf13..0040cb99 100644 --- a/moonshot-common/src/main/java/org/moonshot/exception/global/common/MoonshotException.java +++ b/moonshot-common/src/main/java/org/moonshot/exception/MoonshotException.java @@ -1,4 +1,4 @@ -package org.moonshot.exception.global.common; +package org.moonshot.exception; import lombok.Getter; import org.moonshot.response.ErrorType; diff --git a/moonshot-common/src/main/java/org/moonshot/exception/NotFoundException.java b/moonshot-common/src/main/java/org/moonshot/exception/NotFoundException.java new file mode 100644 index 00000000..336bb428 --- /dev/null +++ b/moonshot-common/src/main/java/org/moonshot/exception/NotFoundException.java @@ -0,0 +1,15 @@ +package org.moonshot.exception; + +import org.moonshot.response.ErrorType; + +public class NotFoundException extends MoonshotException { + + public NotFoundException() { + super(ErrorType.NOT_FOUND); + } + + public NotFoundException(ErrorType errorType) { + super(errorType); + } + +} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/UnauthorizedException.java b/moonshot-common/src/main/java/org/moonshot/exception/UnauthorizedException.java new file mode 100644 index 00000000..5994b0d2 --- /dev/null +++ b/moonshot-common/src/main/java/org/moonshot/exception/UnauthorizedException.java @@ -0,0 +1,15 @@ +package org.moonshot.exception; + +import org.moonshot.response.ErrorType; + +public class UnauthorizedException extends MoonshotException { + + public UnauthorizedException() { + super(ErrorType.UNAUTHORIZED); + } + + public UnauthorizedException(ErrorType errorType) { + super(errorType); + } + +} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/global/auth/AccessDeniedException.java b/moonshot-common/src/main/java/org/moonshot/exception/global/auth/AccessDeniedException.java deleted file mode 100644 index 050419fb..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/global/auth/AccessDeniedException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.moonshot.exception.global.auth; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class AccessDeniedException extends MoonshotException { - public AccessDeniedException() { - super(ErrorType.FORBIDDEN_ERROR); - } -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/global/auth/ExpiredTokenException.java b/moonshot-common/src/main/java/org/moonshot/exception/global/auth/ExpiredTokenException.java deleted file mode 100644 index d3efb8fe..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/global/auth/ExpiredTokenException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.global.auth; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class ExpiredTokenException extends MoonshotException { - - public ExpiredTokenException() { - super(ErrorType.EXPIRED_TOKEN_ERROR); - } - -} \ No newline at end of file diff --git a/moonshot-common/src/main/java/org/moonshot/exception/global/auth/InvalidAuthException.java b/moonshot-common/src/main/java/org/moonshot/exception/global/auth/InvalidAuthException.java deleted file mode 100644 index b29b9131..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/global/auth/InvalidAuthException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.global.auth; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class InvalidAuthException extends MoonshotException { - - public InvalidAuthException() { - super(ErrorType.INVALID_AUTH_ERROR); - } - -} \ No newline at end of file diff --git a/moonshot-common/src/main/java/org/moonshot/exception/global/auth/InvalidRefreshTokenException.java b/moonshot-common/src/main/java/org/moonshot/exception/global/auth/InvalidRefreshTokenException.java deleted file mode 100644 index 4ef8ec91..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/global/auth/InvalidRefreshTokenException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.moonshot.exception.global.auth; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class InvalidRefreshTokenException extends MoonshotException { - public InvalidRefreshTokenException() { - super(ErrorType.INVALID_REFRESHTOKEN_ERROR); - } -} \ No newline at end of file diff --git a/moonshot-common/src/main/java/org/moonshot/exception/global/external/discord/ErrorLogAppenderException.java b/moonshot-common/src/main/java/org/moonshot/exception/global/external/discord/ErrorLogAppenderException.java deleted file mode 100644 index dc4199c0..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/global/external/discord/ErrorLogAppenderException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.moonshot.exception.global.external.discord; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class ErrorLogAppenderException extends MoonshotException { - public ErrorLogAppenderException() { - super(ErrorType.DISCORD_LOG_APPENDER_ERROR); - } -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/global/external/s3/UnsupportedFileExtensionException.java b/moonshot-common/src/main/java/org/moonshot/exception/global/external/s3/UnsupportedFileExtensionException.java deleted file mode 100644 index 8f4b5b43..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/global/external/s3/UnsupportedFileExtensionException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.global.external.s3; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class UnsupportedFileExtensionException extends MoonshotException { - - public UnsupportedFileExtensionException() { - super(ErrorType.INVALID_IMAGE_EXTENSION); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultInvalidIndexException.java b/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultInvalidIndexException.java deleted file mode 100644 index fabce67b..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultInvalidIndexException.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.moonshot.exception.keyresult; - - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class KeyResultInvalidIndexException extends MoonshotException { - - public KeyResultInvalidIndexException() { - super(ErrorType.INVALID_KEY_RESULT_INDEX); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultInvalidPeriodException.java b/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultInvalidPeriodException.java deleted file mode 100644 index ab7bf553..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultInvalidPeriodException.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.moonshot.exception.keyresult; - - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class KeyResultInvalidPeriodException extends MoonshotException { - public KeyResultInvalidPeriodException() { - super(ErrorType.INVALID_KEY_RESULT_PERIOD); - } -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultNotFoundException.java b/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultNotFoundException.java deleted file mode 100644 index c21e404d..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultNotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.keyresult; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class KeyResultNotFoundException extends MoonshotException { - - public KeyResultNotFoundException() { - super(ErrorType.NOT_FOUND_KEY_RESULT_ERROR); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultNumberExceededException.java b/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultNumberExceededException.java deleted file mode 100644 index 81abe304..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultNumberExceededException.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.moonshot.exception.keyresult; - - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class KeyResultNumberExceededException extends MoonshotException { - - public KeyResultNumberExceededException() { - super(ErrorType.ACTIVE_KEY_RESULT_NUMBER_EXCEEDED); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultRequiredException.java b/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultRequiredException.java deleted file mode 100644 index e30adaf2..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/keyresult/KeyResultRequiredException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.keyresult; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class KeyResultRequiredException extends MoonshotException { - - public KeyResultRequiredException() { - super(ErrorType.REQUIRED_KEY_RESULT_VALUE); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/log/InvalidLogValueException.java b/moonshot-common/src/main/java/org/moonshot/exception/log/InvalidLogValueException.java deleted file mode 100644 index 4c4f87e7..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/log/InvalidLogValueException.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.moonshot.exception.log; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class InvalidLogValueException extends MoonshotException { - - public InvalidLogValueException() { - super(ErrorType.INVALID_LOG_VALUE); - } -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/log/LogNotFoundException.java b/moonshot-common/src/main/java/org/moonshot/exception/log/LogNotFoundException.java deleted file mode 100644 index b7ecc122..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/log/LogNotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.log; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class LogNotFoundException extends MoonshotException { - - public LogNotFoundException() { - super(ErrorType.NOT_FOUND_LOG_ERROR); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/objective/DateInputRequiredException.java b/moonshot-common/src/main/java/org/moonshot/exception/objective/DateInputRequiredException.java deleted file mode 100644 index 0910d25b..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/objective/DateInputRequiredException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.objective; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class DateInputRequiredException extends MoonshotException { - - public DateInputRequiredException() { - super(ErrorType.REQUIRED_EXPIRE_AT); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/objective/InvalidExpiredAtException.java b/moonshot-common/src/main/java/org/moonshot/exception/objective/InvalidExpiredAtException.java deleted file mode 100644 index 34095ccc..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/objective/InvalidExpiredAtException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.objective; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class InvalidExpiredAtException extends MoonshotException { - - public InvalidExpiredAtException() { - super(ErrorType.INVALID_EXPIRE_AT); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/objective/ObjectiveInvalidIndexException.java b/moonshot-common/src/main/java/org/moonshot/exception/objective/ObjectiveInvalidIndexException.java deleted file mode 100644 index 615d2fa9..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/objective/ObjectiveInvalidIndexException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.moonshot.exception.objective; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class ObjectiveInvalidIndexException extends MoonshotException { - public ObjectiveInvalidIndexException() { - super(ErrorType.INVALID_OBJECTIVE_INDEX); - } -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/objective/ObjectiveNotFoundException.java b/moonshot-common/src/main/java/org/moonshot/exception/objective/ObjectiveNotFoundException.java deleted file mode 100644 index 4e885243..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/objective/ObjectiveNotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.objective; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class ObjectiveNotFoundException extends MoonshotException { - - public ObjectiveNotFoundException() { - super(ErrorType.NOT_FOUND_OBJECTIVE_ERROR); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/objective/ObjectiveNumberExceededException.java b/moonshot-common/src/main/java/org/moonshot/exception/objective/ObjectiveNumberExceededException.java deleted file mode 100644 index 0d09e738..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/objective/ObjectiveNumberExceededException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.objective; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class ObjectiveNumberExceededException extends MoonshotException { - - public ObjectiveNumberExceededException() { - super(ErrorType.ACTIVE_OBJECTIVE_NUMBER_EXCEEDED); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/task/TaskInvalidIndexException.java b/moonshot-common/src/main/java/org/moonshot/exception/task/TaskInvalidIndexException.java deleted file mode 100644 index 6fa21e8c..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/task/TaskInvalidIndexException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.task; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class TaskInvalidIndexException extends MoonshotException { - - public TaskInvalidIndexException() { - super(ErrorType.INVALID_TASK_INDEX); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/task/TaskNotFoundException.java b/moonshot-common/src/main/java/org/moonshot/exception/task/TaskNotFoundException.java deleted file mode 100644 index c79d0f9b..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/task/TaskNotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.task; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class TaskNotFoundException extends MoonshotException { - - public TaskNotFoundException() { - super(ErrorType.NOT_FOUND_TASK_ERROR); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/task/TaskNumberExceededException.java b/moonshot-common/src/main/java/org/moonshot/exception/task/TaskNumberExceededException.java deleted file mode 100644 index 7f7d53e0..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/task/TaskNumberExceededException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.moonshot.exception.task; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class TaskNumberExceededException extends MoonshotException { - - public TaskNumberExceededException() { - super(ErrorType.ACTIVE_TASK_NUMBER_EXCEEDED); - } - -} diff --git a/moonshot-common/src/main/java/org/moonshot/exception/user/UserNotFoundException.java b/moonshot-common/src/main/java/org/moonshot/exception/user/UserNotFoundException.java deleted file mode 100644 index 213af1d4..00000000 --- a/moonshot-common/src/main/java/org/moonshot/exception/user/UserNotFoundException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.moonshot.exception.user; - -import org.moonshot.exception.global.common.MoonshotException; -import org.moonshot.response.ErrorType; - -public class UserNotFoundException extends MoonshotException { - public UserNotFoundException() { - super(ErrorType.NOT_FOUND_USER_ERROR); - } -} diff --git a/moonshot-common/src/main/java/org/moonshot/response/ErrorType.java b/moonshot-common/src/main/java/org/moonshot/response/ErrorType.java index e29e7bd9..3944cba9 100644 --- a/moonshot-common/src/main/java/org/moonshot/response/ErrorType.java +++ b/moonshot-common/src/main/java/org/moonshot/response/ErrorType.java @@ -9,65 +9,73 @@ @AllArgsConstructor(access = AccessLevel.PRIVATE) public enum ErrorType { - /* - 400 BAD REQUEST + /** + * 400 BAD REQUEST (4000 ~ 4099) */ - REQUEST_VALIDATION_EXCEPTION(HttpStatus.BAD_REQUEST, "잘못된 요청입니다"), - INVALID_TYPE(HttpStatus.BAD_REQUEST, "잘못된 타입이 입력되었습니다."), - INVALID_MISSING_HEADER(HttpStatus.BAD_REQUEST, "요청에 필요한 헤더값이 존재하지 않습니다."), - INVALID_HTTP_REQUEST(HttpStatus.BAD_REQUEST, "허용되지 않는 문자열이 입력되었습니다."), - INVALID_HTTP_METHOD(HttpStatus.BAD_REQUEST, "지원되지 않는 HTTP method 요청입니다."), - INVALID_IMAGE_EXTENSION(HttpStatus.BAD_REQUEST, "지원하지 않는 이미지 확장자입니다."), - ACTIVE_OBJECTIVE_NUMBER_EXCEEDED(HttpStatus.BAD_REQUEST, "허용된 Objective 개수를 초과하였습니다"), - ACTIVE_KEY_RESULT_NUMBER_EXCEEDED(HttpStatus.BAD_REQUEST, "허용된 Key Result 개수를 초과하였습니다"), - ACTIVE_TASK_NUMBER_EXCEEDED(HttpStatus.BAD_REQUEST, "허용된 Task 개수를 초과하였습니다."), - USER_OBJECTIVE_EMPTY(HttpStatus.BAD_REQUEST, "해당 유저의 Objective가 존재하지 않습니다."), - INVALID_OBJECTIVE_INDEX(HttpStatus.BAD_REQUEST, "정상적이지 않은 Objective 위치입니다."), - INVALID_KEY_RESULT_INDEX(HttpStatus.BAD_REQUEST, "정상적이지 않은 KeyResult 위치입니다."), - INVALID_TASK_INDEX(HttpStatus.BAD_REQUEST, "정상적이지 않은 Task 위치입니다."), - INVALID_LOG_VALUE(HttpStatus.BAD_REQUEST, "Log 입력값은 이전 값과 동일할 수 없습니다."), - INVALID_EXPIRE_AT(HttpStatus.BAD_REQUEST, "Objective 종료 기간은 오늘보다 이전 날짜일 수 없습니다."), - INVALID_KEY_RESULT_PERIOD(HttpStatus.BAD_REQUEST, "KeyResult 기간 설정이 올바르지 않습니다."), - REQUIRED_EXPIRE_AT(HttpStatus.BAD_REQUEST, "기간 연장시 목표 종료 기간은 필수 입력값입니다."), - REQUIRED_KEY_RESULT_VALUE(HttpStatus.BAD_REQUEST, "KR 수정시 목표값과 체크인 로그는 필수 입력값입니다."), + BAD_REQUEST(HttpStatus.BAD_REQUEST, 4000, "잘못된 요청입니다."), + REQUEST_VALIDATION(HttpStatus.BAD_REQUEST, 4001, "잘못된 요청입니다."), + INVALID_TYPE(HttpStatus.BAD_REQUEST, 4002, "잘못된 타입이 입력되었습니다."), + INVALID_MISSING_HEADER(HttpStatus.BAD_REQUEST, 4003, "요청에 필요한 헤더값이 존재하지 않습니다."), + INVALID_HTTP_REQUEST(HttpStatus.BAD_REQUEST, 4004, "허용되지 않는 문자열이 입력되었습니다."), + INVALID_IMAGE_EXTENSION(HttpStatus.BAD_REQUEST, 4006, "지원하지 않는 이미지 확장자입니다."), + ACTIVE_OBJECTIVE_NUMBER_EXCEEDED(HttpStatus.BAD_REQUEST, 4007, "허용된 Objective 개수를 초과하였습니다"), + ACTIVE_KEY_RESULT_NUMBER_EXCEEDED(HttpStatus.BAD_REQUEST, 4008, "허용된 Key Result 개수를 초과하였습니다"), + ACTIVE_TASK_NUMBER_EXCEEDED(HttpStatus.BAD_REQUEST, 4009, "허용된 Task 개수를 초과하였습니다."), + USER_OBJECTIVE_EMPTY(HttpStatus.BAD_REQUEST, 4010, "해당 유저의 Objective가 존재하지 않습니다."), + INVALID_OBJECTIVE_INDEX(HttpStatus.BAD_REQUEST, 4011, "정상적이지 않은 Objective 위치입니다."), + INVALID_KEY_RESULT_INDEX(HttpStatus.BAD_REQUEST, 4012, "정상적이지 않은 KeyResult 위치입니다."), + INVALID_TASK_INDEX(HttpStatus.BAD_REQUEST, 4013, "정상적이지 않은 Task 위치입니다."), + INVALID_LOG_VALUE(HttpStatus.BAD_REQUEST, 4014, "Log 입력값은 이전 값과 동일할 수 없습니다."), + INVALID_EXPIRE_AT(HttpStatus.BAD_REQUEST, 4015, "Objective 종료 기간은 오늘보다 이전 날짜일 수 없습니다."), + INVALID_KEY_RESULT_PERIOD(HttpStatus.BAD_REQUEST, 4016, "KeyResult 기간 설정이 올바르지 않습니다."), + REQUIRED_EXPIRE_AT(HttpStatus.BAD_REQUEST, 4017, "기간 연장시 목표 종료 기간은 필수 입력값입니다."), + REQUIRED_KEY_RESULT_VALUE(HttpStatus.BAD_REQUEST, 4018, "KR 수정시 목표값과 체크인 로그는 필수 입력값입니다."), /** - * 401 UNAUTHROZIED + * 401 UNAUTHROZIED (4100 ~ 4199) */ - UNKNOWN_TOKEN_ERROR(HttpStatus.UNAUTHORIZED,"인증 토큰이 존재하지 않습니다."), - INVALID_AUTHORIZATION_ERROR(HttpStatus.UNAUTHORIZED, "유효하지 않은 인증 코드입니다."), - UNSUPPORTED_TOKEN_ERROR(HttpStatus.UNAUTHORIZED,"지원하지 않는 토큰 방식입니다."), - INVALID_ACCESS_TOKEN_ERROR(HttpStatus.UNAUTHORIZED, "유효하지 않은 AccessToken입니다."), - INVALID_REFRESHTOKEN_ERROR(HttpStatus.UNAUTHORIZED, "유효하지 않은 RefreshToken입니다."), - INVALID_AUTH_ERROR(HttpStatus.UNAUTHORIZED, "인증되지 않은 사용자입니다."), - EXPIRED_TOKEN_ERROR(HttpStatus.UNAUTHORIZED, "만료된 Token입니다."), - WRONG_TYPE_TOKEN_ERROR(HttpStatus.UNAUTHORIZED, "잘못된 형식의 Token입니다"), - WRONG_SIGNATURE_TOKEN_ERROR(HttpStatus.UNAUTHORIZED, "Signature가 잘못된 Token입니다."), - ACCESS_DENIED(HttpStatus.UNAUTHORIZED,"알 수 없는 이유로 요청이 거절되었습니다."), + UNAUTHORIZED(HttpStatus.UNAUTHORIZED, 4100, "인증되지 않았습니다."), + UNKNOWN_TOKEN(HttpStatus.UNAUTHORIZED, 4100, "인증 토큰이 존재하지 않습니다."), + INVALID_AUTHORIZATION(HttpStatus.UNAUTHORIZED, 4101, "유효하지 않은 인증 코드입니다."), + UNSUPPORTED_TOKEN(HttpStatus.UNAUTHORIZED, 4102, "지원하지 않는 토큰 방식입니다."), + INVALID_ACCESS_TOKEN(HttpStatus.UNAUTHORIZED, 4103, "유효하지 않은 AccessToken입니다."), + INVALID_REFRESH_TOKEN(HttpStatus.UNAUTHORIZED, 4104, "유효하지 않은 RefreshToken입니다."), + INVALID_AUTH(HttpStatus.UNAUTHORIZED, 4105, "인증되지 않은 사용자입니다."), + EXPIRED_TOKEN(HttpStatus.UNAUTHORIZED, 4106, "만료된 Token입니다."), + WRONG_TYPE_TOKEN(HttpStatus.UNAUTHORIZED, 4107, "잘못된 형식의 Token입니다"), + WRONG_SIGNATURE_TOKEN(HttpStatus.UNAUTHORIZED, 4108, "Signature가 잘못된 Token입니다."), + ACCESS_DENIED(HttpStatus.UNAUTHORIZED, 4109, "알 수 없는 이유로 요청이 거절되었습니다."), + /** + * 403 FORBIDDEN (4300 ~ 4399) + */ + FORBIDDEN(HttpStatus.FORBIDDEN, 4300, "해당 자원에 접근 권한이 없습니다."), /** - * 403 FORBIDDEN + * 404 NOT FOUND (4400 ~ 4499) */ - FORBIDDEN_ERROR(HttpStatus.FORBIDDEN, "해당 자원에 접근 권한이 없습니다."), + NOT_FOUND(HttpStatus.NOT_FOUND, 4400, "존재하지 않는 리소스입니다."), + NOT_FOUND_USER(HttpStatus.NOT_FOUND, 4401, "존재하지 않는 유저입니다."), + NOT_FOUND_OBJECTIVE(HttpStatus.NOT_FOUND, 4402, "존재하지 않는 Objective입니다."), + NOT_FOUND_KEY_RESULT(HttpStatus.NOT_FOUND, 4403, "존재하지 않는 KeyResult입니다."), + NOT_FOUND_TASK(HttpStatus.NOT_FOUND, 4404, "존재하지 않는 Task입니다."), + NOT_FOUND_LOG(HttpStatus.NOT_FOUND, 4405, "존재하지 않는 Log입니다."), /** - * 404 NOT FOUND + * 405 Method Not Allowed (4500 ~ 4599) */ - NOT_FOUND_USER_ERROR(HttpStatus.NOT_FOUND, "존재하지 않는 유저입니다."), - NOT_FOUND_OBJECTIVE_ERROR(HttpStatus.NOT_FOUND, "존재하지 않는 Objective입니다."), - NOT_FOUND_KEY_RESULT_ERROR(HttpStatus.NOT_FOUND, "존재하지 않는 KeyResult입니다."), - NOT_FOUND_TASK_ERROR(HttpStatus.NOT_FOUND, "존재하지 않는 Task입니다."), - NOT_FOUND_LOG_ERROR(HttpStatus.NOT_FOUND, "존재하지 않는 Log입니다."), + METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, 4500, "잘못된 HTTP method 요청입니다."), /** - * 500 INTERNAL SERVER ERROR + * 500 INTERNAL SERVER (5000 ~ 5099) */ - INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "알 수 없는 서버 에러가 발생했습니다"), - DISCORD_LOG_APPENDER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "디스코드 로그 전송에 실패하였습니다"), - API_CALL_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "외부 API CALL에 실패하였습니다."); + INTERNAL_SERVER(HttpStatus.INTERNAL_SERVER_ERROR, 5000, "알 수 없는 서버 에러가 발생했습니다"), + DISCORD_LOG_APPENDER(HttpStatus.INTERNAL_SERVER_ERROR, 5001, "디스코드 로그 전송에 실패하였습니다"), + DISCORD_CONTENT(HttpStatus.INTERNAL_SERVER_ERROR, 5002, "디스코드 로그 전송 내용이 존재하지 않습니다."), + API_CALL(HttpStatus.INTERNAL_SERVER_ERROR, 5003, "외부 API CALL에 실패하였습니다."); private final HttpStatus httpStatus; + private final int code; private final String message; public int getHttpStatusCode() { diff --git a/moonshot-common/src/main/java/org/moonshot/response/MoonshotResponse.java b/moonshot-common/src/main/java/org/moonshot/response/MoonshotResponse.java index a40669ed..e8583ec9 100644 --- a/moonshot-common/src/main/java/org/moonshot/response/MoonshotResponse.java +++ b/moonshot-common/src/main/java/org/moonshot/response/MoonshotResponse.java @@ -8,41 +8,42 @@ import lombok.RequiredArgsConstructor; @Getter -@JsonPropertyOrder({"status", "message", "data"}) +@JsonPropertyOrder({"status", "code", "message", "data"}) @RequiredArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor(access = AccessLevel.PRIVATE) public class MoonshotResponse { private final int status; + private final int code; private final String message; @JsonInclude(JsonInclude.Include.NON_NULL) private T data; public static MoonshotResponse success(SuccessType successType) { - return new MoonshotResponse<>(successType.getHttpStatusCode(), successType.getMessage()); + return new MoonshotResponse<>(successType.getHttpStatusCode(), successType.getCode(), successType.getMessage()); } public static MoonshotResponse success(SuccessType successType, T data) { - return new MoonshotResponse<>(successType.getHttpStatusCode(), successType.getMessage(), data); + return new MoonshotResponse<>(successType.getHttpStatusCode(), successType.getCode(), successType.getMessage(), data); } public static MoonshotResponse error(ErrorType errorType) { - return new MoonshotResponse<>(errorType.getHttpStatusCode(), errorType.getMessage()); + return new MoonshotResponse<>(errorType.getHttpStatusCode(), errorType.getCode(), errorType.getMessage()); } public static MoonshotResponse error(ErrorType errorType, T data) { - return new MoonshotResponse<>(errorType.getHttpStatusCode(), errorType.getMessage(), data); + return new MoonshotResponse<>(errorType.getHttpStatusCode(), errorType.getCode(), errorType.getMessage(), data); } public static MoonshotResponse error(ErrorType errorType, String message) { - return new MoonshotResponse<>(errorType.getHttpStatusCode(), message); + return new MoonshotResponse<>(errorType.getHttpStatusCode(), errorType.getCode(), message); } public static MoonshotResponse error(ErrorType errorType, String message, T data) { - return new MoonshotResponse<>(errorType.getHttpStatusCode(), message, data); + return new MoonshotResponse<>(errorType.getHttpStatusCode(), errorType.getCode(), message, data); } public static MoonshotResponse error(ErrorType errorType, Exception e) { - return new MoonshotResponse<>(errorType.getHttpStatusCode(), errorType.getMessage(), e); + return new MoonshotResponse<>(errorType.getHttpStatusCode(), errorType.getCode(), errorType.getMessage(), e); } } diff --git a/moonshot-common/src/main/java/org/moonshot/response/SuccessType.java b/moonshot-common/src/main/java/org/moonshot/response/SuccessType.java index b800c45f..94ae782c 100644 --- a/moonshot-common/src/main/java/org/moonshot/response/SuccessType.java +++ b/moonshot-common/src/main/java/org/moonshot/response/SuccessType.java @@ -10,41 +10,42 @@ public enum SuccessType { /** - * 200 OK + * 200 OK (2000 ~ 2099) */ - OK(HttpStatus.OK, "성공"), - GET_PRESIGNED_URL_SUCCESS(HttpStatus.OK, "Presigned Url 조회에 성공하였습니다."), - GET_OKR_LIST_SUCCESS(HttpStatus.OK, "O-KR 목록 조회에 성공하였습니다."), - GET_HISTORY_SUCCESS(HttpStatus.OK, "히스토리 조회에 성공하였습니다."), - POST_LOGIN_SUCCESS(HttpStatus.OK, "로그인에 성공하였습니다."), - POST_REISSUE_SUCCESS(HttpStatus.OK, "엑세스 토큰 재발급에 성공하였습니다."), - POST_LOGOUT_SUCCESS(HttpStatus.OK, "로그아웃에 성공하였습니다."), - GET_PROFILE_SUCCESS(HttpStatus.OK, "사용자 프로필 조회에 성공하였습니다."), - GET_KR_DETAIL_SUCCESS(HttpStatus.OK, "KR 상세 조회에 성공하였습니다."), - PATCH_KR_ACHIEVE_SUCCESS(HttpStatus.OK, "KeyResult 수정 후 목표를 달성하였습니다."), - POST_LOG_ACHIEVE_SUCCESS(HttpStatus.OK, "체크인 Log 생성 후 목표를 달성하였습니다."), - DELETE_OBJECTIVE_SUCCESS(HttpStatus.OK, "Objective 삭제를 성공하였습니다."), + OK(HttpStatus.OK, 2000, "성공"), + GET_PRESIGNED_URL_SUCCESS(HttpStatus.OK, 2001, "Presigned Url 조회에 성공하였습니다."), + GET_OKR_LIST_SUCCESS(HttpStatus.OK, 2002, "O-KR 목록 조회에 성공하였습니다."), + GET_HISTORY_SUCCESS(HttpStatus.OK, 2003, "히스토리 조회에 성공하였습니다."), + POST_LOGIN_SUCCESS(HttpStatus.OK, 2004, "로그인에 성공하였습니다."), + POST_REISSUE_SUCCESS(HttpStatus.OK, 2005, "엑세스 토큰 재발급에 성공하였습니다."), + POST_LOGOUT_SUCCESS(HttpStatus.OK, 2006, "로그아웃에 성공하였습니다."), + GET_PROFILE_SUCCESS(HttpStatus.OK, 2007, "사용자 프로필 조회에 성공하였습니다."), + GET_KR_DETAIL_SUCCESS(HttpStatus.OK, 2008, "KR 상세 조회에 성공하였습니다."), + PATCH_KR_ACHIEVE_SUCCESS(HttpStatus.OK, 2009, "KeyResult 수정 후 목표를 달성하였습니다."), + POST_LOG_ACHIEVE_SUCCESS(HttpStatus.OK, 2010, "체크인 Log 생성 후 목표를 달성하였습니다."), + DELETE_OBJECTIVE_SUCCESS(HttpStatus.OK, 2011, "Objective 삭제를 성공하였습니다."), /** - * 201 CREATED + * 201 CREATED (2100 ~ 2199) */ - POST_NOTIFY_IMAGE_SAVE_SUCCESS(HttpStatus.CREATED, "Presigned Url을 통해 이미지 생성을 성공하였습니다."), - POST_OKR_SUCCESS(HttpStatus.CREATED, "O-KR을 생성을 성공하였습니다."), - POST_KEY_RESULT_SUCCESS(HttpStatus.CREATED, "KeyResult 생성을 성공하였습니다."), - POST_TASK_SUCCESS(HttpStatus.CREATED, "Task 생성을 성공하였습니다."), - POST_LOG_SUCCESS(HttpStatus.CREATED, "체크인 Log 생성을 성공하였습니다."), + POST_NOTIFY_IMAGE_SAVE_SUCCESS(HttpStatus.CREATED, 2100, "Presigned Url을 통해 이미지 생성을 성공하였습니다."), + POST_OKR_SUCCESS(HttpStatus.CREATED, 2101, "O-KR을 생성을 성공하였습니다."), + POST_KEY_RESULT_SUCCESS(HttpStatus.CREATED, 2102, "KeyResult 생성을 성공하였습니다."), + POST_TASK_SUCCESS(HttpStatus.CREATED, 2103, "Task 생성을 성공하였습니다."), + POST_LOG_SUCCESS(HttpStatus.CREATED, 2104, "체크인 Log 생성을 성공하였습니다."), /** - * 204 NO CONTENT + * 204 NO CONTENT (2400 ~ 2499) */ - PATCH_PROFILE_SUCCESS(HttpStatus.NO_CONTENT, "사용자 프로필 업데이트에 성공하였습니다."), - PATCH_OBJECTIVE_SUCCESS(HttpStatus.OK, "Objective 수정에 성공하였습니다"), - PATCH_KEY_RESULT_SUCCESS(HttpStatus.NO_CONTENT, "KeyResult 수정을 성공하였습니다."), - PATCH_TARGET_INDEX_SUCCESS(HttpStatus.NO_CONTENT, "대상의 순서 수정을 성공하였습니다."), - DELETE_KEY_RESULT_SUCCESS(HttpStatus.NO_CONTENT, "KeyResult 삭제를 성공하였습니다."), - DELETE_USER_SUCCESS(HttpStatus.NO_CONTENT, "회원 탈퇴에 성공하였습니다."); + PATCH_PROFILE_SUCCESS(HttpStatus.NO_CONTENT, 2400, "사용자 프로필 업데이트에 성공하였습니다."), + PATCH_OBJECTIVE_SUCCESS(HttpStatus.OK, 2401, "Objective 수정에 성공하였습니다"), + PATCH_KEY_RESULT_SUCCESS(HttpStatus.NO_CONTENT, 2402, "KeyResult 수정을 성공하였습니다."), + PATCH_TARGET_INDEX_SUCCESS(HttpStatus.NO_CONTENT, 2403, "대상의 순서 수정을 성공하였습니다."), + DELETE_KEY_RESULT_SUCCESS(HttpStatus.NO_CONTENT, 2404, "KeyResult 삭제를 성공하였습니다."), + DELETE_USER_SUCCESS(HttpStatus.NO_CONTENT, 2405, "회원 탈퇴에 성공하였습니다."); private final HttpStatus httpStatus; + private final int code; private final String message; public int getHttpStatusCode() { diff --git a/moonshot-domain/src/main/java/org/moonshot/keyresult/model/KRState.java b/moonshot-domain/src/main/java/org/moonshot/keyresult/model/KRState.java index 72a7deba..f8c8357b 100644 --- a/moonshot-domain/src/main/java/org/moonshot/keyresult/model/KRState.java +++ b/moonshot-domain/src/main/java/org/moonshot/keyresult/model/KRState.java @@ -5,7 +5,7 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; -import org.moonshot.exception.global.common.MoonshotException; +import org.moonshot.exception.MoonshotException; import org.moonshot.response.ErrorType; @Getter diff --git a/moonshot-domain/src/main/java/org/moonshot/objective/model/Category.java b/moonshot-domain/src/main/java/org/moonshot/objective/model/Category.java index 98824915..822ce8a5 100644 --- a/moonshot-domain/src/main/java/org/moonshot/objective/model/Category.java +++ b/moonshot-domain/src/main/java/org/moonshot/objective/model/Category.java @@ -5,7 +5,7 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; -import org.moonshot.exception.global.common.MoonshotException; +import org.moonshot.exception.MoonshotException; import org.moonshot.response.ErrorType; @Getter diff --git a/moonshot-domain/src/main/java/org/moonshot/objective/model/Criteria.java b/moonshot-domain/src/main/java/org/moonshot/objective/model/Criteria.java index 1f6bfcbb..26d1fbc2 100644 --- a/moonshot-domain/src/main/java/org/moonshot/objective/model/Criteria.java +++ b/moonshot-domain/src/main/java/org/moonshot/objective/model/Criteria.java @@ -5,7 +5,7 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; -import org.moonshot.exception.global.common.MoonshotException; +import org.moonshot.exception.MoonshotException; import org.moonshot.response.ErrorType; @Getter diff --git a/moonshot-domain/src/main/java/org/moonshot/user/model/LoginUser.java b/moonshot-domain/src/main/java/org/moonshot/user/model/LoginUser.java new file mode 100644 index 00000000..c30c69a8 --- /dev/null +++ b/moonshot-domain/src/main/java/org/moonshot/user/model/LoginUser.java @@ -0,0 +1,14 @@ +package org.moonshot.user.model; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.security.core.annotation.AuthenticationPrincipal; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +@AuthenticationPrincipal(expression = "userId == null ? 0L : userId") +public @interface LoginUser { +} diff --git a/moonshot-domain/src/main/java/org/moonshot/user/model/UserPrincipal.java b/moonshot-domain/src/main/java/org/moonshot/user/model/UserPrincipal.java new file mode 100644 index 00000000..9fd69a82 --- /dev/null +++ b/moonshot-domain/src/main/java/org/moonshot/user/model/UserPrincipal.java @@ -0,0 +1,60 @@ +package org.moonshot.user.model; + +import java.util.Collection; +import java.util.List; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +public class UserPrincipal implements UserDetails { + + private final User user; + private final List grantedAuthorities; + + public UserPrincipal(User user) { + this.user = user; + this.grantedAuthorities = user.getId() == null ? + List.of(new SimpleGrantedAuthority("ANONYMOUS")) : + List.of(new SimpleGrantedAuthority("USER")); + } + + @Override + public Collection getAuthorities() { + return grantedAuthorities; + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getUsername() { + return user.getName(); + } + + @Override + public boolean isAccountNonExpired() { + return false; + } + + @Override + public boolean isAccountNonLocked() { + return false; + } + + @Override + public boolean isCredentialsNonExpired() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } + + public Long getUserId() { + return user.getId(); + } + +} diff --git a/moonshot-domain/src/main/java/org/moonshot/user/repository/UserRepository.java b/moonshot-domain/src/main/java/org/moonshot/user/repository/UserRepository.java index 65b47f76..2527f08d 100644 --- a/moonshot-domain/src/main/java/org/moonshot/user/repository/UserRepository.java +++ b/moonshot-domain/src/main/java/org/moonshot/user/repository/UserRepository.java @@ -6,15 +6,12 @@ import java.util.Optional; import org.moonshot.user.model.User; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; -import org.springframework.transaction.annotation.Transactional; public interface UserRepository extends JpaRepository { Optional findUserBySocialId(String socialId); Optional findUserByNickname(String nickname); - @Query("SELECT u FROM User u WHERE u.deleteAt < :currentDate") List findIdByDeletedAtBefore(LocalDateTime currentDate); diff --git a/moonshot-external/src/main/java/org/moonshot/discord/DiscordAppender.java b/moonshot-external/src/main/java/org/moonshot/discord/DiscordAppender.java index c17b20af..3d8ccf7e 100644 --- a/moonshot-external/src/main/java/org/moonshot/discord/DiscordAppender.java +++ b/moonshot-external/src/main/java/org/moonshot/discord/DiscordAppender.java @@ -1,5 +1,7 @@ package org.moonshot.discord; +import static org.moonshot.response.ErrorType.DISCORD_LOG_APPENDER; + import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.IThrowableProxy; import ch.qos.logback.classic.spi.ThrowableProxyUtil; @@ -15,12 +17,14 @@ import lombok.extern.slf4j.Slf4j; import org.moonshot.constants.DiscordConstants; import org.moonshot.discord.model.EmbedObject; -import org.moonshot.exception.global.external.discord.ErrorLogAppenderException; +import org.moonshot.exception.InternalServerException; import org.moonshot.util.MDCUtil; import org.moonshot.util.StringUtil; +import org.springframework.stereotype.Component; @Slf4j @Setter +@Component @RequiredArgsConstructor public class DiscordAppender extends UnsynchronizedAppenderBase { @@ -110,7 +114,7 @@ protected void append(ILoggingEvent eventObject) { try { discordWebhook.execute(); } catch (IOException ioException) { - throw new ErrorLogAppenderException(); + throw new InternalServerException(DISCORD_LOG_APPENDER); } } @@ -131,7 +135,7 @@ public void signInAppend(String name, String email, String socialPlatform, Local try { discordWebhook.executeSignIn(DiscordConstants.signInWebhookUrl); } catch (IOException ioException) { - throw new ErrorLogAppenderException(); + throw new InternalServerException(DISCORD_LOG_APPENDER); } } diff --git a/moonshot-external/src/main/java/org/moonshot/discord/DiscordWebHook.java b/moonshot-external/src/main/java/org/moonshot/discord/DiscordWebHook.java index ed4ffdfc..f2a651b3 100644 --- a/moonshot-external/src/main/java/org/moonshot/discord/DiscordWebHook.java +++ b/moonshot-external/src/main/java/org/moonshot/discord/DiscordWebHook.java @@ -1,5 +1,8 @@ package org.moonshot.discord; +import static org.moonshot.response.ErrorType.DISCORD_CONTENT; +import static org.moonshot.response.ErrorType.DISCORD_LOG_APPENDER; + import java.awt.Color; import java.io.IOException; import java.util.ArrayList; @@ -11,7 +14,7 @@ import org.moonshot.discord.model.Image; import org.moonshot.discord.model.JsonObject; import org.moonshot.discord.model.Thumbnail; -import org.moonshot.exception.global.external.discord.ErrorLogAppenderException; +import org.moonshot.exception.InternalServerException; import org.moonshot.util.ApiCallUtil; public class DiscordWebHook { @@ -35,7 +38,7 @@ public void addEmbed(EmbedObject embed) { public void execute() throws IOException { if (this.embeds.isEmpty()) { - throw new RuntimeException("컨텐츠를 설정하거나 하나 이상의 Embed Object를 추가해야 합니다."); + throw new InternalServerException(DISCORD_CONTENT); } try { @@ -50,7 +53,7 @@ this.embeds, initializerDiscordSendForJsonObject(new JsonObject()) public void executeSignIn(String signinWebhookUrl) throws IOException { if (this.embeds.isEmpty()) { - throw new RuntimeException("컨텐츠를 설정하거나 하나 이상의 Embed Object를 추가해야 합니다."); + throw new InternalServerException(DISCORD_CONTENT); } try { @@ -73,7 +76,7 @@ private JsonObject initializerDiscordSendForJsonObject(JsonObject json) { private JsonObject createDiscordEmbedObject(List embeds, JsonObject json) { if (embeds.isEmpty()) { - throw new ErrorLogAppenderException(); + throw new InternalServerException(DISCORD_LOG_APPENDER); } List embedObjects = new ArrayList<>(); diff --git a/moonshot-external/src/main/java/org/moonshot/discord/SignUpEvent.java b/moonshot-external/src/main/java/org/moonshot/discord/SignUpEvent.java new file mode 100644 index 00000000..672d9669 --- /dev/null +++ b/moonshot-external/src/main/java/org/moonshot/discord/SignUpEvent.java @@ -0,0 +1,13 @@ +package org.moonshot.discord; + + +import java.time.LocalDateTime; + +public record SignUpEvent(String name, String email, String socialPlatform, LocalDateTime createdAt, String imageUrl) { + + public static SignUpEvent of(String name, String email, String socialPlatform, LocalDateTime createdAt, + String imageUrl) { + return new SignUpEvent(name, email, socialPlatform, createdAt, imageUrl); + } + +} diff --git a/moonshot-external/src/main/java/org/moonshot/discord/SignUpEventListener.java b/moonshot-external/src/main/java/org/moonshot/discord/SignUpEventListener.java new file mode 100644 index 00000000..7683e237 --- /dev/null +++ b/moonshot-external/src/main/java/org/moonshot/discord/SignUpEventListener.java @@ -0,0 +1,25 @@ +package org.moonshot.discord; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Profile; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Component +@Profile("prod") +@RequiredArgsConstructor +public class SignUpEventListener { + + private final DiscordAppender discordAppender; + + @EventListener + public void handleSignUpEvent(SignUpEvent event) { + discordAppender.signInAppend( + event.name(), + event.email(), + event.socialPlatform(), + event.createdAt(), + event.imageUrl()); + } + +}