diff --git a/src/main/java/com/retrip/trip/application/in/TripService.java b/src/main/java/com/retrip/trip/application/in/TripService.java index 093103c..e07d081 100644 --- a/src/main/java/com/retrip/trip/application/in/TripService.java +++ b/src/main/java/com/retrip/trip/application/in/TripService.java @@ -43,7 +43,6 @@ public class TripService @Override public TripCreateResponse createTrip(UUID memberId, TripCreateRequest request) { Trip trip = request.to(memberId); - assignPasswordIfNotOpen(trip, request.password()); Trip savedTrip = tripRepository.save(trip); return TripCreateResponse.of(savedTrip); } @@ -51,7 +50,6 @@ public TripCreateResponse createTrip(UUID memberId, TripCreateRequest request) { @Override public TripCreateResponse createTripWithItineraries(UUID memberId, TripCreateRequest request) { Trip trip = request.toWithItineraries(memberId); - assignPasswordIfNotOpen(trip, request.password()); Trip savedTrip = tripRepository.save(trip); return TripCreateResponse.of(savedTrip); } @@ -164,7 +162,7 @@ private void assignPasswordIfNotOpen(Trip trip, String password) { if (trip.isOpen()) { return; } - String trimPassword = password.trim(); + String trimPassword = (password != null) ? password.trim() : ""; if (!StringUtils.hasText(trimPassword)) { throw new InvalidValueException(PRIVATE_TRIP_PASSWORD_REQUIRED); } diff --git a/src/main/java/com/retrip/trip/application/in/request/TripCreateRequest.java b/src/main/java/com/retrip/trip/application/in/request/TripCreateRequest.java index a705aae..86ffa94 100644 --- a/src/main/java/com/retrip/trip/application/in/request/TripCreateRequest.java +++ b/src/main/java/com/retrip/trip/application/in/request/TripCreateRequest.java @@ -39,11 +39,11 @@ public record TripCreateRequest( @FutureOrPresent LocalDate end, - @Schema(description = "여행 공개 여부") - boolean open, - - @Schema(description = "여행 참여 비밀번호") - String password, +// @Schema(description = "여행 공개 여부") +// boolean open, +// +// @Schema(description = "여행 참여 비밀번호") +// String password, @Schema(description = "여행 최대 참가 인원") int maxParticipants, @@ -63,7 +63,7 @@ public Trip to(UUID memberId) { imageUrl, new TripDescription(description), new TripPeriod(start, end), - open, + true, maxParticipants, hashTags, category, @@ -79,7 +79,7 @@ public Trip toWithItineraries(UUID memberId) { imageUrl, new TripDescription(description), new TripPeriod(start, end), - open, + true, maxParticipants, hashTags, category, diff --git a/src/main/java/com/retrip/trip/application/in/request/context/WithUserContext.java b/src/main/java/com/retrip/trip/application/in/request/context/WithUserContext.java index 73b9228..65d9ea7 100644 --- a/src/main/java/com/retrip/trip/application/in/request/context/WithUserContext.java +++ b/src/main/java/com/retrip/trip/application/in/request/context/WithUserContext.java @@ -1,14 +1,14 @@ package com.retrip.trip.application.in.request.context; import io.swagger.v3.oas.annotations.Parameter; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) @Parameter(hidden = true) public @interface WithUserContext { -} + boolean required() default true; +} \ No newline at end of file diff --git a/src/main/java/com/retrip/trip/application/in/response/TripDetailResponse.java b/src/main/java/com/retrip/trip/application/in/response/TripDetailResponse.java index fce91ab..f0d48b1 100644 --- a/src/main/java/com/retrip/trip/application/in/response/TripDetailResponse.java +++ b/src/main/java/com/retrip/trip/application/in/response/TripDetailResponse.java @@ -98,8 +98,8 @@ public record TripDetailResponse( public static TripDetailResponse of(UUID memberId, Trip trip) { return TripDetailResponse.builder() .id(trip.getId()) - .isLeader(trip.getTripParticipants().isLeader(memberId)) - .isParticipant(trip.getTripParticipants().isParticipant(memberId)) + .isLeader(memberId != null && trip.getTripParticipants().isLeader(memberId)) + .isParticipant(memberId != null && trip.getTripParticipants().isParticipant(memberId)) .title(trip.getTitle().getValue()) .createdAt(trip.getCreatedAt()) .participantCount(trip.getTripParticipants().getCurrentCount()) @@ -158,14 +158,13 @@ public static List toList(List tripPar .toList(); } - //TODO: 해당 참가자 정보 auth API 에서 따로 가져오도록 수정해야함 private static TripParticipantResponse of(TripParticipant participant) { return TripParticipantResponse.builder() .participantId(participant.getId()) .memberId(participant.getMemberId()) - .introduction("안녕하세여") - .nickName("박정수") - .imageUrl("http://~~~") + .introduction(null) + .nickName("여행자-" + participant.getMemberId().toString().substring(0, 8)) + .imageUrl(null) .role(participant.getRole()) .build(); } diff --git a/src/main/java/com/retrip/trip/infra/adapter/in/presentation/filter/AuthenticationFilter.java b/src/main/java/com/retrip/trip/infra/adapter/in/presentation/filter/AuthenticationFilter.java index 4565e0a..a98cff1 100644 --- a/src/main/java/com/retrip/trip/infra/adapter/in/presentation/filter/AuthenticationFilter.java +++ b/src/main/java/com/retrip/trip/infra/adapter/in/presentation/filter/AuthenticationFilter.java @@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; @@ -30,6 +31,7 @@ public class AuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + String path = request.getRequestURI(); String pathLowercase = path.toLowerCase(); @@ -39,7 +41,6 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse pathLowercase.contains("actuator") || pathLowercase.contains("robots.txt") || pathLowercase.contains("status-check") || - pathLowercase.contains("trips") || pathLowercase.contains("images") || pathLowercase.contains("/h2-console")) { filterChain.doFilter(request, response); @@ -47,40 +48,36 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse } String token = resolveToken(request); - if (token == null || token.isEmpty()) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - try { - Claims claims = getClaims(token); + if (StringUtils.hasText(token)) { + try { + Claims claims = getClaims(token); - String subject = claims.getSubject(); - UUID memberId = UUID.fromString(subject); + String subject = claims.getSubject(); + UUID memberId = UUID.fromString(subject); - UserContext userContext = new UserContext( - memberId, - claims.get("nickname", String.class), - claims.get("email", String.class), - claims.get("name", String.class), - null, - 0 - ); + UserContext userContext = new UserContext( + memberId, + claims.get("nickname", String.class), + claims.get("email", String.class), + claims.get("name", String.class), + null, + 0 + ); - request.setAttribute("userContext", userContext); - - filterChain.doFilter(request, response); - - } catch (Exception e) { - log.error("Token validation failed: {}", e.getMessage()); - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + request.setAttribute("userContext", userContext); + } catch (Exception e) { + log.warn("Invalid Token: {}", e.getMessage()); + } } + + filterChain.doFilter(request, response); } private String resolveToken(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); - if (bearerToken != null && bearerToken.startsWith("Bearer ")) { + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { return bearerToken.substring(7); } return null; diff --git a/src/main/java/com/retrip/trip/infra/adapter/in/presentation/resolver/UserContextArgumentResolver.java b/src/main/java/com/retrip/trip/infra/adapter/in/presentation/resolver/UserContextArgumentResolver.java index 027b712..6692fda 100644 --- a/src/main/java/com/retrip/trip/infra/adapter/in/presentation/resolver/UserContextArgumentResolver.java +++ b/src/main/java/com/retrip/trip/infra/adapter/in/presentation/resolver/UserContextArgumentResolver.java @@ -15,22 +15,26 @@ public class UserContextArgumentResolver implements HandlerMethodArgumentResolve @Override public boolean supportsParameter(MethodParameter parameter) { - return parameter.hasParameterAnnotation(WithUserContext.class); + return parameter.hasParameterAnnotation(WithUserContext.class) + && parameter.getParameterType().equals(UserContext.class); } @Override - public UserContext resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, - NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { -// UserContext userContext = (UserContext) webRequest.getAttribute( -// "userContext", -// RequestAttributes.SCOPE_REQUEST -// ); + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { - UserContext userContext = UserContext.mockOf(); + UserContext userContext = (UserContext) webRequest.getAttribute( + "userContext", + RequestAttributes.SCOPE_REQUEST + ); - if (userContext == null) { - throw new IllegalStateException("UserContext not found in request"); + WithUserContext annotation = parameter.getParameterAnnotation(WithUserContext.class); + boolean required = (annotation != null) && annotation.required(); + + if (required && userContext == null) { + throw new IllegalStateException("Login required"); } + return userContext; } -} +} \ No newline at end of file diff --git a/src/main/java/com/retrip/trip/infra/adapter/in/presentation/rest/TripController.java b/src/main/java/com/retrip/trip/infra/adapter/in/presentation/rest/TripController.java index 07a170c..75ffd39 100644 --- a/src/main/java/com/retrip/trip/infra/adapter/in/presentation/rest/TripController.java +++ b/src/main/java/com/retrip/trip/infra/adapter/in/presentation/rest/TripController.java @@ -97,15 +97,21 @@ public ApiResponse> getTrips( return ApiResponse.ok(trips); } + @Operation( summary = "여행 상세 조회", - description = "tripId를 이용하여 여행 상세 정보를 조회하는 API" + description = "tripId를 이용하여 여행 상세 정보를 조회합니다. (비로그인 가능)" ) @ApiErrorCodeExample(TRIP_NOT_FOUND) @GetMapping("/{tripId}") - public ApiResponse getTripDetail(@WithUserContext UserContext userContext, - @PathVariable UUID tripId) { - TripDetailResponse tripDetail = getTripUseCase.getTripDetail(userContext.memberId(), tripId); + @Schema(description = "여행 상세 조회") + public ApiResponse getTripDetail( + @WithUserContext(required = false) UserContext userContext, + @PathVariable UUID tripId) { + + UUID memberId = (userContext != null) ? userContext.memberId() : null; + + TripDetailResponse tripDetail = getTripUseCase.getTripDetail(memberId, tripId); return ApiResponse.ok(tripDetail); }