Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feature/74: isScrap 필드 추가 #77

Merged
merged 3 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions src/main/java/briefing/briefing/api/BriefingApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@
import briefing.briefing.application.dto.*;
import briefing.briefing.domain.BriefingType;
import java.time.LocalDate;
import java.util.Optional;

import briefing.common.response.CommonResponse;
import briefing.member.domain.Member;
import briefing.scrap.application.ScrapQueryService;
import briefing.security.handler.annotation.AuthMember;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
Expand All @@ -27,6 +33,7 @@ public class BriefingApi {

private final BriefingQueryService briefingQueryService;
private final BriefingCommandService briefingCommandService;
private final ScrapQueryService scrapQueryService;

@GetMapping
public CommonResponse<BriefingResponseDTO.BriefingPreviewListDTO> findBriefings(
Expand All @@ -37,8 +44,14 @@ public CommonResponse<BriefingResponseDTO.BriefingPreviewListDTO> findBriefings(
}

@GetMapping("/{id}")
public CommonResponse<BriefingResponseDTO.BriefingDetailDTO> findBriefing(@PathVariable final Long id) {
return CommonResponse.onSuccess(BriefingConverter.toBriefingDetailDTO(briefingQueryService.findBriefing(id)));
@Parameter(name = "member", hidden = true)
public CommonResponse<BriefingResponseDTO.BriefingDetailDTO> findBriefing(@PathVariable final Long id, @AuthMember Member member) {

Boolean isScrap = Optional.ofNullable(member)
.map(m -> scrapQueryService.existsByMemberIdAndBriefingId(m.getId(), id))
.orElseGet(() -> Boolean.FALSE);

return CommonResponse.onSuccess(BriefingConverter.toBriefingDetailDTO(briefingQueryService.findBriefing(id), isScrap));
}

@PostMapping
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/briefing/briefing/api/BriefingConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static BriefingResponseDTO.ArticleResponseDTO toArticleResponseDTO(final
.build();
}

public static BriefingResponseDTO.BriefingDetailDTO toBriefingDetailDTO(Briefing briefing){
public static BriefingResponseDTO.BriefingDetailDTO toBriefingDetailDTO(Briefing briefing, Boolean isScrap){

List<BriefingResponseDTO.ArticleResponseDTO> articleResponseDTOList = briefing.getBriefingArticles().stream()
.map(article -> toArticleResponseDTO(article.getArticle())).toList();
Expand All @@ -54,6 +54,7 @@ public static BriefingResponseDTO.BriefingDetailDTO toBriefingDetailDTO(Briefing
.content(briefing.getContent())
.date(briefing.getCreatedAt().toLocalDate())
.articles(articleResponseDTOList)
.isScrap(isScrap)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public static class BriefingDetailDTO{
String content;
LocalDate date;
List<ArticleResponseDTO> articles;
Boolean isScrap;
}

@Builder
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/briefing/member/api/MemberApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.sql.Ref;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Tag(name = "02-Member \uD83D\uDC64",description = "사용자 관련 API")
@RestController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@ public class ScrapQueryService {
public List<Scrap> getScrapsByMemberId(Long memberId) {
return scrapRepository.findByMember_Id(memberId);
}


public Boolean existsByMemberIdAndBriefingId(Long memberId, Long briefingId) {
return scrapRepository.existsByMember_IdAndBriefing_Id(memberId, briefingId);
}
}
7 changes: 3 additions & 4 deletions src/main/java/briefing/security/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.sessionManagement(manage -> manage.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // Session 사용 안함
.formLogin(AbstractHttpConfigurer::disable) // form login 사용 안함
.httpBasic(AbstractHttpConfigurer::disable) // http basic 방식 사용 안함
// .authorizeHttpRequests(authorize -> authorize // lambda 방식
// //.requestMatchers(WHITE_LIST).permitAll()
// .anyRequest().authenticated()
// )
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/briefings/**").permitAll() // 모두 접근 가능합니다.
)
.exceptionHandling(exceptionHandling -> exceptionHandling
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.accessDeniedHandler(jwtAccessDeniedHandler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class JwtRequestFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
HttpServletRequest httpServletRequest = request;
String jwt = tokenProvider.resolveToken(httpServletRequest);

if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt, TokenProvider.TokenType.ACCESS)){

Authentication authentication = tokenProvider.getAuthentication(jwt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
import briefing.member.api.MemberConverter;
import briefing.member.application.MemberQueryService;
import briefing.member.domain.Member;
import briefing.security.provider.TokenProvider;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.core.MethodParameter;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
Expand All @@ -22,6 +25,7 @@ public class AuthUserArgumentResolver implements HandlerMethodArgumentResolver {


private final MemberQueryService memberQueryService;
private final TokenProvider tokenProvider;

@Override
public boolean supportsParameter(MethodParameter parameter) {
Expand All @@ -33,20 +37,24 @@ public boolean supportsParameter(MethodParameter parameter) {
return true;
}


/*
NOTE - 사용자 추출 방법 변경
기존) 스프링 시큐리티 컨텍스트에서 유저정보를 가져와 세팅해주었습니다.
현재) httpRequest의 authorization header에서 액세스 토큰을 가져와 사용자 정보를 반환합니다.
변경 배경)
permitAll()을 통해 인증 유무에 상관없이 제공되는 API에서 JwtRequestFilter까지 도달하지 않는 문제인해
authentication 객체가 세팅이 되지 않기 때문에 기존 방법으로는 토큰을 물고 있는 사용자라도 AuthMember를 통해 추출하면 null이 반환되었습니다.
*/
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Object principal = null;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication != null) {
principal = authentication.getPrincipal();
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
String jwt = tokenProvider.resolveToken(request);
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt, TokenProvider.TokenType.ACCESS)) {
// 토큰에서 사용자 ID (subject) 추출
String userId = tokenProvider.getAuthentication(jwt).getName();
return memberQueryService.findById(Long.valueOf(userId));
}
if (principal == null || principal.getClass() == String.class) {
throw new MemberException(ErrorCode.MEMBER_NOT_FOUND);
}

UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) authentication;
Member member = memberQueryService.findById(Long.valueOf(authenticationToken.getName()));
return member;
return null; // 토큰이 없거나 유효하지 않은 경우
}
}
Loading