diff --git a/gg-agenda-api/src/main/java/gg/agenda/api/user/agendaprofile/controller/AgendaProfileController.java b/gg-agenda-api/src/main/java/gg/agenda/api/user/agendaprofile/controller/AgendaProfileController.java index 0e5755efe..4f3abac15 100644 --- a/gg-agenda-api/src/main/java/gg/agenda/api/user/agendaprofile/controller/AgendaProfileController.java +++ b/gg-agenda-api/src/main/java/gg/agenda/api/user/agendaprofile/controller/AgendaProfileController.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import org.springframework.data.domain.Page; @@ -73,10 +74,10 @@ public ResponseEntity myAgendaProfileInfoDetails */ @GetMapping public ResponseEntity myAgendaProfileDetails( - @Login @Parameter(hidden = true) UserDto user) { + @Login @Parameter(hidden = true) UserDto user, HttpServletResponse response) { AgendaProfile profile = agendaProfileFindService.findAgendaProfileByIntraId(user.getIntraId()); int ticketCount = ticketService.findTicketList(profile).size(); - IntraProfile intraProfile = intraProfileUtils.getIntraProfile(); + IntraProfile intraProfile = intraProfileUtils.getIntraProfile(response); MyAgendaProfileDetailsResDto agendaProfileDetails = MyAgendaProfileDetailsResDto.toDto( profile, ticketCount, intraProfile); return ResponseEntity.ok(agendaProfileDetails); @@ -109,9 +110,10 @@ public ResponseEntity> getCurrentAttendAgend } @GetMapping("/{intraId}") - public ResponseEntity agendaProfileDetails(@PathVariable String intraId) { + public ResponseEntity agendaProfileDetails(@PathVariable String intraId, + HttpServletResponse response) { AgendaProfile profile = agendaProfileFindService.findAgendaProfileByIntraId(intraId); - IntraProfile intraProfile = intraProfileUtils.getIntraProfile(intraId); + IntraProfile intraProfile = intraProfileUtils.getIntraProfile(intraId, response); AgendaProfileDetailsResDto resDto = AgendaProfileDetailsResDto.toDto(profile, intraProfile); return ResponseEntity.ok(resDto); } diff --git a/gg-agenda-api/src/main/java/gg/agenda/api/user/agendaprofile/service/IntraProfileUtils.java b/gg-agenda-api/src/main/java/gg/agenda/api/user/agendaprofile/service/IntraProfileUtils.java index 6e7c39e95..610c16db5 100644 --- a/gg-agenda-api/src/main/java/gg/agenda/api/user/agendaprofile/service/IntraProfileUtils.java +++ b/gg-agenda-api/src/main/java/gg/agenda/api/user/agendaprofile/service/IntraProfileUtils.java @@ -5,6 +5,8 @@ import java.util.List; import java.util.Objects; +import javax.servlet.http.HttpServletResponse; + import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; @@ -14,6 +16,7 @@ import gg.agenda.api.user.agendaprofile.service.intraprofile.IntraProfile; import gg.agenda.api.user.agendaprofile.service.intraprofile.IntraProfileResponse; import gg.auth.FortyTwoAuthUtil; +import gg.utils.cookie.CookieUtil; import gg.utils.exception.custom.AuthenticationException; import gg.utils.external.ApiUtil; import lombok.RequiredArgsConstructor; @@ -31,7 +34,9 @@ public class IntraProfileUtils { private final ApiUtil apiUtil; - public IntraProfile getIntraProfile() { + private final CookieUtil cookieUtil; + + public IntraProfile getIntraProfile(HttpServletResponse response) { try { IntraProfileResponse intraProfileResponse = requestIntraProfile(INTRA_PROFILE_URL); intraProfileResponseValidation(intraProfileResponse); @@ -40,11 +45,12 @@ public IntraProfile getIntraProfile() { return new IntraProfile(intraImage.getLink(), intraAchievements); } catch (Exception e) { log.error("42 Intra Profile API 호출 실패", e); + cookieUtil.deleteCookie(response, "refresh_token"); throw new AuthenticationException(AUTH_NOT_FOUND); } } - public IntraProfile getIntraProfile(String intraId) { + public IntraProfile getIntraProfile(String intraId, HttpServletResponse response) { try { IntraProfileResponse intraProfileResponse = requestIntraProfile(INTRA_USERS_URL + intraId); intraProfileResponseValidation(intraProfileResponse); @@ -53,6 +59,7 @@ public IntraProfile getIntraProfile(String intraId) { return new IntraProfile(intraImage.getLink(), intraAchievements); } catch (Exception e) { log.error("42 Intra Profile API 호출 실패", e); + cookieUtil.deleteCookie(response, "refresh_token"); throw new AuthenticationException(AUTH_NOT_FOUND); } } @@ -71,7 +78,6 @@ private IntraProfileResponse requestIntraProfile(String requestUrl) { } } - private void intraProfileResponseValidation(IntraProfileResponse intraProfileResponse) { if (Objects.isNull(intraProfileResponse)) { throw new AuthenticationException(AUTH_NOT_FOUND); diff --git a/gg-agenda-api/src/test/java/gg/agenda/api/admin/agenda/controller/AgendaAdminControllerTest.java b/gg-agenda-api/src/test/java/gg/agenda/api/admin/agenda/controller/AgendaAdminControllerTest.java index a05f53654..d07adb842 100644 --- a/gg-agenda-api/src/test/java/gg/agenda/api/admin/agenda/controller/AgendaAdminControllerTest.java +++ b/gg-agenda-api/src/test/java/gg/agenda/api/admin/agenda/controller/AgendaAdminControllerTest.java @@ -41,11 +41,9 @@ import gg.data.agenda.type.AgendaStatus; import gg.data.agenda.type.Location; import gg.data.user.User; -import gg.utils.AgendaTestDataUtils; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; import gg.utils.converter.MultiValueMapConverter; -import gg.utils.dto.PageRequestDto; import gg.utils.dto.PageResponseDto; import gg.utils.file.handler.AwsImageHandler; import gg.utils.fixture.agenda.AgendaFixture; diff --git a/gg-agenda-api/src/test/java/gg/agenda/api/user/agendaprofile/AgendaProfileControllerTest.java b/gg-agenda-api/src/test/java/gg/agenda/api/user/agendaprofile/AgendaProfileControllerTest.java index c04c000fc..a01fc39ec 100644 --- a/gg-agenda-api/src/test/java/gg/agenda/api/user/agendaprofile/AgendaProfileControllerTest.java +++ b/gg-agenda-api/src/test/java/gg/agenda/api/user/agendaprofile/AgendaProfileControllerTest.java @@ -2,6 +2,7 @@ import static gg.data.agenda.type.Location.*; import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -10,6 +11,7 @@ import java.util.ArrayList; import java.util.List; +import javax.servlet.http.HttpServletResponse; import javax.transaction.Transactional; import org.junit.jupiter.api.BeforeEach; @@ -89,7 +91,8 @@ void test() throws Exception { //given URL url = new URL("http://localhost:8080"); IntraProfile intraProfile = new IntraProfile(url, List.of()); - Mockito.when(intraProfileUtils.getIntraProfile()).thenReturn(intraProfile); + Mockito.when(intraProfileUtils.getIntraProfile(any(HttpServletResponse.class))) + .thenReturn(intraProfile); AgendaProfile agendaProfile = agendaMockData.createAgendaProfile(user, SEOUL); agendaMockData.createTicket(agendaProfile); // when @@ -146,9 +149,10 @@ void getAgendaProfileSuccess() throws Exception { //given URL url = new URL("http://localhost:8080"); IntraProfile intraProfile = new IntraProfile(url, List.of()); - Mockito.when(intraProfileUtils.getIntraProfile(user.getIntraId())).thenReturn(intraProfile); AgendaProfile agendaProfile = agendaMockData.createAgendaProfile(user, SEOUL); agendaMockData.createTicket(agendaProfile); + Mockito.when(intraProfileUtils.getIntraProfile(any(String.class), any(HttpServletResponse.class))) + .thenReturn(intraProfile); // when String response = mockMvc.perform(get("/agenda/profile/" + user.getIntraId()) .header("Authorization", "Bearer " + accessToken)) @@ -171,7 +175,8 @@ void getAgendaProfileFailedWithInvalidIntraId() throws Exception { //given URL url = new URL("http://localhost:8080"); IntraProfile intraProfile = new IntraProfile(url, List.of()); - Mockito.when(intraProfileUtils.getIntraProfile()).thenReturn(intraProfile); + HttpServletResponse res = Mockito.mock(HttpServletResponse.class); + Mockito.when(intraProfileUtils.getIntraProfile(res)).thenReturn(intraProfile); AgendaProfile agendaProfile = agendaMockData.createAgendaProfile(user, SEOUL); agendaMockData.createTicket(agendaProfile); diff --git a/gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java b/gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java index e0f851f4d..b83615326 100644 --- a/gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java +++ b/gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java @@ -25,6 +25,7 @@ import gg.utils.exception.ErrorCode; import gg.utils.exception.custom.NotExistException; +import gg.utils.exception.user.TokenNotValidException; import gg.utils.external.ApiUtil; import lombok.RequiredArgsConstructor; @@ -37,6 +38,9 @@ public class FortyTwoAuthUtil { public String getAccessToken() { Authentication authentication = getAuthenticationFromContext(); OAuth2AuthorizedClient client = getClientFromAuthentication(authentication); + if (Objects.isNull(client)) { + throw new TokenNotValidException(); + } return client.getAccessToken().getTokenValue(); } diff --git a/gg-utils/src/main/java/gg/utils/exception/ErrorCode.java b/gg-utils/src/main/java/gg/utils/exception/ErrorCode.java index 0d3f14e08..b3c68558c 100644 --- a/gg-utils/src/main/java/gg/utils/exception/ErrorCode.java +++ b/gg-utils/src/main/java/gg/utils/exception/ErrorCode.java @@ -193,46 +193,45 @@ public enum ErrorCode { INVALID_CHECKLIST(400, "RE001", "잘못된 요청 데이터입니다."), // agenda - AUTH_NOT_FOUND(404, "AG", "42 정보가 만료되었습니다."), - - AGENDA_NOT_FOUND(404, "AG", "해당 일정이 존재하지 않습니다."), - AGENDA_CREATE_FAILED(500, "AG", "일정 생성에 실패했습니다."), - AGENDA_UPDATE_FAILED(500, "AG", "일정 수정에 실패했습니다."), - AGENDA_NOT_OPEN(400, "AG", "마감된 일정에는 팀을 생성할 수 없습니다."), - AGENDA_TEAM_ALREADY_CONFIRM(400, "AG", "이미 확정된 팀입니다."), - AGENDA_TEAM_ALREADY_CANCEL(400, "AG", "이미 취소된 팀입니다."), - NOT_ENOUGH_TEAM_MEMBER(400, "AG", "팀원이 부족합니다."), - AGENDA_ANNOUNCEMENT_NOT_FOUND(404, "AG", "공지사항이 존재하지 않습니다."), - AGENDA_TEAM_FULL(400, "AG", "팀이 꽉 찼습니다."), - AGENDA_NO_CAPACITY(403, "AG", "해당 일정에 참여할 수 있는 팀이 꽉 찼습니다."), - AGENDA_POSTER_SIZE_TOO_LARGE(400, "AG", "포스터 사이즈가 너무 큽니다."), - AGENDA_INVALID_SCHEDULE(400, "AG", "유효하지 않은 일정입니다."), - AGENDA_INVALID_PARAM(400, "AG", "유효하지 않은 파라미터입니다."), - UPDATE_LOCATION_NOT_VALID(400, "AG", "지역을 변경할 수 없습니다."), - AGENDA_CAPACITY_CONFLICT(409, "AG", "팀 제한을 변경할 수 없습니다."), - AGENDA_TEAM_CAPACITY_CONFLICT(409, "AG", "팀 인원 제한을 변경할 수 없습니다."), - HOST_FORBIDDEN(403, "AG", "개최자는 팀을 생성할 수 없습니다."), - TEAM_LEADER_FORBIDDEN(403, "AG", "팀장만 팀을 확정할 수 있습니다."), - CONFIRM_FORBIDDEN(403, "AG", "개최자만 일정을 종료할 수 있습니다."), - AGENDA_MODIFICATION_FORBIDDEN(403, "AG", "개최자만 일정을 수정할 수 있습니다."), - LOCATION_NOT_VALID(400, "AG", "유효하지 않은 지역입니다."), - AGENDA_TEAM_FORBIDDEN(403, "AG", "일정에 참여한 팀이 있습니다."), - NOT_TEAM_MATE(403, "AG", "팀원이 아닙니다."), - TEAM_NAME_EXIST(409, "AG", "이미 존재하는 팀 이름입니다."), - TICKET_NOT_EXIST(403, "AG", "보유한 티켓이 부족합니다."), - TICKET_NOT_FOUND(404, "AG", "해당 티켓이 존재하지 않습니다."), - AGENDA_TEAM_NOT_FOUND(404, "AG", "팀이 존재하지 않습니다."), - AGENDA_PROFILE_NOT_FOUND(404, "AG", "프로필이 존재하지 않습니다."), - ALREADY_TICKET_SETUP(409, "AG", "이미 티켓 신청이 되어있습니다."), - NOT_SETUP_TICKET(404, "AG", "티켓 신청이 되어있지 않습니다."), - POINT_HISTORY_NOT_FOUND(404, "AG", "기부 내역이 존재하지 않습니다."), - TICKET_FORBIDDEN(403, "AG", "티켓 신청은 1분의 대기시간이 있습니다."), - AGENDA_ALREADY_FINISHED(409, "AG", "이미 종료된 일정입니다."), - AGENDA_ALREADY_CONFIRMED(409, "AG", "이미 확정된 일정입니다."), - AGENDA_ALREADY_CANCELED(409, "AG", "이미 취소된 일정입니다."), - AGENDA_DOES_NOT_CONFIRM(409, "AG", "확정되지 않은 일정입니다."), - AGENDA_AWARD_EMPTY(400, "AG", "시상 정보가 없습니다."), - AGENDA_AWARD_PRIORITY_DUPLICATE(400, "AG", "시상 우선순위가 중복됩니다."); + AGENDA_TEAM_FULL(400, "AG101", "팀이 꽉 찼습니다."), + LOCATION_NOT_VALID(400, "AG102", "유효하지 않은 지역입니다."), + AGENDA_AWARD_EMPTY(400, "AG103", "시상 정보가 없습니다."), + AGENDA_INVALID_PARAM(400, "AG104", "유효하지 않은 파라미터입니다."), + AGENDA_NOT_OPEN(400, "AG105", "마감된 일정에는 팀을 생성할 수 없습니다."), + AGENDA_CREATE_FAILED(400, "AG106", "일정 생성에 실패했습니다."), + AGENDA_UPDATE_FAILED(400, "AG107", "일정 수정에 실패했습니다."), + AGENDA_INVALID_SCHEDULE(400, "AG108", "유효하지 않은 일정입니다."), + NOT_ENOUGH_TEAM_MEMBER(400, "AG109", "팀원이 부족합니다."), + UPDATE_LOCATION_NOT_VALID(400, "AG110", "지역을 변경할 수 없습니다."), + AGENDA_TEAM_ALREADY_CANCEL(400, "AG111", "이미 취소된 팀입니다."), + AGENDA_TEAM_ALREADY_CONFIRM(400, "AG112", "이미 확정된 팀입니다."), + AGENDA_POSTER_SIZE_TOO_LARGE(400, "AG113", "포스터 사이즈가 너무 큽니다."), + AGENDA_AWARD_PRIORITY_DUPLICATE(400, "AG114", "시상 우선순위가 중복됩니다."), + AGENDA_NO_CAPACITY(403, "AG201", "해당 일정에 참여할 수 있는 팀이 꽉 찼습니다."), + HOST_FORBIDDEN(403, "AG202", "개최자는 팀을 생성할 수 없습니다."), + TICKET_NOT_EXIST(403, "AG203", "보유한 티켓이 부족합니다."), + NOT_TEAM_MATE(403, "AG204", "팀원이 아닙니다."), + CONFIRM_FORBIDDEN(403, "AG205", "개최자만 일정을 종료할 수 있습니다."), + TICKET_FORBIDDEN(403, "AG206", "티켓 신청은 1분의 대기시간이 있습니다."), + TEAM_LEADER_FORBIDDEN(403, "AG207", "팀장만 팀을 확정할 수 있습니다."), + AGENDA_TEAM_FORBIDDEN(403, "AG208", "일정에 참여한 팀이 있습니다."), + AGENDA_MODIFICATION_FORBIDDEN(403, "AG209", "개최자만 일정을 수정할 수 있습니다."), + AUTH_NOT_FOUND(404, "AG301", "42 정보가 만료되었습니다."), + TICKET_NOT_FOUND(404, "AG302", "해당 티켓이 존재하지 않습니다."), + AGENDA_NOT_FOUND(404, "AG303", "해당 일정이 존재하지 않습니다."), + NOT_SETUP_TICKET(404, "AG304", "티켓 신청이 되어있지 않습니다."), + AGENDA_TEAM_NOT_FOUND(404, "AG305", "팀이 존재하지 않습니다."), + AGENDA_PROFILE_NOT_FOUND(404, "AG306", "프로필이 존재하지 않습니다."), + POINT_HISTORY_NOT_FOUND(404, "AG307", "기부 내역이 존재하지 않습니다."), + AGENDA_ANNOUNCEMENT_NOT_FOUND(404, "AG308", "공지사항이 존재하지 않습니다."), + TEAM_NAME_EXIST(409, "AG401", "이미 존재하는 팀 이름입니다."), + ALREADY_TICKET_SETUP(409, "AG402", "이미 티켓 신청이 되어있습니다."), + AGENDA_DOES_NOT_CONFIRM(409, "AG403", "확정되지 않은 일정입니다."), + AGENDA_ALREADY_FINISHED(409, "AG404", "이미 종료된 일정입니다."), + AGENDA_ALREADY_CANCELED(409, "AG405", "이미 취소된 일정입니다."), + AGENDA_ALREADY_CONFIRMED(409, "AG406", "이미 확정된 일정입니다."), + AGENDA_CAPACITY_CONFLICT(409, "AG407", "팀 제한을 변경할 수 없습니다."), + AGENDA_TEAM_CAPACITY_CONFLICT(409, "AG408", "팀 인원 제한을 변경할 수 없습니다."); private final int status; private final String errCode;