Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
4805656
[FIX] SecurityContext에서 인증 객체 타입 불일치 해결
Kim-TaeUk Mar 3, 2025
0cc731a
[REMOVE] 불필요한 주석 제거
Kim-TaeUk Mar 3, 2025
84fda4f
[STYLE] 파일 끝 개행 추가
Kim-TaeUk Mar 3, 2025
c209fe2
[STYLE] 코드 포맷팅
Kim-TaeUk Mar 3, 2025
cfa319f
[RENAME] JWT 인증 객체임을 명확하게 하기 위한 rename
Kim-TaeUk Mar 3, 2025
b97b10b
[CHORE] 메서드 보안 활성화를 위한 @EnableMethodSecurity 추가
Kim-TaeUk Mar 12, 2025
066b7e5
[STYLE] 코드 컨벤션에 맞게 formatting
Kim-TaeUk Mar 12, 2025
9de7622
[FEAT] 리소스 권한 검증을 위한 ResourceAuthorizationValidator 인터페이스 추가
Kim-TaeUk Mar 12, 2025
09f5de5
[FEAT] 리소스 권한 검증을 위한 ResourceAuthorizationHandler 추가
Kim-TaeUk Mar 12, 2025
ddafe03
[FEAT] ResourceAuthorizationHandler에서 ResourceAuthorizationValidator …
Kim-TaeUk Mar 12, 2025
f843b07
[FEAT] ResourceAuthorizationHandler에 리소스 권한 검증 기능 추가
Kim-TaeUk Mar 12, 2025
b76c01d
[REFACTOR] Optional을 통해 hasPermission 메서드 리팩터링
Kim-TaeUk Mar 12, 2025
ca48711
[FEAT] FeedAuthorizationValidator 추가
Kim-TaeUk Mar 13, 2025
16176e6
[FEAT] FeedRepository 주입 by @RequiredArgsConstructor
Kim-TaeUk Mar 13, 2025
354d10e
[FEAT] getResourceType() 구현
Kim-TaeUk Mar 13, 2025
f861975
[FEAT] 존재하는 리소스인지 조회
Kim-TaeUk Mar 13, 2025
27e7082
[FEAT] 권한이 없는 경우 예외 throw
Kim-TaeUk Mar 13, 2025
8d44101
[REFACTOR] feed 조회 로직 메서드로 추출
Kim-TaeUk Mar 13, 2025
92af2d4
[REFACTOR] 권한 검증 로직 메서드로 추출
Kim-TaeUk Mar 13, 2025
47456de
[FEAT] AuthorizationService 추가
Kim-TaeUk Mar 13, 2025
eaa546c
[FEAT] AuthorizationService에 UserRepository 주입
Kim-TaeUk Mar 13, 2025
3709b57
[FEAT] 사용자 존재 여부 검증 로직 추가
Kim-TaeUk Mar 13, 2025
0891bac
[REFACTOR] 메서드 rename
Kim-TaeUk Mar 13, 2025
73a08cc
[FEAT] ResourceAuthorizationHandler로 이후 검증 로직 위임
Kim-TaeUk Mar 13, 2025
8f08a2c
[REFACTOR] Principal 대신 @AuthenticationPrincipal 사용
Kim-TaeUk Mar 13, 2025
3cf9a46
[FEAT] 권한 검증을 위한 @PreAuthorize 추가
Kim-TaeUk Mar 13, 2025
165e66d
[REMOVE] 사용하지 않는 코드 제거
Kim-TaeUk Mar 13, 2025
f66efd4
[FIX] FeedService.deleteFeed 메서드 시그니처 변경
Kim-TaeUk Mar 13, 2025
619e2bf
[FIX] feed 삭제 jpa 쿼리 메서드 변경
Kim-TaeUk Mar 13, 2025
ca3fa38
[FEAT] JwtValidationType 추가: INVALID_SIGNATURE
Kim-TaeUk Mar 16, 2025
c760627
[FIX] JWTUtil.validateJWT에서 잡지 않던 exception catch
Kim-TaeUk Mar 16, 2025
6b31fe9
[REMOVE] 의미 없는 try-catch 블럭 삭제
Kim-TaeUk Mar 16, 2025
4999b13
[FEAT] invalid한 token과 비로그인 사용자 구분 로직 추가
Kim-TaeUk Mar 16, 2025
1ae92fe
[FEAT] invalid한 token과 비로그인 사용자 구분 로직 추가
Kim-TaeUk Mar 16, 2025
31eb1f0
[FEAT] 비로그인 사용자 SecurityContextHolder에 ROLE_ANONYMOUS로 설정
Kim-TaeUk Mar 16, 2025
4c98ec0
[FEAT] @AuthenticationPrincipal User 변환을 위한 CustomUserArgumentResolve…
Kim-TaeUk Mar 16, 2025
8c8442e
[FEAT] CustomUserArgumentResolver 등록을 위한 WebConfig 추가
Kim-TaeUk Mar 16, 2025
8352770
[REMOVE] AuthorizationService에서 user 존재 검증 로직 제거
Kim-TaeUk Mar 16, 2025
18eb3ab
[FIX] AuthorizationService.validate 메서드 시그니처 변경
Kim-TaeUk Mar 16, 2025
3cfce58
[REFACTOR] Principal 대신 @AuthenticationPrincipal User 사용
Kim-TaeUk Mar 16, 2025
32c9b7a
[REMOVE] 불필요한 principal.getName() 후 User 조회 로직 제거
Kim-TaeUk Mar 16, 2025
d964616
[FIX] 변경된 AuthorizationService.validate 시그니처에 맞추어 파라미터 수정
Kim-TaeUk Mar 16, 2025
e419947
[REMOVE] 주입하여 사용하지 않는 UserService 제거
Kim-TaeUk Mar 16, 2025
822c560
[STYLE] 메서드 순서 변경
Kim-TaeUk Mar 16, 2025
296f81e
[FEAT] 인증된 사용자일 때만 처리하는 요청에 @PreAuthorize 추가
Kim-TaeUk Mar 16, 2025
50f8355
[FEAT] 리소스 조작 권한 확인을 위해 @PreAuthorize에 validate 추가
Kim-TaeUk Mar 16, 2025
60bc5c2
[REFACTOR] Feed 객체 생성 - 정적 팩토리 메서드로 변경
Kim-TaeUk Mar 16, 2025
6f512be
[REFACTOR] Novel 존재 여부 검증 로직 Optional로 개선
Kim-TaeUk Mar 16, 2025
1ceceba
[REFACTOR] Principal 대신 @AuthenticationPrincipal User 사용
Kim-TaeUk Mar 17, 2025
22fff07
[REMOVE] 불필요한 principal.getName() 후 User 조회 로직 제거
Kim-TaeUk Mar 17, 2025
e9bcbf6
[FEAT] 인증된 사용자일 때만 처리하는 요청에 @PreAuthorize 추가
Kim-TaeUk Mar 17, 2025
5547166
[REFACTOR] Principal 대신 @AuthenticationPrincipal User 사용
Kim-TaeUk Mar 17, 2025
0e8a1a4
[FEAT] 인증된 사용자일 때만 처리하는 요청에 @PreAuthorize 추가
Kim-TaeUk Mar 17, 2025
a22000c
[REMOVE] 불필요한 principal.getName() 후 User 조회 로직 제거
Kim-TaeUk Mar 17, 2025
09179b0
[REMOVE] 주입하여 사용하지 않는 UserService 제거
Kim-TaeUk Mar 17, 2025
874df17
[REFACTOR] Principal 대신 @AuthenticationPrincipal User 사용
Kim-TaeUk Mar 17, 2025
b73c4b7
[REMOVE] 불필요한 principal.getName() 후 User 조회 로직 제거
Kim-TaeUk Mar 17, 2025
9c6c4b0
[REFACTOR] 파라미터 rename
Kim-TaeUk Mar 17, 2025
4821dba
[REMOVE] 주입하여 사용하지 않는 UserService 제거
Kim-TaeUk Mar 17, 2025
bff8bce
[FEAT] 인증된 사용자일 때만 처리하는 요청에 @PreAuthorize 추가
Kim-TaeUk Mar 17, 2025
aaa9284
[FEAT] BlockAuthorizationValidator 추가
Kim-TaeUk Mar 17, 2025
b53d9a9
[FEAT] 리소스 조작 권한 확인을 위해 @PreAuthorize에 validate 추가
Kim-TaeUk Mar 17, 2025
d0378e3
[REMOVE] BlockService에서 권한 검증 로직 삭제
Kim-TaeUk Mar 17, 2025
d7591df
[FIX] BlockService.deleteBlock 메서드 시그니처 변경
Kim-TaeUk Mar 17, 2025
46d3ae4
[STYLE] 컨벤션에 맞게 @Transactional 어노테이션 수정
Kim-TaeUk Mar 17, 2025
d881f7b
[REMOVE] 공지 구 엔티티 Notice 관련 클래스 및 코드 제거
Kim-TaeUk Mar 23, 2025
a5a281c
[REFACTOR] Principal 대신 @AuthenticationPrincipal User 사용
Kim-TaeUk Mar 23, 2025
317e110
[REMOVE] 불필요한 principal.getName() 후 User 조회 로직 제거
Kim-TaeUk Mar 23, 2025
04323ec
[REMOVE] 주입하여 사용하지 않는 UserService 제거
Kim-TaeUk Mar 23, 2025
5f61d7d
[STYLE] 메서드 순서 변경
Kim-TaeUk Mar 23, 2025
3d65ece
[FEAT] 인증된 사용자일 때만 처리하는 요청에 @PreAuthorize 추가
Kim-TaeUk Mar 23, 2025
c2dadb9
[FEAT] 알림 타입이 NOTICE 그룹에 속하는지 검증하는 커스텀 Validator 및 annotation 추가
Kim-TaeUk Mar 24, 2025
a04225e
[FEAT] NotificationAuthorizationValidator 추가
Kim-TaeUk Mar 24, 2025
6618d4c
[REFACTOR] NotificationCreateRequest에서 custom annotation으로 검증하도록 변경
Kim-TaeUk Mar 24, 2025
d32eb9e
[COMMENT] 사용되지 않는 로직에 주석 추가
Kim-TaeUk Mar 24, 2025
b4a5ca5
[FEAT] 리소스 조작 권한 확인을 위해 @PreAuthorize에 validate 추가
Kim-TaeUk Mar 24, 2025
f37c499
[REFACTOR] Principal 대신 @AuthenticationPrincipal User 사용
Kim-TaeUk Mar 24, 2025
0fc8ffa
[REMOVE] 불필요한 principal.getName() 후 User 조회 로직 제거
Kim-TaeUk Mar 24, 2025
ebcaab8
[REMOVE] 주입하여 사용하지 않는 UserService 제거
Kim-TaeUk Mar 24, 2025
57a5345
[REFACTOR] 메서드 순서 조정
Kim-TaeUk Mar 24, 2025
1995a54
[FEAT] 인증된 사용자일 때만 처리하는 요청에 @PreAuthorize 추가
Kim-TaeUk Mar 24, 2025
465e7d6
[FEAT] NovelAuthorizationValidator 추가
Kim-TaeUk Mar 24, 2025
c2bb83b
[FEAT] UserNovelAuthorizationValidator 추가
Kim-TaeUk Mar 24, 2025
88299b4
[FEAT] 리소스 조작 권한 확인을 위해 @PreAuthorize에 validate 추가
Kim-TaeUk Mar 24, 2025
a52b0a7
[REFACTOR] Principal 대신 @AuthenticationPrincipal User 사용
Kim-TaeUk Mar 24, 2025
c149db3
[REMOVE] 불필요한 principal.getName() 후 User 조회 로직 제거
Kim-TaeUk Mar 24, 2025
b654fe1
[STYLE] 코드 포맷팅
Kim-TaeUk Mar 24, 2025
2483205
[REFACTOR] 메서드 순서 조정
Kim-TaeUk Mar 24, 2025
c91be4a
[FEAT] 인증된 사용자일 때만 처리하는 요청에 @PreAuthorize 추가
Kim-TaeUk Mar 26, 2025
99e3fdb
[RENAME] 파라미터 이름 변경
Kim-TaeUk Mar 26, 2025
015386b
[REFACTOR] Principal 대신 @AuthenticationPrincipal User 사용
Kim-TaeUk Mar 26, 2025
e2068cb
[REMOVE] 불필요한 principal.getName() 후 User 조회 로직 제거
Kim-TaeUk Mar 26, 2025
ff6c852
[REMOVE] 주입하여 사용하지 않는 UserService 제거
Kim-TaeUk Mar 26, 2025
b8695c3
[STYLE] 메서드 순서 변경
Kim-TaeUk Mar 26, 2025
52dfd29
[FEAT] 인증된 사용자일 때만 처리하는 요청에 @PreAuthorize 추가
Kim-TaeUk Mar 26, 2025
b07cccc
[STYLE] 코드 포맷팅
Kim-TaeUk Mar 26, 2025
08e18e2
[FEAT] 리소스 조작 권한 확인을 위해 @PreAuthorize에 validate 추가
Kim-TaeUk Mar 28, 2025
046988c
[FEAT] UserNovelRepository.findByNovel_NovelIdAndUser 추가
Kim-TaeUk Mar 28, 2025
2bc91a6
[FIX] getUserNovelOrException의 메서드 시그니처 변경
Kim-TaeUk Mar 28, 2025
e7b8c05
[REMOVE] Novel 이중 검증 코드 삭제
Kim-TaeUk Mar 28, 2025
a6c7f5f
[FIX] getUserNovelOrExceptionNovel에서 findByNovel_NovelIdAndUser 사용하도록 변경
Kim-TaeUk Mar 28, 2025
7a03caf
[REFACTOR] POST /reissue 시 변수 인라인 처리
Kim-TaeUk Mar 28, 2025
290d5ba
[REFACTOR] LogoutRequest를 서비스에 그대로 전달하도록 리팩터링
Kim-TaeUk Mar 28, 2025
82930aa
[FIX] blockingId와 userId가 같을 때로 수정
Kim-TaeUk Mar 30, 2025
e002c1c
[STYLE] 코드 포맷팅
Kim-TaeUk Mar 30, 2025
9fce815
[REMOVE] 리소스 수정을 위한 중복 검증 제거
Kim-TaeUk Mar 30, 2025
3cf8a3e
[REFACTOR] updateFeed() 메서드 시그니처 수정
Kim-TaeUk Mar 30, 2025
805b627
[REMOVE] 사용하지 않는 리소스 수정 권한 검증 로직 제거
Kim-TaeUk Mar 30, 2025
4fedcd7
[FIX] 잘못 검증하고 있던 좋아요 취소 관련 로직 제거
Kim-TaeUk Mar 30, 2025
17b3ffc
[RENAME] 좋아요 관련 CustomError 간결하게 rename
Kim-TaeUk Mar 30, 2025
244486d
[FIX] 좋아요 취소 로직 수정
Kim-TaeUk Mar 30, 2025
4e4ead0
[REFACTOR] 비로그인 사용자때문에 발생하는 null 분기 Optional로 처리
Kim-TaeUk Mar 30, 2025
822c411
[FEAT] FeedAccessValidator 도입으로 피드 접근 권한 검증 책임 분리
Kim-TaeUk Apr 8, 2025
38eeabf
[REFACTOR] 피드 관련 API에서 FeedAccessValidator를 통한 접근 권한 검증 로직 추가
Kim-TaeUk Apr 8, 2025
51769c6
[REFACTOR] FeedAccessValidator 도입으로 서비스 레이어 중복 검사 로직 제거 및 불필요 메서드 정리
Kim-TaeUk Apr 8, 2025
af28ac4
[REFACTOR] Feed 도메인에 getWriterId() 추가 및 외부 접근 시 해당 메서드 사용으로 추상화 강화
Kim-TaeUk Apr 12, 2025
bbd5cb7
[FEAT] Feed 도메인에 isMine() 추가
Kim-TaeUk Apr 12, 2025
625253b
[REFACTOR] isFeedOwner() 대신 isMine() 사용하도록 변경
Kim-TaeUk Apr 12, 2025
cc78d2b
[REMOVE] 사용하지 않는 isFeedOwner() 제거
Kim-TaeUk Apr 12, 2025
2083bca
[REMOVE] 사용하지 않는 validateAdminPrivilege() 제거
Kim-TaeUk Apr 18, 2025
03d87c8
[REMOVE] 사용하지 않는 validateNoticeType() 제거
Kim-TaeUk Apr 18, 2025
c9f6cb6
[FIX] 리소스타입 휴먼에러 발생 시 Runtime Exception 아닌 Custom Exception 던지도록 수정
Kim-TaeUk Apr 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/main/java/org/websoso/WSSServer/auth/AuthorizationService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.websoso.WSSServer.auth;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.websoso.WSSServer.domain.User;

@Service
@RequiredArgsConstructor
public class AuthorizationService {

private final ResourceAuthorizationHandler resourceAuthorizationHandler;

public boolean validate(Long resourceId, User user, Class<?> resourceType) {
return resourceAuthorizationHandler.authorizeResourceAccess(resourceId, user, resourceType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.websoso.WSSServer.auth;

import lombok.RequiredArgsConstructor;
import org.springframework.core.MethodParameter;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.websoso.WSSServer.domain.User;
import org.websoso.WSSServer.service.UserService;

@Component
@RequiredArgsConstructor
public class CustomUserArgumentResolver implements HandlerMethodArgumentResolver {

private final UserService userService;

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(User.class) &&
parameter.hasParameterAnnotation(AuthenticationPrincipal.class);
}

@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication == null || authentication instanceof AnonymousAuthenticationToken) {
return null;
}

Long userId = (Long) authentication.getPrincipal();
return userService.getUserOrException(userId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.websoso.WSSServer.auth;

import static org.websoso.WSSServer.exception.error.CustomAuthorizationError.UNSUPPORTED_RESOURCE_TYPE;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.websoso.WSSServer.auth.validator.ResourceAuthorizationValidator;
import org.websoso.WSSServer.domain.User;
import org.websoso.WSSServer.exception.exception.CustomAuthorizationException;

@Component
public class ResourceAuthorizationHandler {

private final Map<Class<?>, ResourceAuthorizationValidator> validatorMap = new HashMap<>();

@Autowired
public ResourceAuthorizationHandler(List<ResourceAuthorizationValidator> validators) {
for (ResourceAuthorizationValidator validator : validators) {
validatorMap.put(validator.getResourceType(), validator);
}
}

public boolean authorizeResourceAccess(Long resourceId, User user, Class<?> resourceType) {
return Optional.ofNullable(validatorMap.get(resourceType))
.orElseThrow(() -> new CustomAuthorizationException(
UNSUPPORTED_RESOURCE_TYPE, "Unsupported resource type for authorization"))
.hasPermission(resourceId, user);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.websoso.WSSServer.auth.validator;

import static org.websoso.WSSServer.exception.error.CustomBlockError.BLOCK_NOT_FOUND;
import static org.websoso.WSSServer.exception.error.CustomBlockError.INVALID_AUTHORIZED_BLOCK;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.websoso.WSSServer.domain.Block;
import org.websoso.WSSServer.domain.User;
import org.websoso.WSSServer.exception.exception.CustomBlockException;
import org.websoso.WSSServer.repository.BlockRepository;

@Component
@RequiredArgsConstructor
public class BlockAuthorizationValidator implements ResourceAuthorizationValidator {

private final BlockRepository blockRepository;

@Override
public boolean hasPermission(Long blockId, User user) {
Block block = getBlockOrException(blockId);

if (!isBlockOwner(block, user)) {
throw new CustomBlockException(INVALID_AUTHORIZED_BLOCK,
"block with the given blockId is not from user with the given userId");
}
return true;
}

private Block getBlockOrException(Long blockId) {
return blockRepository.findById(blockId)
.orElseThrow(() -> new CustomBlockException(BLOCK_NOT_FOUND,
"block with the given blockId was not found"));
}

private boolean isBlockOwner(Block block, User user) {
return block.getBlockingId().equals(user.getUserId());
}

@Override
public Class<?> getResourceType() {
return Block.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.websoso.WSSServer.auth.validator;

import static org.websoso.WSSServer.exception.error.CustomFeedError.BLOCKED_USER_ACCESS;
import static org.websoso.WSSServer.exception.error.CustomFeedError.FEED_NOT_FOUND;
import static org.websoso.WSSServer.exception.error.CustomFeedError.HIDDEN_FEED_ACCESS;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.websoso.WSSServer.domain.Feed;
import org.websoso.WSSServer.domain.User;
import org.websoso.WSSServer.exception.exception.CustomFeedException;
import org.websoso.WSSServer.repository.FeedRepository;
import org.websoso.WSSServer.service.BlockService;

@Component
@RequiredArgsConstructor
public class FeedAccessValidator {

private final FeedRepository feedRepository;
private final BlockService blockService;

public boolean canAccess(Long feedId, User user) {
Feed feed = getFeedOrException(feedId);

if (feed.getUser().equals(user)) {
return true;
}

if (feed.getIsHidden()) {
throw new CustomFeedException(HIDDEN_FEED_ACCESS, "Cannot access hidden feed.");
}

if (blockService.isBlocked(user.getUserId(), feed.getWriterId())) {
throw new CustomFeedException(BLOCKED_USER_ACCESS,
"cannot access this feed because either you or the feed author has blocked the other.");
}

return true;
}

private Feed getFeedOrException(Long feedId) {
return feedRepository.findById(feedId)
.orElseThrow(() -> new CustomFeedException(FEED_NOT_FOUND, "feed with the given id was not found"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.websoso.WSSServer.auth.validator;

import static org.websoso.WSSServer.exception.error.CustomFeedError.FEED_NOT_FOUND;
import static org.websoso.WSSServer.exception.error.CustomUserError.INVALID_AUTHORIZED;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.websoso.WSSServer.domain.Feed;
import org.websoso.WSSServer.domain.User;
import org.websoso.WSSServer.exception.exception.CustomFeedException;
import org.websoso.WSSServer.exception.exception.CustomUserException;
import org.websoso.WSSServer.repository.FeedRepository;

@Component
@RequiredArgsConstructor
public class FeedAuthorizationValidator implements ResourceAuthorizationValidator {

private final FeedRepository feedRepository;

@Override
public boolean hasPermission(Long feedId, User user) {
Feed feed = getFeedOrException(feedId);

if (!feed.isMine(user.getUserId())) {
throw new CustomUserException(INVALID_AUTHORIZED,
"User with ID " + user.getUserId() + " is not the owner of feed " + feed.getFeedId());
}
return true;
}

private Feed getFeedOrException(Long feedId) {
return feedRepository.findById(feedId)
.orElseThrow(() -> new CustomFeedException(FEED_NOT_FOUND, "feed with the given id was not found"));
}

@Override
public Class<?> getResourceType() {
return Feed.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.websoso.WSSServer.auth.validator;

import static org.websoso.WSSServer.domain.common.Role.ADMIN;
import static org.websoso.WSSServer.exception.error.CustomNotificationError.NOTIFICATION_ADMIN_ONLY;
import static org.websoso.WSSServer.exception.error.CustomNotificationError.NOTIFICATION_NOT_FOUND;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.websoso.WSSServer.domain.Notification;
import org.websoso.WSSServer.domain.User;
import org.websoso.WSSServer.exception.exception.CustomNotificationException;
import org.websoso.WSSServer.repository.NotificationRepository;

@Component
@RequiredArgsConstructor
public class NotificationAuthorizationValidator implements ResourceAuthorizationValidator {

private final NotificationRepository notificationRepository;

@Override
public boolean hasPermission(Long resourceId, User user) {
if (resourceId == null) {
return isAdmin(user);
}

// 수정이나 삭제에서 리소스 존재 여부 검증을 위함
Notification notification = getNotificationOrException(resourceId);
return isAdmin(user);
}

private Notification getNotificationOrException(Long notificationId) {
return notificationRepository.findById(notificationId)
.orElseThrow(() -> new CustomNotificationException(NOTIFICATION_NOT_FOUND,
"notification with the given id is not found"));
}

private boolean isAdmin(User user) {
if (user.getRole() != ADMIN) {
throw new CustomNotificationException(NOTIFICATION_ADMIN_ONLY,
"User who tried to create, modify, or delete the notice is not an ADMIN.");
}
return true;
}

@Override
public Class<?> getResourceType() {
return Notification.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.websoso.WSSServer.auth.validator;

import static org.websoso.WSSServer.exception.error.CustomNovelError.NOVEL_NOT_FOUND;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.websoso.WSSServer.domain.Novel;
import org.websoso.WSSServer.domain.User;
import org.websoso.WSSServer.exception.exception.CustomNovelException;
import org.websoso.WSSServer.repository.NovelRepository;

@Component
@RequiredArgsConstructor
public class NovelAuthorizationValidator implements ResourceAuthorizationValidator {

private final NovelRepository novelRepository;

@Override
public boolean hasPermission(Long resourceId, User user) {
Novel novel = getNovelOrException(resourceId);
return true;
}

private Novel getNovelOrException(Long novelId) {
return novelRepository.findById(novelId)
.orElseThrow(() -> new CustomNovelException(NOVEL_NOT_FOUND, "novel with the given id is not found"));
}

@Override
public Class<?> getResourceType() {
return Novel.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.websoso.WSSServer.auth.validator;

import org.websoso.WSSServer.domain.User;

public interface ResourceAuthorizationValidator {

boolean hasPermission(Long resourceId, User user);

Class<?> getResourceType();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.websoso.WSSServer.auth.validator;

import static org.websoso.WSSServer.exception.error.CustomNovelError.NOVEL_NOT_FOUND;
import static org.websoso.WSSServer.exception.error.CustomUserNovelError.USER_NOVEL_NOT_FOUND;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.websoso.WSSServer.domain.Novel;
import org.websoso.WSSServer.domain.User;
import org.websoso.WSSServer.domain.UserNovel;
import org.websoso.WSSServer.exception.exception.CustomNovelException;
import org.websoso.WSSServer.exception.exception.CustomUserNovelException;
import org.websoso.WSSServer.repository.NovelRepository;
import org.websoso.WSSServer.repository.UserNovelRepository;

@Component
@RequiredArgsConstructor
public class UserNovelAuthorizationValidator implements ResourceAuthorizationValidator {

private final NovelRepository novelRepository;
private final UserNovelRepository userNovelRepository;

@Override
public boolean hasPermission(Long resourceId, User user) {
Novel novel = getNovelOrException(resourceId);
UserNovel userNovel = getUserNovelOrException(user, novel);
return true;
}

private Novel getNovelOrException(Long novelId) {
return novelRepository.findById(novelId)
.orElseThrow(() -> new CustomNovelException(NOVEL_NOT_FOUND, "novel with the given id is not found"));
}

private UserNovel getUserNovelOrException(User user, Novel novel) {
return userNovelRepository.findByNovelAndUser(novel, user)
.orElseThrow(() -> new CustomUserNovelException(USER_NOVEL_NOT_FOUND,
"user novel with the given user and novel is not found"));
}

@Override
public Class<?> getResourceType() {
return UserNovel.class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
Expand All @@ -18,6 +19,7 @@
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final CustomJwtAuthenticationEntryPoint customJwtAuthenticationEntryPoint;
Expand Down
Loading
Loading