From 14790a12bd306b4c2129c77a51e8bb8643a7172d Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Fri, 8 Nov 2024 21:31:48 +0900 Subject: [PATCH 001/216] =?UTF-8?q?[feat]=20Cookie=EC=97=90=20Secure=20?= =?UTF-8?q?=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 관련 이슈: #50 --- .../security/handler/CustomSuccessHandler.java | 13 ++++++++----- .../team7/inplace/security/util/CookieUtil.java | 16 +++++++++------- .../presentation/RefreshTokenController.java | 14 ++++++++++---- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java b/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java index 7936e91b..5594f8d5 100644 --- a/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java +++ b/src/main/java/team7/inplace/security/handler/CustomSuccessHandler.java @@ -1,10 +1,11 @@ package team7.inplace.security.handler; -import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseCookie; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import team7.inplace.security.application.dto.CustomOAuth2User; @@ -49,13 +50,15 @@ private void addTokenToResponse( HttpServletResponse response, String accessToken, String refreshToken ) { - Cookie accessTokenCookie = CookieUtil.createCookie(TokenType.ACCESS_TOKEN.getValue(), + ResponseCookie accessTokenCookie = CookieUtil.createCookie( + TokenType.ACCESS_TOKEN.getValue(), accessToken); - Cookie refreshTokenCookie = CookieUtil.createCookie(TokenType.REFRESH_TOKEN.getValue(), + ResponseCookie refreshTokenCookie = CookieUtil.createCookie( + TokenType.REFRESH_TOKEN.getValue(), refreshToken); - response.addCookie(accessTokenCookie); - response.addCookie(refreshTokenCookie); + response.addHeader(HttpHeaders.SET_COOKIE, accessTokenCookie.toString()); + response.addHeader(HttpHeaders.SET_COOKIE, refreshTokenCookie.toString()); } private void setRedirectUrlToResponse( diff --git a/src/main/java/team7/inplace/security/util/CookieUtil.java b/src/main/java/team7/inplace/security/util/CookieUtil.java index 309421f3..9bf7bac6 100644 --- a/src/main/java/team7/inplace/security/util/CookieUtil.java +++ b/src/main/java/team7/inplace/security/util/CookieUtil.java @@ -1,14 +1,16 @@ package team7.inplace.security.util; -import jakarta.servlet.http.Cookie; +import org.springframework.http.ResponseCookie; public class CookieUtil { - public static Cookie createCookie(String key, String value) { - Cookie cookie = new Cookie(key, value); - cookie.setMaxAge(60 * 60); - cookie.setPath("/"); - cookie.setHttpOnly(true); - return cookie; + public static ResponseCookie createCookie(String key, String value) { + return ResponseCookie.from(key, value) + .sameSite("Lax") + .secure(true) + .path("/") + .httpOnly(true) + .maxAge(60 * 60) + .build(); } } diff --git a/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java b/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java index e1f2dd1f..e20c1678 100644 --- a/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java +++ b/src/main/java/team7/inplace/token/presentation/RefreshTokenController.java @@ -3,13 +3,16 @@ import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseCookie; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import team7.inplace.global.exception.InplaceException; import team7.inplace.global.exception.code.AuthorizationErrorCode; +import team7.inplace.security.filter.TokenType; import team7.inplace.security.util.AuthorizationUtil; import team7.inplace.security.util.CookieUtil; import team7.inplace.security.util.JwtUtil; @@ -39,12 +42,15 @@ public ResponseEntity refreshToken(@CookieValue(value = "refresh_token") C } private void addTokenToCookie(HttpServletResponse response, ReIssued reIssuedToken) { - Cookie accessTokenCookie = CookieUtil.createCookie("access_token", + ResponseCookie accessTokenCookie = CookieUtil.createCookie( + TokenType.ACCESS_TOKEN.getValue(), reIssuedToken.accessToken()); - Cookie refreshTokenCookie = CookieUtil.createCookie("refresh_token", + ResponseCookie refreshTokenCookie = CookieUtil.createCookie( + TokenType.REFRESH_TOKEN.getValue(), reIssuedToken.refreshToken()); - response.addCookie(accessTokenCookie); - response.addCookie(refreshTokenCookie); + + response.addHeader(HttpHeaders.SET_COOKIE, accessTokenCookie.toString()); + response.addHeader(HttpHeaders.SET_COOKIE, refreshTokenCookie.toString()); } private boolean cannotRefreshToken(Cookie cookie) { From 121a27445a2aaf5995620ea1414c2e144a0288ee Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Fri, 8 Nov 2024 21:33:26 +0900 Subject: [PATCH 002/216] =?UTF-8?q?[feat]=20webClient=EC=9D=98=20timeout?= =?UTF-8?q?=20=EC=9D=84=20=EB=8D=94=20=EA=B8=B8=EA=B2=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit jmeter test하는 도중 pool이 부족해 발생하는 문제를 해결하기 위해 timeout을 길게 만들었습니다. 관련 이슈: #50 --- .../java/team7/inplace/global/rest/WebClientConfig.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/team7/inplace/global/rest/WebClientConfig.java b/src/main/java/team7/inplace/global/rest/WebClientConfig.java index 404309ba..b8a62531 100644 --- a/src/main/java/team7/inplace/global/rest/WebClientConfig.java +++ b/src/main/java/team7/inplace/global/rest/WebClientConfig.java @@ -1,8 +1,11 @@ package team7.inplace.global.rest; +import java.time.Duration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.reactive.function.client.WebClient; +import reactor.netty.http.client.HttpClient; @Configuration public class WebClientConfig { @@ -10,6 +13,9 @@ public class WebClientConfig { @Bean public WebClient webClient() { return WebClient.builder() + .clientConnector(new ReactorClientHttpConnector( + HttpClient.create().responseTimeout(Duration.ofMillis(60000)) + )) .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024)) .build(); } From e6a3c24c6b92e3b80c75bc5ec0e0bd565da63896 Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Fri, 8 Nov 2024 22:18:43 +0900 Subject: [PATCH 003/216] =?UTF-8?q?[fix]=20authentication=20=EB=AC=B8?= =?UTF-8?q?=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 permitAll()인 url에서 expired된 token을 가지고 있는 경우 통과되어야 하는데, 통과되지 않고 expired 되는 경우를 올바르게 고쳤습니다. 관련 이슈: #50 --- .../team7/inplace/security/filter/AuthorizationFilter.java | 5 +++-- .../inplace/security/handler/CustomAccessDeniedHandler.java | 3 +-- src/main/java/team7/inplace/security/util/JwtUtil.java | 5 +++-- src/test/java/team7/inplace/security/util/JwtUtilTest.java | 6 +----- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/team7/inplace/security/filter/AuthorizationFilter.java b/src/main/java/team7/inplace/security/filter/AuthorizationFilter.java index a63935c6..a354d2d9 100644 --- a/src/main/java/team7/inplace/security/filter/AuthorizationFilter.java +++ b/src/main/java/team7/inplace/security/filter/AuthorizationFilter.java @@ -35,8 +35,9 @@ protected void doFilterInternal( return; } String token = getTokenCookie(request).getValue(); - jwtUtil.validateExpired(token); - addUserToAuthentication(token); + if (jwtUtil.isNotExpired(token)) { + addUserToAuthentication(token); + } filterChain.doFilter(request, response); } diff --git a/src/main/java/team7/inplace/security/handler/CustomAccessDeniedHandler.java b/src/main/java/team7/inplace/security/handler/CustomAccessDeniedHandler.java index ab09d1fc..778981da 100644 --- a/src/main/java/team7/inplace/security/handler/CustomAccessDeniedHandler.java +++ b/src/main/java/team7/inplace/security/handler/CustomAccessDeniedHandler.java @@ -1,6 +1,5 @@ package team7.inplace.security.handler; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @@ -11,7 +10,7 @@ public class CustomAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, - AccessDeniedException accessDeniedException) throws IOException, ServletException { + AccessDeniedException accessDeniedException) throws IOException { response.sendRedirect("/"); } } diff --git a/src/main/java/team7/inplace/security/util/JwtUtil.java b/src/main/java/team7/inplace/security/util/JwtUtil.java index 3adb4266..546e8324 100644 --- a/src/main/java/team7/inplace/security/util/JwtUtil.java +++ b/src/main/java/team7/inplace/security/util/JwtUtil.java @@ -82,13 +82,14 @@ public String getRoles(String token) throws InplaceException { } } - public void validateExpired(String token) throws InplaceException { + public boolean isNotExpired(String token) { try { jwtParser.parseSignedClaims(token).getPayload().getExpiration(); } catch (ExpiredJwtException e) { - throw InplaceException.of(AuthorizationErrorCode.TOKEN_IS_EXPIRED); + return false; } catch (JwtException | IllegalArgumentException e) { throw InplaceException.of(AuthorizationErrorCode.INVALID_TOKEN); } + return true; } } diff --git a/src/test/java/team7/inplace/security/util/JwtUtilTest.java b/src/test/java/team7/inplace/security/util/JwtUtilTest.java index 9e8cd2f5..16019835 100644 --- a/src/test/java/team7/inplace/security/util/JwtUtilTest.java +++ b/src/test/java/team7/inplace/security/util/JwtUtilTest.java @@ -1,7 +1,6 @@ package team7.inplace.security.util; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.jupiter.api.Assertions.assertAll; import io.jsonwebtoken.Jwts; @@ -12,7 +11,6 @@ import javax.crypto.spec.SecretKeySpec; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import team7.inplace.global.exception.InplaceException; import team7.inplace.security.config.JwtProperties; import team7.inplace.user.domain.Role; @@ -73,8 +71,6 @@ void getInfoTests() { .signWith(secretKey) .compact(); - assertThatExceptionOfType(InplaceException.class).isThrownBy( - () -> jwtUtil.validateExpired(expiredToken) - ); + assertThat(jwtUtil.isNotExpired(expiredToken)).isFalse(); } } From 115bd329cf3cac5ce21d41fbd3b5418d37e9a0ad Mon Sep 17 00:00:00 2001 From: suhyeon7497 Date: Fri, 8 Nov 2024 22:32:43 +0900 Subject: [PATCH 004/216] =?UTF-8?q?[feat]=20html=EB=A1=9C=20api=EC=84=9C?= =?UTF-8?q?=EB=B2=84=20=EC=A0=91=EA=B7=BC=20=EC=8B=9C=20frontend=EB=A1=9C?= =?UTF-8?q?=20redirect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 관련 이슈 : #50 --- .../global/exception/code/AuthorizationErrorCode.java | 7 ++++--- .../security/handler/CustomFailureHandler.java | 11 +++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/team7/inplace/global/exception/code/AuthorizationErrorCode.java b/src/main/java/team7/inplace/global/exception/code/AuthorizationErrorCode.java index 640aaccf..930468d4 100644 --- a/src/main/java/team7/inplace/global/exception/code/AuthorizationErrorCode.java +++ b/src/main/java/team7/inplace/global/exception/code/AuthorizationErrorCode.java @@ -7,9 +7,10 @@ @AllArgsConstructor @Getter public enum AuthorizationErrorCode implements ErrorCode { - TOKEN_IS_EMPTY(HttpStatus.BAD_REQUEST, "A001", "Token is Empty"), - INVALID_TOKEN(HttpStatus.BAD_REQUEST, "A002", "Invalid Token"), - TOKEN_IS_EXPIRED(HttpStatus.BAD_REQUEST, "A003", "Token is Expired"); + NOT_AUTHENTICATION(HttpStatus.UNAUTHORIZED, "A000", "Authentication 실패"), + TOKEN_IS_EMPTY(HttpStatus.BAD_REQUEST, "A001", "토큰 없음"), + INVALID_TOKEN(HttpStatus.BAD_REQUEST, "A002", "Invalid 토큰"), + TOKEN_IS_EXPIRED(HttpStatus.BAD_REQUEST, "A003", "토큰 만료"); private final HttpStatus httpStatus; private final String errorCode; diff --git a/src/main/java/team7/inplace/security/handler/CustomFailureHandler.java b/src/main/java/team7/inplace/security/handler/CustomFailureHandler.java index 05236d80..4f88fea6 100644 --- a/src/main/java/team7/inplace/security/handler/CustomFailureHandler.java +++ b/src/main/java/team7/inplace/security/handler/CustomFailureHandler.java @@ -5,16 +5,20 @@ import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.http.ProblemDetail; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.util.StringUtils; import team7.inplace.global.exception.InplaceException; import team7.inplace.global.exception.code.AuthorizationErrorCode; @Slf4j public class CustomFailureHandler implements AuthenticationFailureHandler { + @Value("${spring.redirect.front-end-url}") + private String frontEndUrl; private final ObjectMapper objectMapper; public CustomFailureHandler(ObjectMapper objectMapper) { @@ -27,8 +31,11 @@ public void onAuthenticationFailure( HttpServletResponse response, AuthenticationException exception ) throws IOException { - log.info("CustomFailureHandler.onAuthenticationFailure"); - setErrorResponse(response, InplaceException.of(AuthorizationErrorCode.TOKEN_IS_EXPIRED)); + String accept = request.getHeader("Accept"); + if (StringUtils.hasText(accept) && accept.contains("text/html")) { + response.sendRedirect(frontEndUrl); + } + setErrorResponse(response, InplaceException.of(AuthorizationErrorCode.NOT_AUTHENTICATION)); } private void setErrorResponse( From a43d0dcadbf32a39f51dbcdf2cb796eea2eec709 Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Sat, 9 Nov 2024 20:37:29 +0900 Subject: [PATCH 005/216] =?UTF-8?q?[refactor]=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8A=94=20api=20=EC=A3=BC=EC=86=8C?= =?UTF-8?q?=EB=A5=BC=20=EA=B0=90=EC=B6=94=EA=B8=B0=20=EC=9C=84=ED=95=B4=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20=EB=B3=80=EC=88=98=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team7/inplace/global/kakao/config/KakaoApiProperties.java | 1 + src/main/resources/application-db.yaml | 2 +- src/main/resources/application-kakao.yaml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/team7/inplace/global/kakao/config/KakaoApiProperties.java b/src/main/java/team7/inplace/global/kakao/config/KakaoApiProperties.java index c725c472..13778fb7 100644 --- a/src/main/java/team7/inplace/global/kakao/config/KakaoApiProperties.java +++ b/src/main/java/team7/inplace/global/kakao/config/KakaoApiProperties.java @@ -5,6 +5,7 @@ @ConfigurationProperties(prefix = "kakao.api") public record KakaoApiProperties( String key, + String jsKey, String sendMessageToMeUrl ) { diff --git a/src/main/resources/application-db.yaml b/src/main/resources/application-db.yaml index 479196b4..540f5d0b 100644 --- a/src/main/resources/application-db.yaml +++ b/src/main/resources/application-db.yaml @@ -6,7 +6,7 @@ spring: driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: - ddl-auto: none + ddl-auto: create-drop properties: hibernate: format_sql: true diff --git a/src/main/resources/application-kakao.yaml b/src/main/resources/application-kakao.yaml index 6cbe2dd5..43d78643 100644 --- a/src/main/resources/application-kakao.yaml +++ b/src/main/resources/application-kakao.yaml @@ -1,4 +1,5 @@ kakao: api: key: ${KAKAO_REST_API_KEY} + js-key : ${KAKAO_JS_API_KEY} send-message-to-me-url: ${KAKAO_MESSAGE_TO_ME_URL} From f07a988b7a9ac37fdcb7e8f86151984cacfa310d Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Sat, 9 Nov 2024 20:38:01 +0900 Subject: [PATCH 006/216] =?UTF-8?q?[refactor]=20=ED=99=98=EA=B2=BD=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=EB=A1=9C=20api=20=EC=A3=BC=EC=86=8C=EB=A5=BC?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/admin/video.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/admin/video.html b/src/main/resources/templates/admin/video.html index 492dddd3..d3434d43 100644 --- a/src/main/resources/templates/admin/video.html +++ b/src/main/resources/templates/admin/video.html @@ -5,7 +5,7 @@ Video List - From 01b7d97fcf8d4fe4927a7411d5611242d0c50d7c Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Sat, 9 Nov 2024 20:38:22 +0900 Subject: [PATCH 007/216] =?UTF-8?q?[fix]=20video=20=EC=82=AD=EC=A0=9C=20ap?= =?UTF-8?q?i=EC=9D=98=20=EC=98=A4=EB=A5=98=EB=A5=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/team7/inplace/admin/AdminPageController.java | 1 + .../inplace/video/presentation/VideoControllerApiSpec.java | 3 ++- src/main/resources/static/js/video.js | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/team7/inplace/admin/AdminPageController.java b/src/main/java/team7/inplace/admin/AdminPageController.java index cfc69efa..bee75868 100644 --- a/src/main/java/team7/inplace/admin/AdminPageController.java +++ b/src/main/java/team7/inplace/admin/AdminPageController.java @@ -31,6 +31,7 @@ public String getVideos(@PageableDefault Pageable pageable, Model model) { model.addAttribute("totalPages", videoPage.getTotalPages()); model.addAttribute("isFirst", videoPage.isFirst()); model.addAttribute("isLast", videoPage.isLast()); + model.addAttribute("kakaoApiKey", kakaoApiProperties.jsKey()); return "admin/video.html"; } diff --git a/src/main/java/team7/inplace/video/presentation/VideoControllerApiSpec.java b/src/main/java/team7/inplace/video/presentation/VideoControllerApiSpec.java index 4c25534e..4c3e042a 100644 --- a/src/main/java/team7/inplace/video/presentation/VideoControllerApiSpec.java +++ b/src/main/java/team7/inplace/video/presentation/VideoControllerApiSpec.java @@ -6,6 +6,7 @@ import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; import team7.inplace.video.presentation.dto.VideoResponse; import team7.inplace.video.presentation.dto.VideoSearchParams; @@ -58,6 +59,6 @@ ResponseEntity> readPlaceNullVideo( description = "비디오를 삭제합니다." ) ResponseEntity deleteVideo( - @RequestParam Long videoId + @PathVariable Long videoId ); } diff --git a/src/main/resources/static/js/video.js b/src/main/resources/static/js/video.js index c56a01be..f589ecc9 100644 --- a/src/main/resources/static/js/video.js +++ b/src/main/resources/static/js/video.js @@ -75,7 +75,7 @@ function deleteVideo(element) { } const videoId = element.getAttribute("data-video-id"); $.ajax({ - url: `/videos/${videoId}`, + url: '/videos/' + videoId, method: 'DELETE', success: function () { alert("장소가 삭제되었습니다."); From 21459041e0657dff2d9df3431ad5ff5da951aba3 Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Sat, 9 Nov 2024 20:44:01 +0900 Subject: [PATCH 008/216] =?UTF-8?q?[chore]=20=EC=8B=A4=EC=88=98=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=ED=95=9C=20=EC=84=A4=EC=A0=95=20=EC=9E=AC?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-db.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-db.yaml b/src/main/resources/application-db.yaml index 540f5d0b..479196b4 100644 --- a/src/main/resources/application-db.yaml +++ b/src/main/resources/application-db.yaml @@ -6,7 +6,7 @@ spring: driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: - ddl-auto: create-drop + ddl-auto: none properties: hibernate: format_sql: true From 9f7611c13286b768a1f957206fa2904fe562ebcc Mon Sep 17 00:00:00 2001 From: BaeJunho Date: Sat, 9 Nov 2024 21:12:58 +0900 Subject: [PATCH 009/216] =?UTF-8?q?[refactor]=20=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8A=94=20api=20=EB=AA=A8=EB=91=90=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=95=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F,?= =?UTF-8?q?=2010=EA=B0=9C=EB=A7=8C=20=EB=B3=B4=EB=82=B4=EB=8A=94=20?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../video/application/VideoFacade.java | 4 +- .../video/application/VideoService.java | 49 ++++++++++++++----- .../video/presentation/VideoController.java | 36 ++++++-------- .../presentation/VideoControllerApiSpec.java | 22 +++------ .../video/application/VideoServiceTest.java | 16 +++--- 5 files changed, 71 insertions(+), 56 deletions(-) diff --git a/src/main/java/team7/inplace/video/application/VideoFacade.java b/src/main/java/team7/inplace/video/application/VideoFacade.java index a4ad5887..046198f8 100644 --- a/src/main/java/team7/inplace/video/application/VideoFacade.java +++ b/src/main/java/team7/inplace/video/application/VideoFacade.java @@ -49,7 +49,7 @@ public void addPlaceInfo(Long videoId, PlacesCommand.Create placeCommand) { } @Transactional(readOnly = true) - public Page getVideosByMyInfluencer(Pageable pageable) { + public List getVideosByMyInfluencer() { // 토큰 정보에 대한 검증 if (AuthorizationUtil.isNotLoginUser()) { throw InplaceException.of(AuthorizationErrorCode.TOKEN_IS_EMPTY); @@ -59,6 +59,6 @@ public Page getVideosByMyInfluencer(Pageable pageable) { // 유저 정보를 이용하여 유저가 좋아요를 누른 인플루언서 id 리스트를 조회 List influencerIds = userService.getInfluencerIdsByUsername(userId); // 인플루언서 id를 사용하여 영상을 조회 - return videoService.getVideosByMyInfluencer(influencerIds, pageable); + return videoService.getVideosByMyInfluencer(influencerIds); } } diff --git a/src/main/java/team7/inplace/video/application/VideoService.java b/src/main/java/team7/inplace/video/application/VideoService.java index 72908f30..b4a408bf 100644 --- a/src/main/java/team7/inplace/video/application/VideoService.java +++ b/src/main/java/team7/inplace/video/application/VideoService.java @@ -3,15 +3,19 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import team7.inplace.global.exception.InplaceException; +import team7.inplace.global.exception.code.AuthorizationErrorCode; import team7.inplace.global.exception.code.PlaceErrorCode; import team7.inplace.global.exception.code.VideoErrorCode; import team7.inplace.influencer.persistence.InfluencerRepository; import team7.inplace.place.application.dto.PlaceForVideo; import team7.inplace.place.domain.Place; import team7.inplace.place.persistence.PlaceRepository; +import team7.inplace.security.util.AuthorizationUtil; import team7.inplace.video.application.command.VideoCommand; import team7.inplace.video.application.command.VideoCommand.Create; import team7.inplace.video.application.dto.VideoInfo; @@ -31,7 +35,13 @@ public class VideoService { private final PlaceRepository placeRepository; private final InfluencerRepository influencerRepository; - public Page getVideosBySurround(VideoSearchParams videoSearchParams, Pageable pageable) { + @Transactional(readOnly = true) + public List getVideosBySurround(VideoSearchParams videoSearchParams) { + // 토큰 정보에 대한 검증 + if (AuthorizationUtil.isNotLoginUser()) { + throw InplaceException.of(AuthorizationErrorCode.TOKEN_IS_EMPTY); + } + // Place 엔티티 조회 Page places = placeRepository.findPlacesByDistanceAndFilters( videoSearchParams.topLeftLongitude(), @@ -42,7 +52,7 @@ public Page getVideosBySurround(VideoSearchParams videoSearchParams, videoSearchParams.latitude(), null, null, - pageable + PageRequest.of(0, 10) ); // 조회된 엔티티가 비어있는지 아닌지 확인 if (places.isEmpty()) { @@ -54,30 +64,41 @@ public Page getVideosBySurround(VideoSearchParams videoSearchParams, videos.add(videoRepository.findTopByPlaceOrderByIdDesc(place) .orElseThrow(() -> InplaceException.of(VideoErrorCode.NOT_FOUND))); } - return new PageImpl<>(videos, pageable, videos.size()).map(this::videoToInfo); + return videos.stream().map(this::videoToInfo).toList(); } - public Page getAllVideosDesc(Pageable pageable) { + @Transactional(readOnly = true) + public List getAllVideosDesc() { // id를 기준으로 내림차순 정렬하여 비디오 정보 불러오기 - Page