diff --git a/src/main/java/cc/backend/amateurShow/service/amateurShowService/AmateurServiceImpl.java b/src/main/java/cc/backend/amateurShow/service/amateurShowService/AmateurServiceImpl.java index f8e42f3..f41e111 100644 --- a/src/main/java/cc/backend/amateurShow/service/amateurShowService/AmateurServiceImpl.java +++ b/src/main/java/cc/backend/amateurShow/service/amateurShowService/AmateurServiceImpl.java @@ -65,7 +65,7 @@ public AmateurEnrollResponseDTO.AmateurEnrollResult enrollShow(Long memberId, Member member = memberRepository.findById(memberId) .orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND)); - if (member.getRole() != Role.PERFORMER) { + if (member.getRole() == Role.AUDIENCE) { throw new GeneralException(ErrorStatus.MEMBER_NOT_PERFORMER); } @@ -186,7 +186,7 @@ public AmateurEnrollResponseDTO.AmateurEnrollResult updateShow(Long memberId, Lo Member member = memberRepository.findById(memberId) .orElseThrow(()->new GeneralException(ErrorStatus.MEMBER_NOT_FOUND)); - if (member.getRole() != Role.PERFORMER) { + if (member.getRole() == Role.AUDIENCE) { throw new GeneralException(ErrorStatus.MEMBER_NOT_PERFORMER); } @@ -399,7 +399,7 @@ public void deleteShow(Long memberId, Long amateurShowId) { Member member = memberRepository.findById(memberId) .orElseThrow(()-> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND)); - if (member.getRole() != Role.PERFORMER) { + if (member.getRole() == Role.AUDIENCE) { throw new GeneralException(ErrorStatus.MEMBER_NOT_PERFORMER); } @@ -579,7 +579,7 @@ public Slice getMyAmateurShow(Long Member member = memberRepository.findById(memberId) .orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND)); - if (member.getRole() != Role.PERFORMER) { + if (member.getRole() == Role.AUDIENCE) { throw new GeneralException(ErrorStatus.MEMBER_NOT_PERFORMER); } diff --git a/src/main/java/cc/backend/config/jwt/MethodSecurityConfig.java b/src/main/java/cc/backend/config/jwt/MethodSecurityConfig.java new file mode 100644 index 0000000..965f4b0 --- /dev/null +++ b/src/main/java/cc/backend/config/jwt/MethodSecurityConfig.java @@ -0,0 +1,19 @@ +package cc.backend.config.jwt; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.access.hierarchicalroles.RoleHierarchy; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; + +@EnableMethodSecurity +@Configuration +public class MethodSecurityConfig { + @Bean + public MethodSecurityExpressionHandler methodSecurityExpressionHandler(RoleHierarchy roleHierarchy) { + DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler(); + handler.setRoleHierarchy(roleHierarchy); + return handler; + } +} diff --git a/src/main/java/cc/backend/config/jwt/SecurityConfig.java b/src/main/java/cc/backend/config/jwt/SecurityConfig.java index 7626c1b..523e994 100644 --- a/src/main/java/cc/backend/config/jwt/SecurityConfig.java +++ b/src/main/java/cc/backend/config/jwt/SecurityConfig.java @@ -4,6 +4,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; +import org.springframework.security.access.hierarchicalroles.RoleHierarchy; +import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl; 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; @@ -95,5 +97,13 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti public BCryptPasswordEncoder encoder() { return new BCryptPasswordEncoder(); } + + @Bean + public RoleHierarchy roleHierarchy() { + return RoleHierarchyImpl.fromHierarchy(""" + ROLE_ADMIN > ROLE_PERFORMER + ROLE_PERFORMER > ROLE_AUDIENCE + """); + } } diff --git a/src/main/java/cc/backend/performer/PerformerController.java b/src/main/java/cc/backend/performer/PerformerController.java index 30f622b..2609a13 100644 --- a/src/main/java/cc/backend/performer/PerformerController.java +++ b/src/main/java/cc/backend/performer/PerformerController.java @@ -72,12 +72,14 @@ public ApiResponse> description = "등록자 계정으로 특정 공연의 예매 내역을 조회합니다. roundId가 있으면 해당 회차 상세, 없으면 첫 회차 상세를 반환합니다." ) public ApiResponse getShowReservation( + @Parameter(description = "작성자 회원 ID", required = true) + @AuthenticationPrincipal(expression = "member") Member member, @PathVariable Long amateurShowId, @Parameter(description = "선택 회차 ID", example = "10") @RequestParam(required = false) Long roundId ) { return ApiResponse.onSuccess( - performerService.getShowReservationList(amateurShowId, roundId) + performerService.getShowReservationList(member.getId(), amateurShowId, roundId) ); } diff --git a/src/main/java/cc/backend/performer/PerformerService.java b/src/main/java/cc/backend/performer/PerformerService.java index 35992c5..4e1a799 100644 --- a/src/main/java/cc/backend/performer/PerformerService.java +++ b/src/main/java/cc/backend/performer/PerformerService.java @@ -9,6 +9,7 @@ import cc.backend.amateurShow.repository.AmateurShowRepository; import cc.backend.apiPayLoad.code.status.ErrorStatus; import cc.backend.apiPayLoad.exception.GeneralException; +import cc.backend.member.entity.Member; import cc.backend.performer.dto.PerformerMyShowResponseDTO; import cc.backend.performer.dto.ShowReservationResponseDTO; import cc.backend.ticket.entity.RealTicket; @@ -31,35 +32,18 @@ public class PerformerService { private final AmateurShowRepository amateurShowRepository; private final AmateurRoundsRepository amateurRoundsRepository; private final RealTicketRepository realTicketRepository; -/* public Slice getMyShows(Long memberId, String tab, Pageable pageable) { - - Slice slice; - - if ("on_sale".equalsIgnoreCase(tab)) { // 예매 진행 - slice = amateurShowRepository.findByMember_IdAndStatusInOrderByIdDesc( - memberId, - EnumSet.of(AmateurShowStatus.APPROVED_ONGOING, AmateurShowStatus.APPROVED_YET), - pageable - ); - } else if ("ended".equalsIgnoreCase(tab)) { // 공연 종료 - slice = amateurShowRepository.findByMember_IdAndStatusInOrderByIdDesc( - memberId, - EnumSet.of(AmateurShowStatus.APPROVED_ENDED), - pageable - ); - } else { // 전체 - slice = amateurShowRepository.findByMember_IdOrderByIdDesc(memberId, pageable); - } - - return slice.map(PerformerMyShowResponseDTO::from); - }*/ - public ShowReservationResponseDTO getShowReservationList(Long amateurShowId, Long roundId) { + public ShowReservationResponseDTO getShowReservationList(Long memberId, Long amateurShowId, Long roundId) { // 1) 공연 로드 AmateurShow show = amateurShowRepository.findById(amateurShowId) .orElseThrow(() -> new GeneralException(ErrorStatus.AMATEURSHOW_NOT_FOUND)); + // 1-1) 로그인한 계정이 공연의 주인인지 확인 + if (!show.getMember().getId().equals(memberId)) { + throw new GeneralException(ErrorStatus.MEMBER_NOT_AUTHORIZED); + } + // 2) 공연의 모든 회차(번호 오름차순) List rounds = amateurRoundsRepository.findByAmateurShow_IdOrderByRoundNumberAsc(amateurShowId); diff --git a/src/main/java/cc/backend/photoAlbum/service/PhotoAlbumServiceImpl.java b/src/main/java/cc/backend/photoAlbum/service/PhotoAlbumServiceImpl.java index 7435dc6..3373ce9 100644 --- a/src/main/java/cc/backend/photoAlbum/service/PhotoAlbumServiceImpl.java +++ b/src/main/java/cc/backend/photoAlbum/service/PhotoAlbumServiceImpl.java @@ -371,8 +371,8 @@ public List getMyShows(Long membe Member member = memberRepository.findById(memberId) .orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND)); - if(member.getRole() != Role.PERFORMER){ - throw new GeneralException(ErrorStatus.MEMBER_NOT_AUTHORIZED); + if (member.getRole() == Role.AUDIENCE) { + throw new GeneralException(ErrorStatus.MEMBER_NOT_PERFORMER); } List amateurShows = amateurShowRepository.findAllByMemberId(memberId);