diff --git a/dplanner/src/main/java/com/dp/dplanner/service/ReservationService.java b/dplanner/src/main/java/com/dp/dplanner/service/ReservationService.java index 9290cce..b13a8f4 100644 --- a/dplanner/src/main/java/com/dp/dplanner/service/ReservationService.java +++ b/dplanner/src/main/java/com/dp/dplanner/service/ReservationService.java @@ -366,7 +366,7 @@ public ReservationDto.SliceResponse findAllReservationsRejected(Long managerId, return new ReservationDto.SliceResponse(ReservationDto.Response.ofList(reservations.getContent()), pageableAmin, reservations.hasNext()); } - @RequiredAuthority(authority = RETURN_MSG_READ) + @RequiredAuthority(authority = {RETURN_MSG_READ,SCHEDULE_ALL}) @Transactional(readOnly = true) public ReservationDto.SliceResponse findAllReservationsConfirmed(Long managerId, ReservationDto.Request requestDto, String status, Pageable pageable) { Pageable pageableAmin = PageRequest.of(pageable.getPageNumber(),100, Sort.by(Sort.Direction.DESC, "period.startDateTime")); diff --git a/dplanner/src/main/java/com/dp/dplanner/service/aop/annotation/RequiredAuthority.java b/dplanner/src/main/java/com/dp/dplanner/service/aop/annotation/RequiredAuthority.java index 676130c..510de92 100644 --- a/dplanner/src/main/java/com/dp/dplanner/service/aop/annotation/RequiredAuthority.java +++ b/dplanner/src/main/java/com/dp/dplanner/service/aop/annotation/RequiredAuthority.java @@ -18,7 +18,7 @@ ClubRole role() default ClubRole.NONE; - ClubAuthorityType authority() default ClubAuthorityType.NONE; + ClubAuthorityType[] authority() default ClubAuthorityType.NONE; } diff --git a/dplanner/src/main/java/com/dp/dplanner/service/aop/aspect/RequiredAuthorityAspect.java b/dplanner/src/main/java/com/dp/dplanner/service/aop/aspect/RequiredAuthorityAspect.java index ca54fd0..963e75a 100644 --- a/dplanner/src/main/java/com/dp/dplanner/service/aop/aspect/RequiredAuthorityAspect.java +++ b/dplanner/src/main/java/com/dp/dplanner/service/aop/aspect/RequiredAuthorityAspect.java @@ -12,6 +12,9 @@ import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; +import java.util.Arrays; +import java.util.Optional; + import static com.dp.dplanner.domain.club.ClubRole.ADMIN; import static com.dp.dplanner.exception.ErrorResult.*; @@ -27,8 +30,10 @@ public class RequiredAuthorityAspect { "&& @annotation(requiredAuthority) " + "&& args(clubMemberId, ..)") public void checkAuthority(Long clubMemberId, RequiredAuthority requiredAuthority) throws Throwable { - if(!requiredAuthority.authority().equals(ClubAuthorityType.NONE) ){ - if (!hasAuthority(clubMemberId, requiredAuthority.authority())) { + if (!requiredAuthority.authority().equals(ClubAuthorityType.NONE)) { + boolean hasRequiredAuthority = Arrays.stream(requiredAuthority.authority()) + .anyMatch(authorityType -> hasAuthority(clubMemberId, authorityType)); + if (!hasRequiredAuthority) { throw new ServiceException(AUTHORIZATION_DENIED); } } else if (!requiredAuthority.role().equals(ClubRole.NONE)) { diff --git a/dplanner/src/test/java/com/dp/dplanner/integration/RequiredAuthorityAspectTests.java b/dplanner/src/test/java/com/dp/dplanner/integration/RequiredAuthorityAspectTests.java index d18fb9d..36bd93e 100644 --- a/dplanner/src/test/java/com/dp/dplanner/integration/RequiredAuthorityAspectTests.java +++ b/dplanner/src/test/java/com/dp/dplanner/integration/RequiredAuthorityAspectTests.java @@ -9,6 +9,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; @@ -16,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -172,6 +176,52 @@ public void requestRoleByManagerUser() throws Exception .isInstanceOf(ServiceException.class); } + @ParameterizedTest + @MethodSource("provideAuthorityTestCases") + @DisplayName("권한에 따른 매니저 요청 테스트") + void testManagerRequestWithDifferentAuthorities(List authorities, boolean shouldThrowException) { + // given + ClubAuthority clubAuthority = createClubAuthority(club, "name", "description", authorities); + ClubMember manager = ClubMember.builder().club(club).member(member).build(); + manager.changeRole(ClubRole.MANAGER); + manager.updateClubAuthority(clubAuthority); + + entityManager.persist(clubAuthority); + entityManager.persist(manager); + + // when & then + if (shouldThrowException) { + assertThatThrownBy(() -> targetClass.targetMethod2(manager.getId())) + .isInstanceOf(ServiceException.class); + } else { + assertDoesNotThrow(() -> targetClass.targetMethod2(manager.getId())); + } + } + + private static Stream provideAuthorityTestCases() { + return Stream.of( + Arguments.of(List.of(ClubAuthorityType.MEMBER_ALL), false), + Arguments.of(List.of(ClubAuthorityType.SCHEDULE_ALL), false), + Arguments.of(List.of(ClubAuthorityType.MEMBER_ALL, ClubAuthorityType.SCHEDULE_ALL), false), + Arguments.of(List.of(ClubAuthorityType.RESOURCE_ALL), true) + ); + } + + @Test + @DisplayName("일반 회원이 요청하면 ServiceException") + public void requestByUserThenException2() throws Exception { + //given + ClubMember clubMember = ClubMember.builder().club(club).member(member).build(); + entityManager.persist(clubMember); + + assert clubMember.getRole().equals(ClubRole.USER); + + //when + //then + assertThatThrownBy(() -> targetClass.targetMethod2(clubMember.getId())) + .isInstanceOf(ServiceException.class); + } + private static ClubAuthority createClubAuthority(Club club, String name, String description, List clubAuthorityTypes) { return ClubAuthority.builder() @@ -193,6 +243,11 @@ class TestAopTargetClass { public void targetMethod(Long clubMemberId) throws IllegalStateException { } + + @RequiredAuthority(authority = {ClubAuthorityType.MEMBER_ALL,ClubAuthorityType.SCHEDULE_ALL}) + public void targetMethod2(Long clubMemberId) throws IllegalStateException { + + } }