Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor : ArgumentResolver -> Interceptor로 변경 #200

Merged
merged 12 commits into from
Nov 8, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.example.sinitto.callback.dto.CallbackResponse;
import com.example.sinitto.callback.dto.CallbackUsageHistoryResponse;
import com.example.sinitto.callback.service.CallbackService;
import com.example.sinitto.common.annotation.MemberId;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.data.domain.Page;
Expand All @@ -27,15 +26,15 @@ public CallbackController(CallbackService callbackService) {

@Operation(summary = "콜백 전화 리스트 보기(페이지)", description = "시니어가 요청한 콜백전화를 페이징으로 보여줍니다.")
@GetMapping
public ResponseEntity<Page<CallbackResponse>> getWaitingCallbackList(@MemberId Long memberId,
public ResponseEntity<Page<CallbackResponse>> getWaitingCallbackList(@RequestAttribute("memberId") Long memberId,
@PageableDefault(sort = "postTime", direction = Sort.Direction.DESC) Pageable pageable) {

return ResponseEntity.ok(callbackService.getWaitingCallbacks(memberId, pageable));
}

@Operation(summary = "진행 상태인 콜백을 완료 대기 상태로 전환(시니또가)", description = "시니또가 수락한 콜백 수행을 완료했을때 이 api 호출하면 완료 대기 상태로 변합니다.")
@PutMapping("/pendingComplete/{callbackId}")
public ResponseEntity<Void> pendingCompleteCallback(@MemberId Long memberId,
public ResponseEntity<Void> pendingCompleteCallback(@RequestAttribute("memberId") Long memberId,
@PathVariable Long callbackId) {

callbackService.changeCallbackStatusToPendingCompleteBySinitto(memberId, callbackId);
Expand All @@ -44,7 +43,7 @@ public ResponseEntity<Void> pendingCompleteCallback(@MemberId Long memberId,

@Operation(summary = "완료 대기 상태인 콜백을 완료 상태로 전환(보호자가)", description = "보호자가 완료 대기 상태인 콜백을 완료 확정 시킵니다.")
@PutMapping("/complete/{callbackId}")
public ResponseEntity<Void> completeCallback(@MemberId Long memberId,
public ResponseEntity<Void> completeCallback(@RequestAttribute("memberId") Long memberId,
@PathVariable Long callbackId) {

callbackService.changeCallbackStatusToCompleteByGuard(memberId, callbackId);
Expand All @@ -53,7 +52,7 @@ public ResponseEntity<Void> completeCallback(@MemberId Long memberId,

@Operation(summary = "콜백 서비스 수락 신청", description = "시니또가 콜백 서비스 수락을 신청합니다.")
@PutMapping("/accept/{callbackId}")
public ResponseEntity<Void> acceptCallback(@MemberId Long memberId,
public ResponseEntity<Void> acceptCallback(@RequestAttribute("memberId") Long memberId,
@PathVariable Long callbackId) {

callbackService.acceptCallbackBySinitto(memberId, callbackId);
Expand All @@ -62,7 +61,7 @@ public ResponseEntity<Void> acceptCallback(@MemberId Long memberId,

@Operation(summary = "진행중인 콜백 서비스 취소", description = "시니또가 진행중인 콜백 서비스를 취소합니다. 콜백은 다시 대기 상태로 돌아갑니다.")
@PutMapping("/cancel/{callbackId}")
public ResponseEntity<Void> cancelCallback(@MemberId Long memberId,
public ResponseEntity<Void> cancelCallback(@RequestAttribute("memberId") Long memberId,
@PathVariable Long callbackId) {

callbackService.cancelCallbackAssignmentBySinitto(memberId, callbackId);
Expand All @@ -77,22 +76,22 @@ public ResponseEntity<String> addCallCheck(@RequestParam("From") String fromNumb

@Operation(summary = "시니또에게 현재 할당된 콜백 조회", description = "현재 시니또 본인에게 할당된 콜백을 조회합니다.")
@GetMapping("/sinitto/accepted")
public ResponseEntity<CallbackResponse> getAcceptedCallback(@MemberId Long memberId) {
public ResponseEntity<CallbackResponse> getAcceptedCallback(@RequestAttribute("memberId") Long memberId) {

return ResponseEntity.ok(callbackService.getAcceptedCallback(memberId));
}

@Operation(summary = "보호자의 콜백 이용 내역 조회", description = "보호자에게 연관된 모든 콜백 내역을 조회합니다. 기본적으로 최신 내역 부터 조회됩니다.")
@GetMapping("/guard/requested")
public ResponseEntity<Page<CallbackUsageHistoryResponse>> getAcceptedCallback(@MemberId Long memberId,
public ResponseEntity<Page<CallbackUsageHistoryResponse>> getAcceptedCallback(@RequestAttribute("memberId") Long memberId,
@PageableDefault(sort = "postTime", direction = Sort.Direction.DESC) Pageable pageable) {

return ResponseEntity.ok(callbackService.getCallbackHistoryOfGuard(memberId, pageable));
}

@Operation(summary = "콜백 단건 조회 (시니또용)", description = "콜백 id 로 콜백을 단건 조회합니다.")
@GetMapping("/{callbackId}")
public ResponseEntity<CallbackForSinittoResponse> getCallback(@MemberId Long memberId,
public ResponseEntity<CallbackForSinittoResponse> getCallback(@RequestAttribute("memberId") Long memberId,
@PathVariable("callbackId") Long callbackId) {

return ResponseEntity.ok(callbackService.getCallbackForSinitto(memberId, callbackId));
Expand Down
14 changes: 0 additions & 14 deletions src/main/java/com/example/sinitto/common/annotation/MemberId.java

This file was deleted.

This file was deleted.

19 changes: 19 additions & 0 deletions src/main/java/com/example/sinitto/common/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.sinitto.common.config;

import com.example.sinitto.common.interceptor.JwtInterceptor;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
Expand All @@ -13,6 +14,7 @@
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.time.Duration;
Expand All @@ -23,6 +25,11 @@ public class WebConfig implements WebMvcConfigurer {
private static final int TIME_OUT_DURATION = 5;
private static final int MAX_OPEN_CONNECTIONS = 100;
private static final int CONNECTIONS_PER_IP_PORT_PAIR = 5;
private final JwtInterceptor jwtInterceptor;

public WebConfig(JwtInterceptor jwtInterceptor){
this.jwtInterceptor = jwtInterceptor;
}

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder, RestTemplateResponseErrorHandler errorHandler) {
Expand Down Expand Up @@ -62,4 +69,16 @@ public CorsFilter corsFilter() {
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor).addPathPatterns("/api/**")
.excludePathPatterns("/api/auth/**")
.excludePathPatterns("/api/reviews")
.excludePathPatterns("/api/members/sinitto")
.excludePathPatterns("/api/members/guard")
.excludePathPatterns("/api/reviews/all")
.excludePathPatterns("/api/callbacks/twilio")
.excludePathPatterns("/api/hellocalls/admin/reports");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

콜백, 포인트 관련해서는 이상없이 잘 제외해주신거 같습니다!

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.example.sinitto.common.interceptor;

import com.example.sinitto.common.exception.UnauthorizedException;
import com.example.sinitto.member.service.MemberTokenService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Component
public class JwtInterceptor implements HandlerInterceptor {
private final MemberTokenService memberTokenService;

public JwtInterceptor(MemberTokenService memberTokenService){
this.memberTokenService = memberTokenService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
throw new UnauthorizedException("토큰이 없거나, 헤더 형식에 맞지 않습니다.");
}

String token = authorizationHeader.substring(7);

request.setAttribute("memberId", memberTokenService.getMemberIdByToken(token));

return true;
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.example.sinitto.guard.controller;

import com.example.sinitto.common.annotation.MemberId;
import com.example.sinitto.guard.dto.GuardRequest;
import com.example.sinitto.guard.dto.GuardResponse;
import com.example.sinitto.guard.dto.SeniorRequest;
Expand All @@ -25,61 +24,61 @@ public GuardController(GuardService guardService) {

@Operation(summary = "연결된 모든 시니어 정보 조회", description = "보호자가 등록한 모든 시니어의 정보를 요청합니다.")
@GetMapping("/senior")
public ResponseEntity<List<SeniorResponse>> getAllSeniors(@MemberId Long memberId) {
public ResponseEntity<List<SeniorResponse>> getAllSeniors(@RequestAttribute("memberId") Long memberId) {
return ResponseEntity.ok(guardService.readSeniors(memberId));
}

@Operation(summary = "연결된 특정 시니어 정보 조회", description = "보호자가 등록한 특정 시니어의 정보를 요청합니다.")
@GetMapping("/senior/{seniorId}")
public ResponseEntity<SeniorResponse> getSenior(@MemberId Long memberId, @PathVariable Long seniorId) {
public ResponseEntity<SeniorResponse> getSenior(@RequestAttribute("memberId") Long memberId, @PathVariable Long seniorId) {
return ResponseEntity.ok(guardService.readOneSenior(memberId, seniorId));
}

@Operation(summary = "시니어 정보 수정", description = "시니어의 정보를 수정합니다.")
@PutMapping("/senior/{seniorId}")
public ResponseEntity<String> updateSenior(@MemberId Long memberId, @PathVariable Long seniorId, @RequestBody SeniorRequest seniorRequest) {
public ResponseEntity<String> updateSenior(@RequestAttribute("memberId") Long memberId, @PathVariable Long seniorId, @RequestBody SeniorRequest seniorRequest) {
guardService.updateSenior(memberId, seniorId, seniorRequest);
return ResponseEntity.ok("시니어 정보가 수정되었습니다.");
}

@Operation(summary = "시니어 추가", description = "보호자가 새로운 시니어를 등록합니다.")
@PostMapping("/senior")
public ResponseEntity<String> createSenior(@MemberId Long memberId, @RequestBody SeniorRequest seniorRequest) {
public ResponseEntity<String> createSenior(@RequestAttribute("memberId") Long memberId, @RequestBody SeniorRequest seniorRequest) {
guardService.createSenior(memberId, seniorRequest);
return ResponseEntity.ok("새로운 시니어가 등록되었습니다.");
}

@Operation(summary = "시니어 삭제", description = "보호자가 시니어를 등록 해제합니다.")
@DeleteMapping("/senior/{seniorId}")
public ResponseEntity<String> deleteSenior(@MemberId Long memberId, @PathVariable Long seniorId) {
public ResponseEntity<String> deleteSenior(@RequestAttribute("memberId") Long memberId, @PathVariable Long seniorId) {
guardService.deleteSenior(memberId, seniorId);
return ResponseEntity.ok("시니어가 삭제되었습니다.");
}

@Operation(summary = "보호자 본인 정보 조회", description = "보호자의 본인 정보를 조회합니다.")
@GetMapping
public ResponseEntity<GuardResponse> getGuardInfo(@MemberId Long memberId) {
public ResponseEntity<GuardResponse> getGuardInfo(@RequestAttribute("memberId") Long memberId) {
return ResponseEntity.ok(guardService.readGuard(memberId));
}

@Operation(summary = "보호자 본인 정보 수정", description = "보호자의 본인 정보를 수정합니다.")
@PutMapping
public ResponseEntity<String> updateGuardInfo(@MemberId Long memberId, @RequestBody GuardRequest guardRequest) {
public ResponseEntity<String> updateGuardInfo(@RequestAttribute("memberId") Long memberId, @RequestBody GuardRequest guardRequest) {
guardService.updateGuard(memberId, guardRequest);
return ResponseEntity.ok("보호자 정보가 수정되었습니다.");
}

// 현재는 jwt 안의 id를 삭제하게 구현했는데, 나중에 관리자 계정 만들면 특정 id 지정해서 삭제하게 수정해야할 듯합니다.
@Operation(summary = "보호자 삭제", description = "관리자용 API입니다.")
@DeleteMapping
public ResponseEntity<String> deleteGuard(@MemberId Long memberId) {
public ResponseEntity<String> deleteGuard(@RequestAttribute("memberId") Long memberId) {
guardService.deleteGuard(memberId);
return ResponseEntity.ok("보호자가 삭제되었습니다.");
}

@Operation(summary = "모든 보호자 조회", description = "관리자용 API입니다.")
@GetMapping("/all")
public ResponseEntity<List<GuardResponse>> getAllGuards(@MemberId Long memberId) {
public ResponseEntity<List<GuardResponse>> getAllGuards(@RequestAttribute("memberId") Long memberId) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 메서드에서는 memberId 가 안쓰이는데 필요한 이유가 있을까요? HelloCallController 에도 3개정도 안쓰이는 memberId가있는데 사용 안하면 제거하는게 깔끔하지 않나 하는 생각입니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

관리자용은 나중에 따로 보안을 적용해서 제거하는게 옳다고 생각하지만, HelloCallController에 있는 memberId의 경우 제거했을 때 회원이 아니어도 조회가 가능하다고 생각되어 일단 남겨두겠습니다!

return ResponseEntity.ok(guardService.readAllGuards());
}

Expand Down
Loading