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

Member Entity 변경 (개인정보 처리방침 동의 컬럼 추가) #58

Merged
merged 4 commits into from
Mar 26, 2024
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
11 changes: 11 additions & 0 deletions src/main/java/com/gamemoonchul/application/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
import com.gamemoonchul.config.oauth.user.OAuth2Provider;
import com.gamemoonchul.domain.converter.MemberConverter;
import com.gamemoonchul.domain.entity.Member;
import com.gamemoonchul.domain.enums.MemberRole;
import com.gamemoonchul.domain.status.MemberStatus;
import com.gamemoonchul.infrastructure.repository.MemberRepository;
import com.gamemoonchul.infrastructure.web.dto.MemberResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -66,4 +68,13 @@ public MemberResponseDto me(Optional<Member> member) {

return response;
}

public MemberResponseDto privacyAgree(Member member) {
member.setPrivacyAgreed(true);
member.setPrivacyAgreedAt(LocalDateTime.now());
member.setRole(MemberRole.USER);
Member result = memberRepository.save(member);
MemberResponseDto response = memberConverter.toResponseDto(result);
return response;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.gamemoonchul.config.oauth.handler.OAuth2AuthenticationFailureHandler;
import com.gamemoonchul.config.oauth.handler.OAuth2AuthenticationSuccessHandler;
import com.gamemoonchul.config.oauth.service.CustomOAuth2UserService;
import com.gamemoonchul.domain.enums.MemberRole;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
Expand Down Expand Up @@ -54,8 +55,11 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.permitAll()
.requestMatchers(EXCEPTION.toArray(new String[0]))
.permitAll()
.anyRequest()
.authenticated()
.requestMatchers("/api/**")
.hasAnyRole("USER")
.requestMatchers("/privacy/**")
.hasAnyRole("PRIVACY_NOT_AGREED", "USER")
.anyRequest().authenticated();
;
})
.csrf(AbstractHttpConfigurer::disable)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
package com.gamemoonchul.config.jwt;

import com.gamemoonchul.config.oauth.user.OAuth2Provider;
import com.gamemoonchul.domain.entity.Member;
import com.gamemoonchul.infrastructure.repository.MemberRepository;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;

@RequiredArgsConstructor
@Component
public class JwtAuthorizationFilter extends OncePerRequestFilter {

private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String BEARER_PREFIX = "Bearer ";
private final TokenHelper tokenProvider;
private final TokenHelper tokenHelper;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

String token = resolveToken(request);

if (StringUtils.hasText(token) && tokenProvider.validateToken(token, TokenType.ACCESS)) {
Authentication authentication = tokenProvider.getAuthentication(token);
if (StringUtils.hasText(token) && tokenHelper.validateToken(token, TokenType.ACCESS)) {
Authentication authentication = tokenHelper.getAuthentication(token);
request.setAttribute("tokenInfo", authentication.getPrincipal());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
Expand All @@ -44,4 +52,6 @@ private String resolveToken(HttpServletRequest request) {

return null;
}


}
25 changes: 20 additions & 5 deletions src/main/java/com/gamemoonchul/config/jwt/TokenHelper.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.gamemoonchul.config.jwt;

import com.gamemoonchul.common.exception.ApiException;
import com.gamemoonchul.config.oauth.user.OAuth2Provider;
import com.gamemoonchul.config.oauth.user.OAuth2UserInfo;
import com.gamemoonchul.domain.entity.Member;
import com.gamemoonchul.infrastructure.repository.MemberRepository;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
Expand All @@ -12,13 +15,12 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

import java.security.Key;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.*;

@Slf4j
@RequiredArgsConstructor
Expand All @@ -30,6 +32,8 @@ public class TokenHelper {

@Value("${jwt.secret}")
private String secret;

private final MemberRepository memberRepository;
private Key key;

@PostConstruct
Expand Down Expand Up @@ -105,7 +109,18 @@ public Authentication getAuthentication(String token) {
// pricipal : 사용자의 세부 정보
// credentials : 사용자의 비밀번호
// authorities : 사용자의 권한 정보
return new UsernamePasswordAuthenticationToken(getTokenInfo(token), "", Collections.emptyList());
return new UsernamePasswordAuthenticationToken(getTokenInfo(token), "", getAuthorities(token));
}

private Collection<GrantedAuthority> getAuthorities(String token) {
Collection<GrantedAuthority> authorities = new ArrayList<>();
TokenInfo tokenInfo = getTokenInfo(token);
Optional<Member> member = memberRepository.findTop1ByEmailAndProviderAndIdentifier(tokenInfo.email(), OAuth2Provider.valueOf(tokenInfo.provider()), tokenInfo.identifier());
if (member.isPresent()) {
authorities.add(new SimpleGrantedAuthority(member.get().getRole().getKey()));

}
return authorities;
}

public TokenInfo getTokenInfo(String token) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ public static Member toEntity(OAuth2UserInfo userInfo) {
nickname = Optional.of(randomNickname());
}
Member member = Member.builder()
.role(MemberRole.USER)
.role(MemberRole.PRIVACY_NOT_AGREED)
.name(userInfo.getName())
.identifier(userInfo.getIdentifier())
.provider(userInfo.getProvider())
.nickname(
nickname.get()
)
.privacyAgreed(false)
.privacyAgreedAt(null)
.score(0.0)
.email(userInfo
.getEmail())
Expand All @@ -43,11 +45,13 @@ public static Member toEntity(OAuth2UserInfo userInfo) {

public static Member toEntity(AppleCredential userInfo) {
Member member = Member.builder()
.role(MemberRole.USER)
.role(MemberRole.PRIVACY_NOT_AGREED)
.name(userInfo.getName())
.identifier(userInfo.getSub()).provider(OAuth2Provider.APPLE)
.nickname(randomNickname())
.score(0.0)
.privacyAgreed(false)
.privacyAgreedAt(null)
.email(userInfo.getEmail())
.picture(null)
.birth(null)
Expand All @@ -60,6 +64,7 @@ public static MemberResponseDto toResponseDto(Member entity) {
.name(entity.getName())
.nickname(entity.getNickname())
.email(entity.getEmail())
.privacyAgreed(entity.isPrivacyAgreed())
.picture(entity.getPicture())
.score(entity.getScore())
.build();
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/gamemoonchul/domain/entity/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public class Member extends BaseTimeEntity {

private String picture;

@Column(name = "privacy_agreed",nullable = false)
private boolean privacyAgreed;

@Column(name = "privacy_agreed_at")
private LocalDateTime privacyAgreedAt;

@Column(nullable = false)
private Double score;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
public enum MemberRole {
ADMIN("ROLE_ADMIN", "관리자"),
USER("ROLE_USER","사용자"),
PRIVACY_NOT_AGREED("ROLE_PRIVACY_NOT_AGREED","개인정보 미동의 사용자");
;
private final String key;
private final String description;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.gamemoonchul.infrastructure;

import com.gamemoonchul.application.MemberService;
import com.gamemoonchul.common.annotation.MemberSession;
import com.gamemoonchul.domain.entity.Member;
import com.gamemoonchul.infrastructure.web.common.RestControllerWithEnvelopPattern;
import com.gamemoonchul.infrastructure.web.dto.MemberResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@RequiredArgsConstructor
@RestControllerWithEnvelopPattern
@RequestMapping("/privacy")
public class MemberPrivacyController {
private final MemberService memberService;

@PatchMapping("/agree")
public MemberResponseDto agreePrivacy(@MemberSession Member member) {
return memberService.privacyAgree(member);
}

@GetMapping("/is-agreed")
public boolean isAgreedPrivacy(@MemberSession Member member) {
return member.isPrivacyAgreed();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ public class MemberResponseDto {
private String nickname;
private String email;
private String picture;
private boolean privacyAgreed;
private Double score;
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,6 @@ void meFailTest() throws Exception {
ResultActions resultActions = super.mvc.perform(get("/api/member/me").header("Authorization", "Bearer " + accessToken));

// then
resultActions.andExpect(status().isBadRequest()).andExpect(jsonPath("$.status.statusCode").value(MemberStatus.MEMBER_NOT_FOUND.getStatusCode()));
resultActions.andExpect(status().isForbidden());
}
}
Loading