From a09cf30c2b6077352b617d462a5fee0aaa5fb368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Wed, 26 Mar 2025 21:46:11 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20DB=20=ED=95=84=EB=93=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=84=A4=EC=A0=95=20=EB=B0=8F=20=EC=8B=9C=EA=B0=84?= =?UTF-8?q?=20=EC=96=91=EC=8B=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/aolda/itda/dto/forwarding/ForwardingDTO.java | 5 +++++ src/main/java/com/aolda/itda/dto/log/LogDTO.java | 5 +++++ src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java | 3 +++ src/main/java/com/aolda/itda/entity/BaseTimeEntity.java | 4 ++-- .../java/com/aolda/itda/entity/certificate/Certificate.java | 4 ++++ .../java/com/aolda/itda/entity/forwarding/Forwarding.java | 6 ++++++ src/main/java/com/aolda/itda/entity/log/Log.java | 4 ++++ src/main/java/com/aolda/itda/entity/routing/Routing.java | 5 +++++ 8 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/aolda/itda/dto/forwarding/ForwardingDTO.java b/src/main/java/com/aolda/itda/dto/forwarding/ForwardingDTO.java index 3302d0a..be003b6 100644 --- a/src/main/java/com/aolda/itda/dto/forwarding/ForwardingDTO.java +++ b/src/main/java/com/aolda/itda/dto/forwarding/ForwardingDTO.java @@ -1,5 +1,6 @@ package com.aolda.itda.dto.forwarding; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; @@ -40,6 +41,10 @@ public class ForwardingDTO { @NotBlank(message = "name 값이 존재하지 않습니다") private String name; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") private LocalDateTime createdAt; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") private LocalDateTime updatedAt; } diff --git a/src/main/java/com/aolda/itda/dto/log/LogDTO.java b/src/main/java/com/aolda/itda/dto/log/LogDTO.java index 5895455..9946028 100644 --- a/src/main/java/com/aolda/itda/dto/log/LogDTO.java +++ b/src/main/java/com/aolda/itda/dto/log/LogDTO.java @@ -3,6 +3,7 @@ package com.aolda.itda.dto.log; import com.aolda.itda.dto.auth.IdAndNameDTO; import com.aolda.itda.entity.log.Action; import com.aolda.itda.entity.log.ObjectType; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import com.querydsl.core.annotations.QueryProjection; import lombok.AllArgsConstructor; @@ -22,7 +23,11 @@ public class LogDTO { private Action action; private ObjectType type; private Long objectId; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") private String description; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") private LocalDateTime createdAt; @QueryProjection diff --git a/src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java b/src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java index 6bc48d8..985056e 100644 --- a/src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java +++ b/src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java @@ -1,5 +1,6 @@ package com.aolda.itda.dto.routing; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @@ -28,8 +29,10 @@ public class RoutingDTO { @NotNull private Long certificateId; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") private LocalDateTime createdAt; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") private LocalDateTime updatedAt; @NotNull diff --git a/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java b/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java index 6cfa1fd..b62af84 100644 --- a/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java +++ b/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java @@ -17,12 +17,12 @@ import java.time.LocalDateTime; public abstract class BaseTimeEntity { @CreatedDate - @Column(updatable = false) + @Column(updatable = false, columnDefinition = "DATETIME") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") private LocalDateTime createdAt; @LastModifiedDate - @Column(name = "updated_at") + @Column(name = "updated_at", columnDefinition = "DATETIME") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") private LocalDateTime updatedAt; diff --git a/src/main/java/com/aolda/itda/entity/certificate/Certificate.java b/src/main/java/com/aolda/itda/entity/certificate/Certificate.java index a23cf85..85b1f29 100644 --- a/src/main/java/com/aolda/itda/entity/certificate/Certificate.java +++ b/src/main/java/com/aolda/itda/entity/certificate/Certificate.java @@ -27,10 +27,13 @@ public class Certificate extends BaseTimeEntity { @JoinColumn(nullable = false, name = "user_id") private User user; + @Column(length = 64) private String projectId; + @Column(length = 64) private String domain; + @Column(length = 64) private String email; private LocalDateTime expiredAt; @@ -40,6 +43,7 @@ public class Certificate extends BaseTimeEntity { private Boolean isDeleted; + @Column(length = 256) private String description; public String formatDomain() { diff --git a/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java b/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java index 0e5e505..0ba96d6 100644 --- a/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java +++ b/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java @@ -20,18 +20,24 @@ public class Forwarding extends BaseTimeEntity { @Column(nullable = false) private Long forwardingId; + @Column(length = 64) private String projectId; + @Column(length = 32) private String serverIp; + @Column(length = 8) private String serverPort; + @Column(length = 32) private String instanceIp; + @Column(length = 8) private String instancePort; private Boolean isDeleted; + @Column(length = 256) private String name; public Forwarding(Forwarding forwarding) { diff --git a/src/main/java/com/aolda/itda/entity/log/Log.java b/src/main/java/com/aolda/itda/entity/log/Log.java index 9832ab2..6bf6074 100644 --- a/src/main/java/com/aolda/itda/entity/log/Log.java +++ b/src/main/java/com/aolda/itda/entity/log/Log.java @@ -27,16 +27,20 @@ public class Log extends BaseTimeEntity { @JoinColumn(name = "user_id", nullable = false) private User user; + @Column(length = 64) private String projectId; @Enumerated(EnumType.STRING) private ObjectType objectType; + @Column(length = 64) private Long objectId; @Enumerated(EnumType.STRING) private Action action; + @Lob + @Column(length = 1024) private String description; public LogDTO toLogDTO() { diff --git a/src/main/java/com/aolda/itda/entity/routing/Routing.java b/src/main/java/com/aolda/itda/entity/routing/Routing.java index de13d82..94ecb55 100644 --- a/src/main/java/com/aolda/itda/entity/routing/Routing.java +++ b/src/main/java/com/aolda/itda/entity/routing/Routing.java @@ -28,18 +28,23 @@ public class Routing extends BaseTimeEntity { @JoinColumn(name = "certificate_id") private Certificate certificate; + @Column(length = 64) private String projectId; + @Column(length = 64) private String domain; + @Column(length = 32) private String instanceIp; + @Column(length = 8) private String instancePort; private Boolean isDeleted; private Boolean caching; + @Column(length = 256) private String name; public RoutingDTO toRoutingDTO() { -- GitLab From 62f400dffe4db2c570926c9a831617ed14a560e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Wed, 26 Mar 2025 22:39:01 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20?= =?UTF-8?q?=EC=96=B4=EB=93=9C=EB=AF=BC=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=91=EA=B7=BC=20=EA=B6=8C=ED=95=9C=20=EB=B6=80?= =?UTF-8?q?=EC=97=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aolda/itda/config/AuthInterceptor.java | 15 ++++++++--- .../com/aolda/itda/config/LoggingFilter.java | 3 --- .../com/aolda/itda/service/AuthService.java | 25 +++++++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/aolda/itda/config/AuthInterceptor.java b/src/main/java/com/aolda/itda/config/AuthInterceptor.java index 3a95f8a..b0767e3 100644 --- a/src/main/java/com/aolda/itda/config/AuthInterceptor.java +++ b/src/main/java/com/aolda/itda/config/AuthInterceptor.java @@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -56,9 +57,17 @@ public class AuthInterceptor implements HandlerInterceptor { } /* 프로젝트 리스트 조회 */ - List<String> projects = authService.getProjectsWithUser(Map.of("id", userId, "token", token)) - .stream().map(IdAndNameDTO::getId) - .toList(); + List<String> projects; + if (authService.isAdmin(Map.of("id", userId, "token", token))) { + projects = authService.getAllProjects(token); + } + + else { + projects = authService.getProjectsWithUser(Map.of("id", userId, "token", token)) + .stream().map(IdAndNameDTO::getId) + .toList(); + } + request.setAttribute("projects", projects); request.setAttribute("user", Map.of("id", userId, "token", token)); return true; diff --git a/src/main/java/com/aolda/itda/config/LoggingFilter.java b/src/main/java/com/aolda/itda/config/LoggingFilter.java index 0dd73b1..49264ec 100644 --- a/src/main/java/com/aolda/itda/config/LoggingFilter.java +++ b/src/main/java/com/aolda/itda/config/LoggingFilter.java @@ -23,16 +23,13 @@ public class LoggingFilter extends OncePerRequestFilter { // Request Body를 읽을 수 있도록 래핑 ContentCachingRequestWrapper cachingRequest = new ContentCachingRequestWrapper(request); - System.out.println("필터 적용"); filterChain.doFilter(cachingRequest, response); // 로그 기록 logRequest(cachingRequest); - System.out.println("왜 안돼ㅐ"); } private void logRequest(ContentCachingRequestWrapper request) { - System.out.println("되는거 맞아?"); String ip = request.getRemoteAddr(); String method = request.getMethod(); String uri = request.getRequestURI(); diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java index 6a25ebc..8bc6836 100644 --- a/src/main/java/com/aolda/itda/service/AuthService.java +++ b/src/main/java/com/aolda/itda/service/AuthService.java @@ -297,6 +297,31 @@ public class AuthService { } + public List<String> getAllProjects(String token) throws JsonProcessingException { + String url = keystone + "/projects"; + HttpHeaders headers = new HttpHeaders(); + headers.set("X-Auth-Token", token); + HttpEntity<String> requestEntity = new HttpEntity<>(headers); + ResponseEntity<String> res; + try { + res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); + } catch (HttpClientErrorException.NotFound e) { + throw new CustomException(ErrorCode.INVALID_TOKEN); + } + + JsonNode node = objectMapper.readTree(res.getBody()); + ArrayNode arrayNode = (ArrayNode) node.get("projects"); + + List<String> lists = new ArrayList<>(); + + for (JsonNode assignment : arrayNode) { + lists.add(assignment.path("id").asText()); + } + + return lists; + + } + public void validateProjectAuth(List<String> projects, String projectId) { if (projects != null && !projects.contains(projectId)) { throw new CustomException(ErrorCode.UNAUTHORIZED_USER); -- GitLab From 1b407531c1208ef0f09867426b7cc75eafd20486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Wed, 26 Mar 2025 23:39:18 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=B0=8F=20=EC=A0=91=EA=B7=BC=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aolda/itda/config/AuthInterceptor.java | 3 +- .../itda/controller/main/MainController.java | 33 ++++++++++ .../com/aolda/itda/dto/main/MainInfoDTO.java | 20 ++++++ .../com/aolda/itda/service/AuthService.java | 8 ++- .../aolda/itda/service/main/MainService.java | 61 +++++++++++++++++++ 5 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/aolda/itda/controller/main/MainController.java create mode 100644 src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java create mode 100644 src/main/java/com/aolda/itda/service/main/MainService.java diff --git a/src/main/java/com/aolda/itda/config/AuthInterceptor.java b/src/main/java/com/aolda/itda/config/AuthInterceptor.java index b0767e3..7c9f87f 100644 --- a/src/main/java/com/aolda/itda/config/AuthInterceptor.java +++ b/src/main/java/com/aolda/itda/config/AuthInterceptor.java @@ -59,7 +59,8 @@ public class AuthInterceptor implements HandlerInterceptor { /* 프로젝트 리스트 조회 */ List<String> projects; if (authService.isAdmin(Map.of("id", userId, "token", token))) { - projects = authService.getAllProjects(token); + projects = authService.getAllProjects(token).stream().map(IdAndNameDTO::getId) + .toList(); } else { diff --git a/src/main/java/com/aolda/itda/controller/main/MainController.java b/src/main/java/com/aolda/itda/controller/main/MainController.java new file mode 100644 index 0000000..7b22923 --- /dev/null +++ b/src/main/java/com/aolda/itda/controller/main/MainController.java @@ -0,0 +1,33 @@ +package com.aolda.itda.controller.main; + +import com.aolda.itda.service.main.MainService; +import com.fasterxml.jackson.core.JsonProcessingException; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +public class MainController { + + private final MainService mainService; + + @GetMapping("/projects") + public ResponseEntity<Object> projects(HttpServletRequest request) throws JsonProcessingException { + return ResponseEntity.ok(mainService.getAllProjects((Map<String, String>) request.getSession().getAttribute("user"))); + } + + @GetMapping("/main") + public ResponseEntity<Object> mainInfo(@RequestParam String projectId, HttpServletRequest request) { + return ResponseEntity.ok(mainService.getMainInfo(projectId, (List<String>) request.getAttribute("projects"))); + } + +} diff --git a/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java b/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java new file mode 100644 index 0000000..6de5fdf --- /dev/null +++ b/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java @@ -0,0 +1,20 @@ +package com.aolda.itda.dto.main; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MainInfoDTO { + + private Long routing; + private Long forwarding; + private Long certificate; + +} diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java index 8bc6836..a222e28 100644 --- a/src/main/java/com/aolda/itda/service/AuthService.java +++ b/src/main/java/com/aolda/itda/service/AuthService.java @@ -297,7 +297,7 @@ public class AuthService { } - public List<String> getAllProjects(String token) throws JsonProcessingException { + public List<IdAndNameDTO> getAllProjects(String token) throws JsonProcessingException { String url = keystone + "/projects"; HttpHeaders headers = new HttpHeaders(); headers.set("X-Auth-Token", token); @@ -312,10 +312,12 @@ public class AuthService { JsonNode node = objectMapper.readTree(res.getBody()); ArrayNode arrayNode = (ArrayNode) node.get("projects"); - List<String> lists = new ArrayList<>(); + List<IdAndNameDTO> lists = new ArrayList<>(); for (JsonNode assignment : arrayNode) { - lists.add(assignment.path("id").asText()); + String projectId = assignment.path("id").asText(); + String projectName = assignment.path("name").asText(); + lists.add(new IdAndNameDTO(projectId, projectName)); } return lists; diff --git a/src/main/java/com/aolda/itda/service/main/MainService.java b/src/main/java/com/aolda/itda/service/main/MainService.java new file mode 100644 index 0000000..2c36ac8 --- /dev/null +++ b/src/main/java/com/aolda/itda/service/main/MainService.java @@ -0,0 +1,61 @@ +package com.aolda.itda.service.main; + +import com.aolda.itda.dto.PageResp; +import com.aolda.itda.dto.auth.IdAndNameDTO; +import com.aolda.itda.dto.main.MainInfoDTO; +import com.aolda.itda.repository.certificate.CertificateRepository; +import com.aolda.itda.repository.forwarding.ForwardingRepository; +import com.aolda.itda.repository.routing.RoutingRepository; +import com.aolda.itda.service.AuthService; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +@Service +@Transactional +@RequiredArgsConstructor +public class MainService { + + private final AuthService authService; + private final RoutingRepository routingRepository; + private final ForwardingRepository forwardingRepository; + private final CertificateRepository certificateRepository; + + /* 메인 페이지에 필요한 정보 반환 */ + public MainInfoDTO getMainInfo(String projectId, List<String> projects) { + + /* 프로젝트 권한 검증 */ + authService.validateProjectAuth(projects, projectId); + + /* 카운팅 */ + Long routing = (long) routingRepository.findByProjectIdAndIsDeleted(projectId, false).size(); + Long forwarding = (long) forwardingRepository.findByProjectIdAndIsDeleted(projectId, false).size(); + Long certificate = 0L; + + return MainInfoDTO.builder() + .routing(routing) + .forwarding(forwarding) + .certificate(certificate) + .build(); + } + + /* 접근 가능한 프로젝트 조회 */ + public PageResp<IdAndNameDTO> getAllProjects(Map<String, String> user) throws JsonProcessingException { + + List<IdAndNameDTO> projects; + if (authService.isAdmin(user)) { + projects = authService.getAllProjects(user.get("token")); + } + + else { + projects = authService.getProjectsWithUser(user); + } + + return PageResp.<IdAndNameDTO>builder() + .contents(projects).build(); + } +} -- GitLab From 017ea5c5ad239d906bdb7f85f9290a01dd99e8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Sat, 29 Mar 2025 11:08:48 +0900 Subject: [PATCH 4/9] =?UTF-8?q?fix:=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8?= =?UTF-8?q?=20=EC=97=AD=ED=95=A0=EA=B3=BC=20=EA=B6=8C=ED=95=9C=EC=9D=B4=20?= =?UTF-8?q?=EC=9D=BC=EC=B9=98=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8D=98=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/aolda/itda/config/AuthInterceptor.java | 6 +++--- .../java/com/aolda/itda/service/AuthService.java | 13 +++++-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/aolda/itda/config/AuthInterceptor.java b/src/main/java/com/aolda/itda/config/AuthInterceptor.java index 7c9f87f..fd78fb6 100644 --- a/src/main/java/com/aolda/itda/config/AuthInterceptor.java +++ b/src/main/java/com/aolda/itda/config/AuthInterceptor.java @@ -43,10 +43,10 @@ public class AuthInterceptor implements HandlerInterceptor { if (projectId != null) { try { - String role = authService.getBestRoleWithinProject(token, projectId).get("role"); - if (!role.equals("admin")) { - log.error("Unauthorized Token for URI {}: {}", request.getRequestURI(), request.getRemoteAddr()); + authService.getBestRoleWithinProject(token, projectId).get("role"); + if (!request.getMethod().equals("GET") && !authService.getBestRoleWithinProject(token, projectId).get("role").equals("admin")) { throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI()); + } } catch (Exception e) { throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI()); diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java index a222e28..4c1740e 100644 --- a/src/main/java/com/aolda/itda/service/AuthService.java +++ b/src/main/java/com/aolda/itda/service/AuthService.java @@ -96,7 +96,6 @@ public class AuthService { try { res = restTemplate.postForEntity(url, requestEntity, Map.class); } catch (Exception e) { - e.printStackTrace(); throw new CustomException(ErrorCode.INVALID_USER_INFO); } Map<String, Object> resToken = (Map<String, Object>) res.getBody().get("token"); @@ -140,7 +139,7 @@ public class AuthService { try { requestEntity = new HttpEntity<>(requestBody, headers); res = restTemplate.postForEntity(url, requestEntity, Map.class); - } catch (RuntimeException e) { + } catch (Exception e) { return null; } @@ -185,8 +184,7 @@ public class AuthService { } catch (HttpClientErrorException.Forbidden e) { return unscopedToken; } - catch (RuntimeException e) { - e.printStackTrace(); + catch (Exception e) { throw new CustomException(ErrorCode.INVALID_TOKEN); } @@ -290,7 +288,7 @@ public class AuthService { ResponseEntity<String> res; try { res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); - } catch (HttpClientErrorException.NotFound e) { + } catch (Exception e) { throw new CustomException(ErrorCode.INVALID_TOKEN); } return objectMapper.readTree(res.getBody()).path("token").path("user").path("id").asText(); @@ -305,7 +303,7 @@ public class AuthService { ResponseEntity<String> res; try { res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); - } catch (HttpClientErrorException.NotFound e) { + } catch (Exception e) { throw new CustomException(ErrorCode.INVALID_TOKEN); } @@ -338,8 +336,7 @@ public class AuthService { ResponseEntity<String> res; try { res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); - } catch (RuntimeException e) { - e.printStackTrace(); + } catch (Exception e) { return false; } JsonNode node = objectMapper.readTree(res.getBody()).path("role_assignments"); -- GitLab From 1b0c96231a33afa111a7016e5289cfbea0930104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Sat, 29 Mar 2025 11:09:28 +0900 Subject: [PATCH 5/9] =?UTF-8?q?fix:=20=EB=9D=BC=EC=9A=B0=ED=8C=85=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20=EB=A1=9C=EA=B7=B8=EC=97=90=20=EA=B0=9C?= =?UTF-8?q?=ED=96=89=EC=9D=B4=20=ED=95=9C=20=EB=B2=88=20=EB=8D=94=20?= =?UTF-8?q?=EB=93=A4=EC=96=B4=EA=B0=80=EB=8D=98=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java b/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java index a3a67d2..97f7de4 100644 --- a/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java +++ b/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java @@ -61,7 +61,7 @@ public class RoutingLogAspect { + "ip: " + routing.getInstanceIp() + "\n" + "port: " + routing.getInstancePort() + "\n" + (routing.getCertificate() != null ? ("certificateId: " + routing.getCertificate().getCertificateId() + "\n") : "") - + "caching: " + routing.getCaching() + "\n"; + + "caching: " + routing.getCaching(); /* 로그 엔티티 저장 */ logRepository.save(Log.builder() @@ -97,7 +97,7 @@ public class RoutingLogAspect { + "ip: " + routing.getInstanceIp() + "\n" + "port: " + routing.getInstancePort() + "\n" + (routing.getCertificate() != null ? ("certificateId: " + routing.getCertificate().getCertificateId() + "\n") : "") - + "caching: " + routing.getCaching() + "\n"; + + "caching: " + routing.getCaching(); /* 로그 엔티티 저장 */ logRepository.save(Log.builder() -- GitLab From aa911ace917181294680c8cf68ce89ef7b26fb3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Sat, 29 Mar 2025 11:56:18 +0900 Subject: [PATCH 6/9] =?UTF-8?q?fix:=20enum=20type=20=EC=86=8C=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=20=EC=A7=81=EB=A0=AC=ED=99=94=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/aolda/itda/config/LoggingFilter.java | 96 +++++----- .../itda/controller/main/MainController.java | 66 +++---- .../com/aolda/itda/dto/main/MainInfoDTO.java | 40 ++-- .../itda/entity/certificate/Challenge.java | 12 +- .../com/aolda/itda/entity/log/Action.java | 12 +- .../com/aolda/itda/entity/log/ObjectType.java | 12 +- .../aolda/itda/service/main/MainService.java | 122 ++++++------ src/main/resources/logback-spring.xml | 178 +++++++++--------- 8 files changed, 284 insertions(+), 254 deletions(-) diff --git a/src/main/java/com/aolda/itda/config/LoggingFilter.java b/src/main/java/com/aolda/itda/config/LoggingFilter.java index 49264ec..f2330bf 100644 --- a/src/main/java/com/aolda/itda/config/LoggingFilter.java +++ b/src/main/java/com/aolda/itda/config/LoggingFilter.java @@ -1,48 +1,48 @@ -package com.aolda.itda.config; - -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; -import org.springframework.web.util.ContentCachingRequestWrapper; - -import java.io.IOException; - -@Component -public class LoggingFilter extends OncePerRequestFilter { - - private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class); - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - - // Request Body를 읽을 수 있도록 래핑 - ContentCachingRequestWrapper cachingRequest = new ContentCachingRequestWrapper(request); - filterChain.doFilter(cachingRequest, response); - - // 로그 기록 - logRequest(cachingRequest); - } - - private void logRequest(ContentCachingRequestWrapper request) { - String ip = request.getRemoteAddr(); - String method = request.getMethod(); - String uri = request.getRequestURI(); - String queryString = request.getQueryString(); - String body = getRequestBody(request); - - logger.info("IP: {}, Method: {}, URI: {}, Query Params: {}, Request Body: {}", - ip, method, uri, (queryString != null ? queryString : "None"), - (!body.isEmpty() ? body : "None")); - } - - private String getRequestBody(ContentCachingRequestWrapper request) { - byte[] buf = request.getContentAsByteArray(); - return (buf.length > 0) ? new String(buf) : ""; - } -} +package com.aolda.itda.config; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.util.ContentCachingRequestWrapper; + +import java.io.IOException; + +@Component +public class LoggingFilter extends OncePerRequestFilter { + + private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class); + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + + // Request Body를 읽을 수 있도록 래핑 + ContentCachingRequestWrapper cachingRequest = new ContentCachingRequestWrapper(request); + filterChain.doFilter(cachingRequest, response); + + // 로그 기록 + logRequest(cachingRequest); + } + + private void logRequest(ContentCachingRequestWrapper request) { + String ip = request.getRemoteAddr(); + String method = request.getMethod(); + String uri = request.getRequestURI(); + String queryString = request.getQueryString(); + String body = getRequestBody(request); + + logger.info("IP: {}, Method: {}, URI: {}, Query Params: {}, Request Body: {}", + ip, method, uri, (queryString != null ? queryString : "None"), + (!body.isEmpty() ? body : "None")); + } + + private String getRequestBody(ContentCachingRequestWrapper request) { + byte[] buf = request.getContentAsByteArray(); + return (buf.length > 0) ? new String(buf) : ""; + } +} diff --git a/src/main/java/com/aolda/itda/controller/main/MainController.java b/src/main/java/com/aolda/itda/controller/main/MainController.java index 7b22923..371cce5 100644 --- a/src/main/java/com/aolda/itda/controller/main/MainController.java +++ b/src/main/java/com/aolda/itda/controller/main/MainController.java @@ -1,33 +1,33 @@ -package com.aolda.itda.controller.main; - -import com.aolda.itda.service.main.MainService; -import com.fasterxml.jackson.core.JsonProcessingException; -import jakarta.servlet.http.HttpServletRequest; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; -import java.util.Map; - -@RestController -@RequestMapping("/api") -@RequiredArgsConstructor -public class MainController { - - private final MainService mainService; - - @GetMapping("/projects") - public ResponseEntity<Object> projects(HttpServletRequest request) throws JsonProcessingException { - return ResponseEntity.ok(mainService.getAllProjects((Map<String, String>) request.getSession().getAttribute("user"))); - } - - @GetMapping("/main") - public ResponseEntity<Object> mainInfo(@RequestParam String projectId, HttpServletRequest request) { - return ResponseEntity.ok(mainService.getMainInfo(projectId, (List<String>) request.getAttribute("projects"))); - } - -} +package com.aolda.itda.controller.main; + +import com.aolda.itda.service.main.MainService; +import com.fasterxml.jackson.core.JsonProcessingException; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +public class MainController { + + private final MainService mainService; + + @GetMapping("/projects") + public ResponseEntity<Object> projects(HttpServletRequest request) throws JsonProcessingException { + return ResponseEntity.ok(mainService.getAllProjects((Map<String, String>) request.getSession().getAttribute("user"))); + } + + @GetMapping("/main") + public ResponseEntity<Object> mainInfo(@RequestParam String projectId, HttpServletRequest request) { + return ResponseEntity.ok(mainService.getMainInfo(projectId, (List<String>) request.getAttribute("projects"))); + } + +} diff --git a/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java b/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java index 6de5fdf..cbcdcd5 100644 --- a/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java +++ b/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java @@ -1,20 +1,20 @@ -package com.aolda.itda.dto.main; - -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -@JsonInclude(JsonInclude.Include.NON_NULL) -public class MainInfoDTO { - - private Long routing; - private Long forwarding; - private Long certificate; - -} +package com.aolda.itda.dto.main; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MainInfoDTO { + + private Long routing; + private Long forwarding; + private Long certificate; + +} diff --git a/src/main/java/com/aolda/itda/entity/certificate/Challenge.java b/src/main/java/com/aolda/itda/entity/certificate/Challenge.java index 14713bf..41f607e 100644 --- a/src/main/java/com/aolda/itda/entity/certificate/Challenge.java +++ b/src/main/java/com/aolda/itda/entity/certificate/Challenge.java @@ -1,5 +1,15 @@ package com.aolda.itda.entity.certificate; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonValue; + +@JsonFormat(shape = JsonFormat.Shape.STRING) public enum Challenge { - HTTP, DNS_CLOUDFLARE + HTTP, DNS_CLOUDFLARE; + + @JsonValue + @Override + public String toString() { + return name().toLowerCase(); + } } diff --git a/src/main/java/com/aolda/itda/entity/log/Action.java b/src/main/java/com/aolda/itda/entity/log/Action.java index a620f87..448a65e 100644 --- a/src/main/java/com/aolda/itda/entity/log/Action.java +++ b/src/main/java/com/aolda/itda/entity/log/Action.java @@ -1,5 +1,15 @@ package com.aolda.itda.entity.log; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonValue; + +@JsonFormat(shape = JsonFormat.Shape.STRING) public enum Action { - CREATE, UPDATE, DELETE + CREATE, UPDATE, DELETE; + + @JsonValue + @Override + public String toString() { + return name().toLowerCase(); + } } diff --git a/src/main/java/com/aolda/itda/entity/log/ObjectType.java b/src/main/java/com/aolda/itda/entity/log/ObjectType.java index 5310315..c91f279 100644 --- a/src/main/java/com/aolda/itda/entity/log/ObjectType.java +++ b/src/main/java/com/aolda/itda/entity/log/ObjectType.java @@ -1,5 +1,15 @@ package com.aolda.itda.entity.log; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonValue; + +@JsonFormat(shape = JsonFormat.Shape.STRING) public enum ObjectType { - ROUTING, CERTIFICATE, FORWARDING + ROUTING, CERTIFICATE, FORWARDING; + + @JsonValue + @Override + public String toString() { + return name().toLowerCase(); + } } diff --git a/src/main/java/com/aolda/itda/service/main/MainService.java b/src/main/java/com/aolda/itda/service/main/MainService.java index 2c36ac8..8a4345e 100644 --- a/src/main/java/com/aolda/itda/service/main/MainService.java +++ b/src/main/java/com/aolda/itda/service/main/MainService.java @@ -1,61 +1,61 @@ -package com.aolda.itda.service.main; - -import com.aolda.itda.dto.PageResp; -import com.aolda.itda.dto.auth.IdAndNameDTO; -import com.aolda.itda.dto.main.MainInfoDTO; -import com.aolda.itda.repository.certificate.CertificateRepository; -import com.aolda.itda.repository.forwarding.ForwardingRepository; -import com.aolda.itda.repository.routing.RoutingRepository; -import com.aolda.itda.service.AuthService; -import com.fasterxml.jackson.core.JsonProcessingException; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -@Service -@Transactional -@RequiredArgsConstructor -public class MainService { - - private final AuthService authService; - private final RoutingRepository routingRepository; - private final ForwardingRepository forwardingRepository; - private final CertificateRepository certificateRepository; - - /* 메인 페이지에 필요한 정보 반환 */ - public MainInfoDTO getMainInfo(String projectId, List<String> projects) { - - /* 프로젝트 권한 검증 */ - authService.validateProjectAuth(projects, projectId); - - /* 카운팅 */ - Long routing = (long) routingRepository.findByProjectIdAndIsDeleted(projectId, false).size(); - Long forwarding = (long) forwardingRepository.findByProjectIdAndIsDeleted(projectId, false).size(); - Long certificate = 0L; - - return MainInfoDTO.builder() - .routing(routing) - .forwarding(forwarding) - .certificate(certificate) - .build(); - } - - /* 접근 가능한 프로젝트 조회 */ - public PageResp<IdAndNameDTO> getAllProjects(Map<String, String> user) throws JsonProcessingException { - - List<IdAndNameDTO> projects; - if (authService.isAdmin(user)) { - projects = authService.getAllProjects(user.get("token")); - } - - else { - projects = authService.getProjectsWithUser(user); - } - - return PageResp.<IdAndNameDTO>builder() - .contents(projects).build(); - } -} +package com.aolda.itda.service.main; + +import com.aolda.itda.dto.PageResp; +import com.aolda.itda.dto.auth.IdAndNameDTO; +import com.aolda.itda.dto.main.MainInfoDTO; +import com.aolda.itda.repository.certificate.CertificateRepository; +import com.aolda.itda.repository.forwarding.ForwardingRepository; +import com.aolda.itda.repository.routing.RoutingRepository; +import com.aolda.itda.service.AuthService; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +@Service +@Transactional +@RequiredArgsConstructor +public class MainService { + + private final AuthService authService; + private final RoutingRepository routingRepository; + private final ForwardingRepository forwardingRepository; + private final CertificateRepository certificateRepository; + + /* 메인 페이지에 필요한 정보 반환 */ + public MainInfoDTO getMainInfo(String projectId, List<String> projects) { + + /* 프로젝트 권한 검증 */ + authService.validateProjectAuth(projects, projectId); + + /* 카운팅 */ + Long routing = (long) routingRepository.findByProjectIdAndIsDeleted(projectId, false).size(); + Long forwarding = (long) forwardingRepository.findByProjectIdAndIsDeleted(projectId, false).size(); + Long certificate = 0L; + + return MainInfoDTO.builder() + .routing(routing) + .forwarding(forwarding) + .certificate(certificate) + .build(); + } + + /* 접근 가능한 프로젝트 조회 */ + public PageResp<IdAndNameDTO> getAllProjects(Map<String, String> user) throws JsonProcessingException { + + List<IdAndNameDTO> projects; + if (authService.isAdmin(user)) { + projects = authService.getAllProjects(user.get("token")); + } + + else { + projects = authService.getProjectsWithUser(user); + } + + return PageResp.<IdAndNameDTO>builder() + .contents(projects).build(); + } +} diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index a8acbee..39e9337 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -1,90 +1,90 @@ -<?xml version="1.0" encoding="UTF-8"?> -<configuration> - - <property name="MAX_FILE_SIZE" value="10MB" /> - <property name="TOTAL_SIZE" value="1GB" /> - <property name="MAX_HISTORY" value="30" /> - - <!-- 콘솔에 출력할 로그 형식 --> - <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> - <encoder> - <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern> - </encoder> - </appender> - - <!-- INFO 로그 파일 저장 (1개당 10MB, 5개까지 유지, 이후 압축) --> - <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>/data/logs/info.log</file> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>/data/logs/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> - <maxHistory>${MAX_HISTORY}</maxHistory> - <totalSizeCap>${TOTAL_SIZE}</totalSizeCap> - <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> - <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> - </timeBasedFileNamingAndTriggeringPolicy> - </rollingPolicy> - <encoder> - <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern> - </encoder> - <!-- INFO 레벨만 허용 --> - <filter class="ch.qos.logback.classic.filter.LevelFilter"> - <level>INFO</level> - <onMatch>ACCEPT</onMatch> - <onMismatch>DENY</onMismatch> - </filter> - </appender> - - <!-- WARN 로그 파일 저장 --> - <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>/data/logs/warn.log</file> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>/data/logs/warn.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> - <maxHistory>${MAX_HISTORY}</maxHistory> - <totalSizeCap>${TOTAL_SIZE}</totalSizeCap> - <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> - <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> - </timeBasedFileNamingAndTriggeringPolicy> - </rollingPolicy> - <encoder> - <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern> - </encoder> - <!-- WARN 레벨만 허용 --> - <filter class="ch.qos.logback.classic.filter.LevelFilter"> - <level>WARN</level> - <onMatch>ACCEPT</onMatch> - <onMismatch>DENY</onMismatch> - </filter> - </appender> - - <!-- ERROR 로그 파일 저장 --> - <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>/data/logs/error.log</file> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>/data/logs/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> - <maxHistory>${MAX_HISTORY}</maxHistory> - <totalSizeCap>${TOTAL_SIZE}</totalSizeCap> - <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> - <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> - </timeBasedFileNamingAndTriggeringPolicy> - </rollingPolicy> - <encoder> - <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern> - </encoder> - <!-- ERROR 레벨만 허용 --> - <filter class="ch.qos.logback.classic.filter.LevelFilter"> - <level>ERROR</level> - <onMatch>ACCEPT</onMatch> - <onMismatch>DENY</onMismatch> - </filter> - </appender> - - <logger name="com.aolda.itda" additivity="false"> - <!-- 각 Appender 참조 (필터는 Appender 내부에 정의됨) --> - <appender-ref ref="INFO_FILE"/> - <appender-ref ref="WARN_FILE"/> - <appender-ref ref="ERROR_FILE"/> - <!-- 콘솔 출력 --> - <appender-ref ref="CONSOLE"/> - </logger> - +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + + <property name="MAX_FILE_SIZE" value="10MB" /> + <property name="TOTAL_SIZE" value="1GB" /> + <property name="MAX_HISTORY" value="30" /> + + <!-- 콘솔에 출력할 로그 형식 --> + <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + </appender> + + <!-- INFO 로그 파일 저장 (1개당 10MB, 5개까지 유지, 이후 압축) --> + <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>/data/logs/info.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <fileNamePattern>/data/logs/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> + <maxHistory>${MAX_HISTORY}</maxHistory> + <totalSizeCap>${TOTAL_SIZE}</totalSizeCap> + <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> + <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> + </timeBasedFileNamingAndTriggeringPolicy> + </rollingPolicy> + <encoder> + <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + <!-- INFO 레벨만 허용 --> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <level>INFO</level> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + </appender> + + <!-- WARN 로그 파일 저장 --> + <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>/data/logs/warn.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <fileNamePattern>/data/logs/warn.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> + <maxHistory>${MAX_HISTORY}</maxHistory> + <totalSizeCap>${TOTAL_SIZE}</totalSizeCap> + <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> + <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> + </timeBasedFileNamingAndTriggeringPolicy> + </rollingPolicy> + <encoder> + <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + <!-- WARN 레벨만 허용 --> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <level>WARN</level> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + </appender> + + <!-- ERROR 로그 파일 저장 --> + <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>/data/logs/error.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <fileNamePattern>/data/logs/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> + <maxHistory>${MAX_HISTORY}</maxHistory> + <totalSizeCap>${TOTAL_SIZE}</totalSizeCap> + <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> + <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> + </timeBasedFileNamingAndTriggeringPolicy> + </rollingPolicy> + <encoder> + <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + <!-- ERROR 레벨만 허용 --> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <level>ERROR</level> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + </appender> + + <logger name="com.aolda.itda" additivity="false"> + <!-- 각 Appender 참조 (필터는 Appender 내부에 정의됨) --> + <appender-ref ref="INFO_FILE"/> + <appender-ref ref="WARN_FILE"/> + <appender-ref ref="ERROR_FILE"/> + <!-- 콘솔 출력 --> + <appender-ref ref="CONSOLE"/> + </logger> + </configuration> \ No newline at end of file -- GitLab From 331b11478b712ac7c3fa1dc2794c3881b53d198d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Sat, 29 Mar 2025 12:04:32 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=20=EA=B2=80=EC=83=89=EC=9D=84=20=EC=9D=BC?= =?UTF-8?q?=EB=B6=80=20=EA=B2=80=EC=83=89=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java b/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java index ceba4b2..19feb19 100644 --- a/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java +++ b/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java @@ -86,7 +86,7 @@ public class LogQueryDSL { /* 사용자 ID 조건 */ if (username != null) { - builder.and(log.user.keystoneUsername.eq(username)); + builder.and(log.user.keystoneUsername.contains(username)); } /* CUD 조건 */ -- GitLab From 88e8e972827daa6d3b8e7fe1330641e42e8e7a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Sat, 29 Mar 2025 13:20:16 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=97=90=20=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../forwarding/ForwardingController.java | 5 ++-- .../controller/routing/RoutingController.java | 5 ++-- .../forwarding/ForwardingRepository.java | 4 ++++ .../repository/routing/RoutingRepository.java | 4 ++++ .../service/forwarding/ForwardingService.java | 16 ++++++++++--- .../itda/service/routing/RoutingService.java | 23 ++++++++++++++++--- 6 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java b/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java index 36e6f9a..999707a 100644 --- a/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java +++ b/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java @@ -30,8 +30,9 @@ public class ForwardingController { } @GetMapping("/forwardings") - public ResponseEntity<Object> lists(@RequestParam String projectId) { - return ResponseEntity.ok(forwardingService.getForwardings(projectId)); + public ResponseEntity<Object> lists(@RequestParam String projectId, + @RequestParam(required = false) String query) { + return ResponseEntity.ok(forwardingService.getForwardingsWithSearch(projectId, query)); } @PatchMapping("/forwarding") diff --git a/src/main/java/com/aolda/itda/controller/routing/RoutingController.java b/src/main/java/com/aolda/itda/controller/routing/RoutingController.java index 4b9d551..c96e910 100644 --- a/src/main/java/com/aolda/itda/controller/routing/RoutingController.java +++ b/src/main/java/com/aolda/itda/controller/routing/RoutingController.java @@ -31,8 +31,9 @@ public class RoutingController { } @GetMapping("/routings") - public ResponseEntity<Object> lists(@RequestParam String projectId) { - return ResponseEntity.ok(routingService.getRoutings(projectId)); + public ResponseEntity<Object> lists(@RequestParam String projectId, + @RequestParam(required = false) String query) { + return ResponseEntity.ok(routingService.getRoutingsWithSearch(projectId, query)); } @PatchMapping("/routing") diff --git a/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java b/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java index c461762..9a330f0 100644 --- a/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java +++ b/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java @@ -2,6 +2,7 @@ package com.aolda.itda.repository.forwarding; import com.aolda.itda.entity.forwarding.Forwarding; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import java.util.List; import java.util.Optional; @@ -11,4 +12,7 @@ public interface ForwardingRepository extends JpaRepository<Forwarding, Long> { Optional<Forwarding> findByForwardingIdAndIsDeleted(Long forwardingId, Boolean isDeleted); Boolean existsByInstanceIpAndInstancePortAndIsDeleted(String instanceIp, String instancePort, Boolean isDeleted); Boolean existsByServerPortAndIsDeleted(String serverPort, Boolean isDeleted); + + @Query("SELECT f FROM Forwarding f WHERE f.projectId = ?1 AND f.isDeleted = ?3 AND (f.instanceIp LIKE %?2% OR f.serverPort LIKE %?2% OR f.name LIKE %?2%)") + List<Forwarding> findWithSearch(String projectId, String query, Boolean isDeleted); } diff --git a/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java b/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java index 046296c..44b88ae 100644 --- a/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java +++ b/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java @@ -3,6 +3,7 @@ package com.aolda.itda.repository.routing; import com.aolda.itda.entity.forwarding.Forwarding; import com.aolda.itda.entity.routing.Routing; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import java.util.List; import java.util.Optional; @@ -11,4 +12,7 @@ public interface RoutingRepository extends JpaRepository<Routing, Long> { List<Routing> findByProjectIdAndIsDeleted(String projectId, Boolean isDeleted); Optional<Routing> findByRoutingIdAndIsDeleted(Long routingId, Boolean isDeleted); Boolean existsByDomainAndIsDeleted(String domain, Boolean isDeleted); + + @Query("SELECT r FROM Routing r WHERE r.projectId = ?1 AND r.isDeleted = ?3 AND (r.domain LIKE %?2% OR r.instanceIp LIKE %?2% OR r.name LIKE %?2%)") + List<Routing> findWithSearch(String projectId, String query, Boolean isDeleted); } diff --git a/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java b/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java index cae38c3..e6fc9d4 100644 --- a/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java +++ b/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java @@ -27,6 +27,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; +import java.util.regex.Pattern; @Service @Transactional @@ -52,11 +53,20 @@ public class ForwardingService { return forwarding.toForwardingDTO(); } - /* 포트포워딩 목록 조회 */ - public PageResp<ForwardingDTO> getForwardings(String projectId) { + /* 포트포워딩 목록 조회 + 검색 */ + public PageResp<ForwardingDTO> getForwardingsWithSearch(String projectId, String query) { + + /* 입력 검증 */ + if (query == null || query.isBlank()) { + return PageResp.<ForwardingDTO>builder() + .contents(forwardingRepository.findByProjectIdAndIsDeleted(projectId, false) + .stream() + .map(Forwarding::toForwardingDTO) + .toList()).build(); + } return PageResp.<ForwardingDTO>builder() - .contents(forwardingRepository.findByProjectIdAndIsDeleted(projectId, false) + .contents(forwardingRepository.findWithSearch(projectId, query, false) .stream() .map(Forwarding::toForwardingDTO) .toList()).build(); diff --git a/src/main/java/com/aolda/itda/service/routing/RoutingService.java b/src/main/java/com/aolda/itda/service/routing/RoutingService.java index 769278d..d01eb02 100644 --- a/src/main/java/com/aolda/itda/service/routing/RoutingService.java +++ b/src/main/java/com/aolda/itda/service/routing/RoutingService.java @@ -28,6 +28,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; +import java.util.regex.Pattern; @Service @Transactional @@ -52,10 +53,26 @@ public class RoutingService { return routing.toRoutingDTO(); } - /* Routing 목록 조회 */ - public PageResp<RoutingDTO> getRoutings(String projectId) { + /* Routing 목록 조회 + 검색 */ + public PageResp<RoutingDTO> getRoutingsWithSearch(String projectId, String query) { + + /* 입력 검증 */ + if (query == null || query.isBlank()) { + return PageResp.<RoutingDTO>builder() + .contents(routingRepository.findByProjectIdAndIsDeleted(projectId, false) + .stream() + .map(Routing::toRoutingDTO) + .toList()).build(); + } + + /* 도메인 패턴 검증 */ + String domainPattern = "^(\\*\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$"; + if (Pattern.matches(domainPattern, query) && query.startsWith("*.")) { + query = query.substring(2); + } + return PageResp.<RoutingDTO>builder() - .contents(routingRepository.findByProjectIdAndIsDeleted(projectId, false) + .contents(routingRepository.findWithSearch(projectId, query, false) .stream() .map(Routing::toRoutingDTO) .toList()).build(); -- GitLab From 9662eda4bf9e66027a5cbe31f55ab3721aa676ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Sat, 29 Mar 2025 13:54:43 +0900 Subject: [PATCH 9/9] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=EC=85=89=ED=84=B0=EC=97=90=EC=84=9C=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=97=90=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{AuthInterceptor.java => AuthFilter.java} | 153 +++++++++--------- .../com/aolda/itda/config/LoggingFilter.java | 15 +- .../java/com/aolda/itda/config/WebConfig.java | 27 +++- 3 files changed, 107 insertions(+), 88 deletions(-) rename src/main/java/com/aolda/itda/config/{AuthInterceptor.java => AuthFilter.java} (71%) diff --git a/src/main/java/com/aolda/itda/config/AuthInterceptor.java b/src/main/java/com/aolda/itda/config/AuthFilter.java similarity index 71% rename from src/main/java/com/aolda/itda/config/AuthInterceptor.java rename to src/main/java/com/aolda/itda/config/AuthFilter.java index fd78fb6..f810c2c 100644 --- a/src/main/java/com/aolda/itda/config/AuthInterceptor.java +++ b/src/main/java/com/aolda/itda/config/AuthFilter.java @@ -1,77 +1,76 @@ -package com.aolda.itda.config; - -import com.aolda.itda.dto.auth.IdAndNameDTO; -import com.aolda.itda.exception.CustomException; -import com.aolda.itda.exception.ErrorCode; -import com.aolda.itda.service.AuthService; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@RequiredArgsConstructor -@Component -@Slf4j -public class AuthInterceptor implements HandlerInterceptor { - - private final AuthService authService; - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - String token = request.getHeader("X-Subject-Token"); - - /* 토큰 헤더 검증 */ - if (token == null || token.isEmpty()) { - throw new CustomException(ErrorCode.INVALID_TOKEN, request.getRequestURI()); - } - - /* 유효 토큰 검증 */ - String userId = authService.validateTokenAndGetUserId(token); - if (userId == null) { - log.error("Token validation failed for URI {}: {}", request.getRequestURI(), request.getRemoteAddr()); - throw new CustomException(ErrorCode.INVALID_TOKEN, request.getRequestURI()); - } - - /* 프로젝트 권한 검증 */ - String projectId = request.getParameter("projectId"); - if (projectId != null) { - - try { - authService.getBestRoleWithinProject(token, projectId).get("role"); - if (!request.getMethod().equals("GET") && !authService.getBestRoleWithinProject(token, projectId).get("role").equals("admin")) { - throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI()); - - } - } catch (Exception e) { - throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI()); - } - - - - } - - /* 프로젝트 리스트 조회 */ - List<String> projects; - if (authService.isAdmin(Map.of("id", userId, "token", token))) { - projects = authService.getAllProjects(token).stream().map(IdAndNameDTO::getId) - .toList(); - } - - else { - projects = authService.getProjectsWithUser(Map.of("id", userId, "token", token)) - .stream().map(IdAndNameDTO::getId) - .toList(); - } - - request.setAttribute("projects", projects); - request.setAttribute("user", Map.of("id", userId, "token", token)); - return true; - - } -} +package com.aolda.itda.config; + +import com.aolda.itda.dto.auth.IdAndNameDTO; +import com.aolda.itda.exception.CustomException; +import com.aolda.itda.exception.ErrorCode; +import com.aolda.itda.service.AuthService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +@RequiredArgsConstructor +@Component +@Slf4j +public class AuthFilter extends OncePerRequestFilter { + + private final AuthService authService; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + + if (request.getRequestURI().contains("/api/auth")) { + filterChain.doFilter(request, response); + return; + } + + String token = request.getHeader("X-Subject-Token"); + + // 토큰 헤더 검증 + if (token == null || token.isEmpty()) { + throw new CustomException(ErrorCode.INVALID_TOKEN, request.getRequestURI()); + } + + // 유효 토큰 검증 + String userId = authService.validateTokenAndGetUserId(token); + if (userId == null) { + log.error("Token validation failed for URI {}: {}", request.getRequestURI(), request.getRemoteAddr()); + throw new CustomException(ErrorCode.INVALID_TOKEN, request.getRequestURI()); + } + + // 프로젝트 권한 검증 + String projectId = request.getParameter("projectId"); + if (projectId != null) { + try { + authService.getBestRoleWithinProject(token, projectId).get("role"); + if (!request.getMethod().equals("GET") && !authService.getBestRoleWithinProject(token, projectId).get("role").equals("admin")) { + throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI()); + } + } catch (Exception e) { + throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI()); + } + } + + // 프로젝트 리스트 조회 + List<String> projects; + if (authService.isAdmin(Map.of("id", userId, "token", token))) { + projects = authService.getAllProjects(token).stream().map(IdAndNameDTO::getId).toList(); + } else { + projects = authService.getProjectsWithUser(Map.of("id", userId, "token", token)).stream().map(IdAndNameDTO::getId).toList(); + } + + request.setAttribute("projects", projects); + request.setAttribute("user", Map.of("id", userId, "token", token)); + + filterChain.doFilter(request, response); + } +} \ No newline at end of file diff --git a/src/main/java/com/aolda/itda/config/LoggingFilter.java b/src/main/java/com/aolda/itda/config/LoggingFilter.java index f2330bf..8c5c2f0 100644 --- a/src/main/java/com/aolda/itda/config/LoggingFilter.java +++ b/src/main/java/com/aolda/itda/config/LoggingFilter.java @@ -1,9 +1,14 @@ package com.aolda.itda.config; +import com.aolda.itda.exception.CustomException; +import com.aolda.itda.exception.ErrorCode; +import com.aolda.itda.service.AuthService; +import com.fasterxml.jackson.core.JsonProcessingException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -11,11 +16,14 @@ import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.ContentCachingRequestWrapper; import java.io.IOException; +import java.util.Map; @Component +@RequiredArgsConstructor public class LoggingFilter extends OncePerRequestFilter { private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class); + private final AuthService authService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) @@ -29,15 +37,16 @@ public class LoggingFilter extends OncePerRequestFilter { logRequest(cachingRequest); } - private void logRequest(ContentCachingRequestWrapper request) { + private void logRequest(ContentCachingRequestWrapper request) throws JsonProcessingException { String ip = request.getRemoteAddr(); String method = request.getMethod(); String uri = request.getRequestURI(); String queryString = request.getQueryString(); String body = getRequestBody(request); + Map<String, String> user = (Map<String, String>) request.getAttribute("user"); - logger.info("IP: {}, Method: {}, URI: {}, Query Params: {}, Request Body: {}", - ip, method, uri, (queryString != null ? queryString : "None"), + logger.info("IP: {}, Method: {}, URI: {}, Query Params: {}, User: {}, Request Body: {}", + ip, method, uri, (queryString != null ? queryString : "None"), (user != null ? user.get("id") : "None"), (!body.isEmpty() ? body : "None")); } diff --git a/src/main/java/com/aolda/itda/config/WebConfig.java b/src/main/java/com/aolda/itda/config/WebConfig.java index e3893ae..a3559c4 100644 --- a/src/main/java/com/aolda/itda/config/WebConfig.java +++ b/src/main/java/com/aolda/itda/config/WebConfig.java @@ -3,17 +3,18 @@ package com.aolda.itda.config; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { - private final AuthInterceptor authInterceptor; + private final AuthFilter authFilter; + private final LoggingFilter loggingFilter; @Override public void addCorsMappings(CorsRegistry registry) { // 스프링단에서 cors 설정 @@ -26,13 +27,23 @@ public class WebConfig implements WebMvcConfigurer { ; } - @Override - public void addInterceptors(InterceptorRegistry registry) { - String[] excludeAuth = {"/error", "/api/auth/*" }; - registry.addInterceptor(authInterceptor) - .addPathPatterns("/**") - .excludePathPatterns(excludeAuth); + @Bean + public FilterRegistrationBean<AuthFilter> authFilterRegistration() { + FilterRegistrationBean<AuthFilter> registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(authFilter); + registrationBean.setOrder(1); // AuthFilter의 순서를 1로 설정 + registrationBean.addUrlPatterns("/*"); + return registrationBean; + } + + @Bean + public FilterRegistrationBean<LoggingFilter> loggingFilterRegistration() { + FilterRegistrationBean<LoggingFilter> registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(loggingFilter); + registrationBean.setOrder(2); // LoggingFilter의 순서를 2로 설정 + registrationBean.addUrlPatterns("/*"); + return registrationBean; } @Bean -- GitLab