From ec99e8cb19993388842d5901b33e13b14565d016 Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Tue, 13 Aug 2024 15:58:44 +0900 Subject: [PATCH 1/4] [feat] voiceRoom controler apply UserSpaceInterceptor in VoiceRoomController delete userSpace Validae function add @UserSpaceAuth annotation --- .../UserSpaceValidationInterceptorURL.java | 1 + .../controller/VoiceRoomController.java | 46 ++++++------------- .../UserSpaceValidationInterceptor.java | 2 +- 3 files changed, 16 insertions(+), 33 deletions(-) diff --git a/src/main/java/space/space_spring/config/UserSpaceValidationInterceptorURL.java b/src/main/java/space/space_spring/config/UserSpaceValidationInterceptorURL.java index 18156f8c..3ef064a7 100644 --- a/src/main/java/space/space_spring/config/UserSpaceValidationInterceptorURL.java +++ b/src/main/java/space/space_spring/config/UserSpaceValidationInterceptorURL.java @@ -6,6 +6,7 @@ public enum UserSpaceValidationInterceptorURL { //SPACE("/space/**"), TEST("/space/{spaceId}/test/**"), + VOICEROOM("/space/{spaceId}/voiceRoom/**") ; private final String urlPattern; diff --git a/src/main/java/space/space_spring/controller/VoiceRoomController.java b/src/main/java/space/space_spring/controller/VoiceRoomController.java index 281930bd..a436d56d 100644 --- a/src/main/java/space/space_spring/controller/VoiceRoomController.java +++ b/src/main/java/space/space_spring/controller/VoiceRoomController.java @@ -7,6 +7,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import space.space_spring.argumentResolver.jwtLogin.JwtLoginAuth; +import space.space_spring.argumentResolver.userSpace.UserSpaceAuth; import space.space_spring.dao.UserSpaceDao; import space.space_spring.dao.VoiceRoomRepository; import space.space_spring.dto.VoiceRoom.*; @@ -47,15 +48,15 @@ public BaseResponse createRoom( @PathVariable("spaceId") @NotNull long spaceId, @JwtLoginAuth Long userId, @Validated @RequestBody PostVoiceRoomDto.Request voiceRoomRequest, + @UserSpaceAuth String userSpaceAuth, BindingResult bindingResult){ if(bindingResult.hasErrors()){ throw new VoiceRoomException(INVALID_VOICEROOM_REQUEST,getErrorMessage(bindingResult)); } - //해당 유저가 voice이 있는 space에 포함되어 있는지(권한이 있는지) 확인 - validateIsUserInSpace(spaceId,userId); //해당 유저가 현재 space에 대해 관리자 권한을 갖고 있는지 확인 - validateManagerPermission(spaceId,userId); + validateManagerPermission(userSpaceAuth); + //Todo response 내용을 무엇을 주면 좋을지 ( POST response 전체 기능 통일 하는 것일 좋아보임 ) PostVoiceRoomDto.Response res = new PostVoiceRoomDto.Response(voiceRoomService.createVoiceRoom(spaceId,voiceRoomRequest)); return new BaseResponse<>(res); @@ -72,8 +73,6 @@ public BaseResponse getRoomList( boolean showParticipantValue = (showParticipant != null) ? showParticipant : false; - //해당 유저가, voiceRoom이 있는 space에 포함되어 있는지(권한이 있는지) 확인 - validateIsUserInSpace(spaceId,userId); GetVoiceRoomList.Request voiceRoomList=new GetVoiceRoomList.Request(limit, showParticipant); @@ -89,8 +88,7 @@ public BaseResponse getToken( @PathVariable("voiceRoomId") @NotNull Long roomId, HttpServletResponse response ){ - //해당 유저가, voiceRoom이 있는 space에 포함되어 있는지(권한이 있는지) 확인 - validateIsUserInSpace(spaceId,userId); + //해당 voiceRoomId가 존재하는지 확인 validateVoiceRoom(roomId); //해당 voiceRoom이 해당 space에 속한것이 맞는지 확인 @@ -109,8 +107,7 @@ public BaseResponse getParticipants( @JwtLoginAuth Long userId, @PathVariable("voiceRoomId") @NotNull Long roomId ){ - //해당 유저가 voice이 있는 space에 포함되어 있는지(권한이 있는지) 확인 - validateIsUserInSpace(spaceId,userId); + //해당 voiceRoomId가 존재하는지 확인 validateVoiceRoom(roomId); //해당 voiceRoom이 해당 space에 속한것이 맞는지 확인 @@ -125,16 +122,15 @@ public BaseResponse updateVoiceRoom( @PathVariable("spaceId") @NotNull long spaceId, @JwtLoginAuth Long userId, @Validated @RequestBody PatchVoiceRoom patchVoiceRoom, + @UserSpaceAuth String userSpaceAuth, BindingResult bindingResult ){ if(bindingResult.hasErrors()){ throw new VoiceRoomException(INVALID_VOICEROOM_REQUEST,getErrorMessage(bindingResult)); } - //해당 유저가 voice이 있는 space에 포함되어 있는지(권한이 있는지) 확인 - validateIsUserInSpace(spaceId,userId); //해당 유저가 현재 space에 대해 관리자 권한을 갖고 있는지 확인 - validateManagerPermission(spaceId,userId); + validateManagerPermission(userSpaceAuth); //해당 voiceRoom이 해당 space에 속한것이 맞는지 확인 for(PatchVoiceRoom.UpdateRoom updateRoom : patchVoiceRoom.getUpdateRoomList()) { validateVoiceRoomInSpace(spaceId, updateRoom.getRoomId()); @@ -149,12 +145,12 @@ public BaseResponse updateVoiceRoom( public BaseResponse deleteVoiceRoom( @PathVariable("spaceId") @NotNull long spaceId, @JwtLoginAuth Long userId, - @PathVariable("voiceRoomId") @NotNull Long voiceRoomId + @PathVariable("voiceRoomId") @NotNull Long voiceRoomId, + @UserSpaceAuth String userSpaceAuth ){ - //해당 유저가 voice이 있는 space에 포함되어 있는지(권한이 있는지) 확인 - validateIsUserInSpace(spaceId,userId); + //해당 유저가 현재 space에 대해 관리자 권한을 갖고 있는지 확인 - validateManagerPermission(spaceId,userId); + validateManagerPermission(userSpaceAuth); //해당 voiceRoom이 해당 space에 속한것이 맞는지 확인 validateVoiceRoomInSpace(spaceId, voiceRoomId); @@ -169,14 +165,6 @@ public BaseResponse postRoomStatus(){ return new BaseResponse(null); } - private void validateIsUserInSpace( Long spaceId,Long userId) { - // 유저가 스페이스에 속할 경우 exception이 터지지 않을 것임 - // 그렇지 않을 경우, USER_IS_NOT_IN_SPACE 예외가 터질 것임 -> 추후 exception handling 과정 필요 - - //현재는 스페이스 접근 권한을 일괄적으로 예외 처리 - //분리 가능성 및 효용성 검토 필요 - userSpaceUtils.isUserInSpace(userId, spaceId); - } private boolean validateVoiceRoom(long voiceRoomId){ //Todo 해당 보이스룸이 존재하는지 확인 if(!voiceRoomRepository.existsByVoiceRoomId(voiceRoomId)){ @@ -196,15 +184,9 @@ private boolean validateVoiceRoomInSpace(long spaceId,long voiceRoomId){ } return true; } - private boolean validateManagerPermission(long spaceId,long userId){ + private boolean validateManagerPermission(String userSpaceAuth){ //해당 유저가 현재 space에 대해 관리자 권한을 갖고 있는지 확인 - //TODO 권한 확인 과정을 일괄적으로 처리 할 수 있는 코드가 필요해 보임 - User user = userUtils.findUserByUserId(userId); - Space space = spaceUtils.findSpaceBySpaceId(spaceId); - //이미 userSpace 존재 여부를 검사해서 null 검사는 생략함 - - if(!userSpaceDao.findUserSpaceByUserAndSpace(user,space).get().getUserSpaceAuth().toString().equals(MANAGER.getAuth())){ - System.out.print("Author :" +userSpaceDao.findUserSpaceByUserAndSpace(user,space).get().getUserSpaceAuth().toString()); + if(!userSpaceAuth.equals(MANAGER.getAuth())){ throw new VoiceRoomException(VOICEROOM_DO_NOT_HAVE_PERMISSION); } return true; diff --git a/src/main/java/space/space_spring/interceptor/UserSpaceValidationInterceptor.java b/src/main/java/space/space_spring/interceptor/UserSpaceValidationInterceptor.java index febda0d0..4b8398a0 100644 --- a/src/main/java/space/space_spring/interceptor/UserSpaceValidationInterceptor.java +++ b/src/main/java/space/space_spring/interceptor/UserSpaceValidationInterceptor.java @@ -63,7 +63,7 @@ private Long getUserSpace(long spaceId,long userId){ } Optional userSpace = userSpaceDao.findUserSpaceByUserAndSpace(userByUserId, spaceBySpaceId); Optional.ofNullable(userSpace - .orElseThrow(() -> new UserSpaceException(USER_IS_NOT_IN_SPACE))); + .orElseThrow(() -> new CustomException(USER_IS_NOT_IN_SPACE))); return userSpace.get().getUserSpaceId(); } From 5dc55faab3d0a9a67470276e470ff0f46ea6bfe9 Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:14:39 +0900 Subject: [PATCH 2/4] [refactoring] voiceRoom Exception -> CustomException --- .../controller/VoiceRoomController.java | 18 ++++++++--------- .../exception/VoiceRoomException.java | 20 ------------------- 2 files changed, 8 insertions(+), 30 deletions(-) delete mode 100644 src/main/java/space/space_spring/exception/VoiceRoomException.java diff --git a/src/main/java/space/space_spring/controller/VoiceRoomController.java b/src/main/java/space/space_spring/controller/VoiceRoomController.java index a436d56d..fc555a74 100644 --- a/src/main/java/space/space_spring/controller/VoiceRoomController.java +++ b/src/main/java/space/space_spring/controller/VoiceRoomController.java @@ -11,10 +11,8 @@ import space.space_spring.dao.UserSpaceDao; import space.space_spring.dao.VoiceRoomRepository; import space.space_spring.dto.VoiceRoom.*; -import space.space_spring.entity.Space; -import space.space_spring.entity.User; -import space.space_spring.entity.UserSpace; -import space.space_spring.exception.VoiceRoomException; + +import space.space_spring.exception.CustomException; import space.space_spring.response.BaseResponse; import space.space_spring.service.LiveKitService; import space.space_spring.service.VoiceRoomService; @@ -51,7 +49,7 @@ public BaseResponse createRoom( @UserSpaceAuth String userSpaceAuth, BindingResult bindingResult){ if(bindingResult.hasErrors()){ - throw new VoiceRoomException(INVALID_VOICEROOM_REQUEST,getErrorMessage(bindingResult)); + throw new CustomException(INVALID_VOICEROOM_REQUEST,getErrorMessage(bindingResult)); } //해당 유저가 현재 space에 대해 관리자 권한을 갖고 있는지 확인 @@ -127,7 +125,7 @@ public BaseResponse updateVoiceRoom( ){ if(bindingResult.hasErrors()){ - throw new VoiceRoomException(INVALID_VOICEROOM_REQUEST,getErrorMessage(bindingResult)); + throw new CustomException(INVALID_VOICEROOM_REQUEST,getErrorMessage(bindingResult)); } //해당 유저가 현재 space에 대해 관리자 권한을 갖고 있는지 확인 validateManagerPermission(userSpaceAuth); @@ -168,26 +166,26 @@ public BaseResponse postRoomStatus(){ private boolean validateVoiceRoom(long voiceRoomId){ //Todo 해당 보이스룸이 존재하는지 확인 if(!voiceRoomRepository.existsByVoiceRoomId(voiceRoomId)){ - throw new VoiceRoomException(VOICEROOM_NOT_EXIST); + throw new CustomException(VOICEROOM_NOT_EXIST); } return true; } private boolean validateVoiceRoomNameExist(String voiceRoomName){ if(!voiceRoomRepository.existsByName(voiceRoomName)){ - throw new VoiceRoomException(VOICEROOM_NAME_ALREADY_EXIST); + throw new CustomException(VOICEROOM_NAME_ALREADY_EXIST); } return true; } private boolean validateVoiceRoomInSpace(long spaceId,long voiceRoomId){ if(! (voiceRoomRepository.findById(voiceRoomId).getSpace().getSpaceId().equals(spaceId))){ - throw new VoiceRoomException(VOICEROOM_NOT_IN_SPACE); + throw new CustomException(VOICEROOM_NOT_IN_SPACE); } return true; } private boolean validateManagerPermission(String userSpaceAuth){ //해당 유저가 현재 space에 대해 관리자 권한을 갖고 있는지 확인 if(!userSpaceAuth.equals(MANAGER.getAuth())){ - throw new VoiceRoomException(VOICEROOM_DO_NOT_HAVE_PERMISSION); + throw new CustomException(VOICEROOM_DO_NOT_HAVE_PERMISSION); } return true; } diff --git a/src/main/java/space/space_spring/exception/VoiceRoomException.java b/src/main/java/space/space_spring/exception/VoiceRoomException.java deleted file mode 100644 index c2972b23..00000000 --- a/src/main/java/space/space_spring/exception/VoiceRoomException.java +++ /dev/null @@ -1,20 +0,0 @@ -package space.space_spring.exception; - -import lombok.Getter; -import space.space_spring.response.status.ResponseStatus; - -@Getter -public class VoiceRoomException extends RuntimeException{ - private final ResponseStatus exceptionStatus; - - public VoiceRoomException(ResponseStatus exceptionStatus) { - super(exceptionStatus.getMessage()); - this.exceptionStatus = exceptionStatus; - } - - public VoiceRoomException(ResponseStatus exceptionStatus, String message) { - super(message); - this.exceptionStatus = exceptionStatus; - } - -} From 15a063eb7eabeb2a22091f99e42d88855de16d98 Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:17:23 +0900 Subject: [PATCH 3/4] [feat] JWT Signature Exception add --- .../JwtExceptionControllerAdvice.java | 11 +++++++++++ .../response/status/BaseExceptionResponseStatus.java | 1 + 2 files changed, 12 insertions(+) diff --git a/src/main/java/space/space_spring/exceptionHandler/JwtExceptionControllerAdvice.java b/src/main/java/space/space_spring/exceptionHandler/JwtExceptionControllerAdvice.java index 9d2b67d4..89456585 100644 --- a/src/main/java/space/space_spring/exceptionHandler/JwtExceptionControllerAdvice.java +++ b/src/main/java/space/space_spring/exceptionHandler/JwtExceptionControllerAdvice.java @@ -10,6 +10,10 @@ import space.space_spring.exception.jwt.unauthorized.JwtUnauthorizedTokenException; import space.space_spring.response.BaseErrorResponse; +import java.security.SignatureException; + +import static space.space_spring.response.status.BaseExceptionResponseStatus.WRONG_SIGNATURE_JWT; + @Slf4j @Priority(0) @RestControllerAdvice @@ -28,4 +32,11 @@ public BaseErrorResponse handle_JwtUnauthorizedException(JwtUnauthorizedTokenExc log.error("[handle_JwtUnauthorizedException]", e); return new BaseErrorResponse(e.getExceptionStatus()); } + + @ResponseStatus(HttpStatus.UNAUTHORIZED) + @ExceptionHandler(SignatureException.class) + public BaseErrorResponse handle_JwtSignatureException(SignatureException e) { + log.error("[handle_JwtUnauthorizedException]", e); + return new BaseErrorResponse(WRONG_SIGNATURE_JWT); + } } diff --git a/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java b/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java index a0da73fa..e8c8f992 100644 --- a/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java +++ b/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java @@ -37,6 +37,7 @@ public enum BaseExceptionResponseStatus implements ResponseStatus { EXPIRED_TOKEN(4005, HttpStatus.UNAUTHORIZED, "만료된 토큰입니다."), TOKEN_MISMATCH(4006, HttpStatus.UNAUTHORIZED, "로그인 정보가 토큰 정보와 일치하지 않습니다."), CANNOT_FIND_USER_ID(4007, HttpStatus.UNAUTHORIZED,"토큰의 userId정보를 찾을 수 없습니다."), + WRONG_SIGNATURE_JWT(4008,HttpStatus.UNAUTHORIZED,"JWT 서명이 잘못 되었습니다."), /** * 5000: User 오류 From b50df26f975852a31299c533f4a450afb1ad7846 Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Tue, 13 Aug 2024 20:37:10 +0900 Subject: [PATCH 4/4] [feat] add JWT signature exception throw --- .../JwtExceptionControllerAdvice.java | 11 ----------- .../java/space/space_spring/jwt/JwtLoginProvider.java | 6 +++++- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/main/java/space/space_spring/exceptionHandler/JwtExceptionControllerAdvice.java b/src/main/java/space/space_spring/exceptionHandler/JwtExceptionControllerAdvice.java index 89456585..9d2b67d4 100644 --- a/src/main/java/space/space_spring/exceptionHandler/JwtExceptionControllerAdvice.java +++ b/src/main/java/space/space_spring/exceptionHandler/JwtExceptionControllerAdvice.java @@ -10,10 +10,6 @@ import space.space_spring.exception.jwt.unauthorized.JwtUnauthorizedTokenException; import space.space_spring.response.BaseErrorResponse; -import java.security.SignatureException; - -import static space.space_spring.response.status.BaseExceptionResponseStatus.WRONG_SIGNATURE_JWT; - @Slf4j @Priority(0) @RestControllerAdvice @@ -32,11 +28,4 @@ public BaseErrorResponse handle_JwtUnauthorizedException(JwtUnauthorizedTokenExc log.error("[handle_JwtUnauthorizedException]", e); return new BaseErrorResponse(e.getExceptionStatus()); } - - @ResponseStatus(HttpStatus.UNAUTHORIZED) - @ExceptionHandler(SignatureException.class) - public BaseErrorResponse handle_JwtSignatureException(SignatureException e) { - log.error("[handle_JwtUnauthorizedException]", e); - return new BaseErrorResponse(WRONG_SIGNATURE_JWT); - } } diff --git a/src/main/java/space/space_spring/jwt/JwtLoginProvider.java b/src/main/java/space/space_spring/jwt/JwtLoginProvider.java index 7a434287..7427b8c4 100644 --- a/src/main/java/space/space_spring/jwt/JwtLoginProvider.java +++ b/src/main/java/space/space_spring/jwt/JwtLoginProvider.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import space.space_spring.entity.User; +import space.space_spring.exception.CustomException; import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; import space.space_spring.exception.jwt.unauthorized.JwtInvalidTokenException; import space.space_spring.exception.jwt.unauthorized.JwtMalformedTokenException; @@ -56,10 +57,13 @@ public boolean isExpiredToken(String accessToken) { throw new JwtMalformedTokenException(MALFORMED_TOKEN); } catch (IllegalArgumentException e) { throw new JwtInvalidTokenException(INVALID_TOKEN); - } catch (JwtException e) { + } catch (SignatureException e){ + throw new CustomException(WRONG_SIGNATURE_JWT); + }catch (JwtException e) { log.error("[JwtTokenProvider.validateAccessToken]", e); throw e; } + } public Long getUserIdFromToken(String accessToken) {