From f2d58389e5d84353df8bdfbbb11907053caa969a Mon Sep 17 00:00:00 2001 From: wuseong Date: Thu, 8 Feb 2024 18:18:14 +0900 Subject: [PATCH 01/16] =?UTF-8?q?refactor:=20=EC=97=85=EB=AC=B4=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20enum=EC=97=90=20value=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=ED=95=98=EC=97=AC=20=EC=9A=94=EC=B2=AD/?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/converter/UserConverter.java | 14 ++----- .../user/dto/EnumInquiryResponseDTO.java | 2 +- .../onnoff/domain/user/enums/FieldOfWork.java | 37 ++++++++++++++++--- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/onnoff/onnoff/domain/user/converter/UserConverter.java b/src/main/java/com/onnoff/onnoff/domain/user/converter/UserConverter.java index 5074078..a09d324 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/converter/UserConverter.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/converter/UserConverter.java @@ -14,26 +14,20 @@ public class UserConverter { public static User toUser(KakaoOauth2DTO.UserInfoResponseDTO response, LoginRequestDTO.AdditionalInfo additionalInfo){ - String fieldOfWork = additionalInfo.getFieldOfWork(); - try{ - FieldOfWork.valueOf(fieldOfWork); - } - catch (IllegalArgumentException e){ - throw new GeneralException(ErrorStatus.INVALID_ENUM_VALUE); - } - + FieldOfWork fieldOfWork = FieldOfWork.fromValue(additionalInfo.getFieldOfWork()); ExperienceYear experienceYear = ExperienceYear.fromValue(additionalInfo.getExperienceYear()); return User.builder() .oauthId(response.getSub()) .email(response.getEmail()) .name(response.getNickname()) .socialType(SocialType.KAKAO) - .fieldOfWork(Enum.valueOf(FieldOfWork.class ,additionalInfo.getFieldOfWork() ) ) + .fieldOfWork(fieldOfWork) .job(additionalInfo.getJob()) .experienceYear(experienceYear) .build(); } public static User toUser(LoginRequestDTO.AppleTokenValidateDTO request, LoginRequestDTO.AdditionalInfo additionalInfo){ + FieldOfWork fieldOfWork = FieldOfWork.fromValue(additionalInfo.getFieldOfWork()); ExperienceYear experienceYear = ExperienceYear.fromValue(additionalInfo.getExperienceYear()); String fullName = request.getFullName().getFamilyName() + request.getFullName().getGivenName(); return User.builder() @@ -41,7 +35,7 @@ public static User toUser(LoginRequestDTO.AppleTokenValidateDTO request, LoginRe .email(request.getEmail()) .name(fullName) .socialType(SocialType.APPLE) - .fieldOfWork(Enum.valueOf(FieldOfWork.class ,additionalInfo.getFieldOfWork() ) ) + .fieldOfWork(fieldOfWork) .job(additionalInfo.getJob()) .experienceYear(experienceYear) .build(); diff --git a/src/main/java/com/onnoff/onnoff/domain/user/dto/EnumInquiryResponseDTO.java b/src/main/java/com/onnoff/onnoff/domain/user/dto/EnumInquiryResponseDTO.java index 830d50f..362cd11 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/dto/EnumInquiryResponseDTO.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/dto/EnumInquiryResponseDTO.java @@ -12,7 +12,7 @@ public class EnumInquiryResponseDTO { public static class FieldOfWorkResponseDTO{ public static List getAllField() { return Arrays.stream(FieldOfWork.values()) - .map(Enum::name) + .map(FieldOfWork::getValue) .collect(Collectors.toList()); } } diff --git a/src/main/java/com/onnoff/onnoff/domain/user/enums/FieldOfWork.java b/src/main/java/com/onnoff/onnoff/domain/user/enums/FieldOfWork.java index 18a356c..e769733 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/enums/FieldOfWork.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/enums/FieldOfWork.java @@ -1,15 +1,40 @@ package com.onnoff.onnoff.domain.user.enums; +import com.onnoff.onnoff.apiPayload.code.status.ErrorStatus; +import com.onnoff.onnoff.apiPayload.exception.GeneralException; import lombok.AllArgsConstructor; +import lombok.Getter; @AllArgsConstructor +@Getter public enum FieldOfWork { - 서비스업, 의료_제약_복지, 제조_화학, - 판매_유통, IT_웹_통신, 건설업, - 교육업, 미디어_디자인, 은행_금융업, - 기관_협회, 비즈니스_투자, 물류_무역업, - 법률_법집행기관, 방송_광고_엔터테인먼트, 여행_숙박_음식점업, - 부동산_임대업 + 서비스업("서비스업"), + 의료_제약_복지("의료•제약•복지"), + 제조_화학("제조•화학"), + 판매_유통("판매•유통"), + IT_웹_통신("IT•웹•통신"), + 건설업("건설업"), + 교육업("교육업"), + 미디어_디자인("미디어•디자인"), + 은행_금융업("은행•금융업"), + 기관_협회("기관•협회"), + 비즈니스_투자("비즈니스•투자"), + 물류_무역업("물류•무역업"), + 법률_법집행기관("법률•법집행기관"), + 방송_광고_엔터테인먼트("방송•광고•엔터테인먼트"), + 여행_숙박_음식점업("여행•숙박•음식점업"), + 부동산_임대업("부동산•임대업"); + + private final String value; + + public static FieldOfWork fromValue(String value) { + for (FieldOfWork fieldOfWork : FieldOfWork.values()) { + if (fieldOfWork.getValue().equals(value)) { + return fieldOfWork; + } + } + throw new GeneralException(ErrorStatus.INVALID_ENUM_VALUE); + } } From b37eb093660e19ef6b6cc908b057b6b09668da8d Mon Sep 17 00:00:00 2001 From: wuseong Date: Fri, 9 Feb 2024 00:24:26 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20=EC=B6=94=EA=B0=80=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20DTO=EC=97=90=20=EB=8B=89=EB=84=A4=EC=9E=84=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 --- src/main/java/com/onnoff/onnoff/auth/dto/LoginRequestDTO.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/onnoff/onnoff/auth/dto/LoginRequestDTO.java b/src/main/java/com/onnoff/onnoff/auth/dto/LoginRequestDTO.java index 9b78e65..4afcf06 100644 --- a/src/main/java/com/onnoff/onnoff/auth/dto/LoginRequestDTO.java +++ b/src/main/java/com/onnoff/onnoff/auth/dto/LoginRequestDTO.java @@ -23,6 +23,7 @@ public static class KakaoTokenValidateDTO{ @Getter public static class AdditionalInfo{ + private String nickname; private String fieldOfWork; private String job; private String experienceYear; From 744fbd378a965f27782a6fe6eaf09da388abb891 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 19:02:26 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=20=EC=99=84?= =?UTF-8?q?=EC=A0=84=20=ED=83=88=ED=87=B4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1,=20=EA=B7=BC=EB=8D=B0=20=EC=88=9C=ED=99=98?= =?UTF-8?q?=EC=B0=B8=EC=A1=B0=20=EC=98=A4=EB=A5=98=EB=95=9C=EC=97=90=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=AA=BB=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/service/UserServiceImplTest.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/onnoff/onnoff/domain/user/service/UserServiceImplTest.java b/src/test/java/com/onnoff/onnoff/domain/user/service/UserServiceImplTest.java index 76268a5..658f7aa 100644 --- a/src/test/java/com/onnoff/onnoff/domain/user/service/UserServiceImplTest.java +++ b/src/test/java/com/onnoff/onnoff/domain/user/service/UserServiceImplTest.java @@ -1,5 +1,8 @@ package com.onnoff.onnoff.domain.user.service; +import com.onnoff.onnoff.apiPayload.code.status.ErrorStatus; +import com.onnoff.onnoff.apiPayload.exception.GeneralException; +import com.onnoff.onnoff.auth.UserContext; import com.onnoff.onnoff.domain.user.User; import jakarta.transaction.Transactional; import org.assertj.core.api.Assertions; @@ -7,13 +10,18 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import static org.junit.jupiter.api.Assertions.assertThrows; @SpringBootTest @Transactional class UserServiceImplTest { - @Autowired UserService userService; + private final UserService userService; + + public UserServiceImplTest(@Autowired UserService userService) { + this.userService = userService; + } @Test void 생성_및_조회() { User user = User.builder().name("우성").nickname("우스").build(); @@ -24,5 +32,21 @@ class UserServiceImplTest { Assertions.assertThat(user.getName()).isEqualTo(findUser.getName()); } + @Test + void 회원탈퇴() { + // 유저가 회원가입을 했고 id가 6인 상황 + + //유저 id 6인 사용자가 회원탈퇴 버튼 누름 + User user = userService.getUser(6l); + user.setUserStatusInactive(); + //한달 후에 hard delete + userService.deleteInactiveUsers(); + // 삭제 됐는지 확인 + GeneralException exception = assertThrows(GeneralException.class, () -> { + userService.getUser(6l); + }); + Assertions.assertThat(ErrorStatus.USER_NOT_FOUND).isEqualTo(exception.getCode()); + // 카카오톡 들어가서 연결된 앱에서 해지 됐는지도 확인 + } } \ No newline at end of file From 6dd0d07eb29ff0c48115106f906b19cbe574f713 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 19:08:21 +0900 Subject: [PATCH 04/16] =?UTF-8?q?refactor:=20WebConfig,=20JwtAuthFilter=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EA=B5=AC=EC=A1=B0=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onnoff/auth/config/FilterConfig.java | 28 +++++++++++++++++++ .../onnoff/onnoff/auth/config/WebConfig.java | 12 +++----- .../onnoff/auth/jwt/filter/JwtAuthFilter.java | 7 ++--- .../auth/jwt/service/JwtTokenProvider.java | 2 +- .../auth/jwt/service/TokenProvider.java | 5 ++++ 5 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/onnoff/onnoff/auth/config/FilterConfig.java create mode 100644 src/main/java/com/onnoff/onnoff/auth/jwt/service/TokenProvider.java diff --git a/src/main/java/com/onnoff/onnoff/auth/config/FilterConfig.java b/src/main/java/com/onnoff/onnoff/auth/config/FilterConfig.java new file mode 100644 index 0000000..9a66ac2 --- /dev/null +++ b/src/main/java/com/onnoff/onnoff/auth/config/FilterConfig.java @@ -0,0 +1,28 @@ +package com.onnoff.onnoff.auth.config; + +import com.onnoff.onnoff.auth.jwt.filter.JwtAuthFilter; +import com.onnoff.onnoff.auth.jwt.filter.UserInterceptor; +import com.onnoff.onnoff.auth.jwt.service.JwtUtil; +import com.onnoff.onnoff.auth.jwt.service.TokenProvider; +import com.onnoff.onnoff.domain.user.service.UserService; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RequiredArgsConstructor +public class FilterConfig { + private final TokenProvider tokenProvider; + private final UserService userService; + private final JwtUtil jwtUtil; + + @Bean + public JwtAuthFilter jwtAuthFilter() { + return new JwtAuthFilter(tokenProvider); + } + + @Bean + public UserInterceptor userInterceptor() { + return new UserInterceptor(userService, jwtUtil); + } +} \ No newline at end of file diff --git a/src/main/java/com/onnoff/onnoff/auth/config/WebConfig.java b/src/main/java/com/onnoff/onnoff/auth/config/WebConfig.java index d123b8a..6a8f20b 100644 --- a/src/main/java/com/onnoff/onnoff/auth/config/WebConfig.java +++ b/src/main/java/com/onnoff/onnoff/auth/config/WebConfig.java @@ -3,9 +3,6 @@ import com.onnoff.onnoff.auth.jwt.filter.JwtAuthFilter; import com.onnoff.onnoff.auth.jwt.filter.UserInterceptor; -import com.onnoff.onnoff.auth.jwt.service.JwtTokenProvider; -import com.onnoff.onnoff.auth.jwt.service.JwtUtil; -import com.onnoff.onnoff.domain.user.service.UserService; import jakarta.persistence.EntityManagerFactory; import lombok.RequiredArgsConstructor; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -18,14 +15,13 @@ @Configuration @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { - private final JwtTokenProvider jwtTokenProvider; - private final JwtUtil jwtUtil; - private final UserService userService; + private final JwtAuthFilter jwtAuthFilter; private final EntityManagerFactory entityManagerFactory; + private final UserInterceptor userInterceptor; @Bean public FilterRegistrationBean jwtFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean<>(); - registration.setFilter(new JwtAuthFilter(jwtTokenProvider)); // 필터 인스턴스 설정 + registration.setFilter(jwtAuthFilter); // 필터 인스턴스 설정 registration.addUrlPatterns("/*"); //서블릿 컨택스트에서 /*는 모든 요청, /**는 인식되지 않음 registration.setOrder(1); // 필터의 순서 설정. 값이 낮을수록 먼저 실행 return registration; @@ -37,7 +33,7 @@ public void addInterceptors(InterceptorRegistry registry) { openEntityManagerInViewInterceptor.setEntityManagerFactory(entityManagerFactory); registry.addWebRequestInterceptor(openEntityManagerInViewInterceptor); - registry.addInterceptor(new UserInterceptor(userService, jwtUtil)) + registry.addInterceptor(userInterceptor) .addPathPatterns("/**") // 스프링 경로는 /*와 /**이 다름 .excludePathPatterns("/swagger-ui/**", "/v3/api-docs/**", "/oauth2/**", "/health", "/token/**" , "/message/**", "/enums/**"); diff --git a/src/main/java/com/onnoff/onnoff/auth/jwt/filter/JwtAuthFilter.java b/src/main/java/com/onnoff/onnoff/auth/jwt/filter/JwtAuthFilter.java index f6da287..1a9a45c 100644 --- a/src/main/java/com/onnoff/onnoff/auth/jwt/filter/JwtAuthFilter.java +++ b/src/main/java/com/onnoff/onnoff/auth/jwt/filter/JwtAuthFilter.java @@ -8,7 +8,7 @@ */ -import com.onnoff.onnoff.auth.jwt.service.JwtTokenProvider; +import com.onnoff.onnoff.auth.jwt.service.TokenProvider; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -16,7 +16,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; -import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; @@ -24,7 +23,7 @@ @Slf4j @RequiredArgsConstructor public class JwtAuthFilter extends OncePerRequestFilter { - private final JwtTokenProvider jwtTokenProvider; + private final TokenProvider tokenProvider; private final static String[] ignorePrefix = {"/swagger-ui", "/v3/api-docs", "/oauth2", "/health", "/token/validate" , "/message", "/enums"}; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { @@ -43,7 +42,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse if (authHeader != null && authHeader.startsWith("Bearer ")) { accessToken = authHeader.substring(7); } - if (jwtTokenProvider.verifyToken(accessToken)){ + if (tokenProvider.verifyToken(accessToken)){ log.info("인증성공"); filterChain.doFilter(request, response); } diff --git a/src/main/java/com/onnoff/onnoff/auth/jwt/service/JwtTokenProvider.java b/src/main/java/com/onnoff/onnoff/auth/jwt/service/JwtTokenProvider.java index 35226fd..dee3f7d 100644 --- a/src/main/java/com/onnoff/onnoff/auth/jwt/service/JwtTokenProvider.java +++ b/src/main/java/com/onnoff/onnoff/auth/jwt/service/JwtTokenProvider.java @@ -23,7 +23,7 @@ @Slf4j @Service @RequiredArgsConstructor -public class JwtTokenProvider { +public class JwtTokenProvider implements TokenProvider { @Value("${spring.jwt.secret}") private String secret; private SecretKey secretkey; diff --git a/src/main/java/com/onnoff/onnoff/auth/jwt/service/TokenProvider.java b/src/main/java/com/onnoff/onnoff/auth/jwt/service/TokenProvider.java new file mode 100644 index 0000000..f314a0b --- /dev/null +++ b/src/main/java/com/onnoff/onnoff/auth/jwt/service/TokenProvider.java @@ -0,0 +1,5 @@ +package com.onnoff.onnoff.auth.jwt.service; + +public interface TokenProvider { + boolean verifyToken(String token); +} From 924365bd62ab39956551137b34fd2a85d67f3909 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 19:09:26 +0900 Subject: [PATCH 05/16] =?UTF-8?q?feat:=20socialType=20=EB=B0=9B=EC=95=84?= =?UTF-8?q?=EC=84=9C=20=ED=8C=90=EB=8B=A8=ED=95=98=EB=8A=94=20=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/onnoff/onnoff/domain/user/enums/SocialType.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/onnoff/onnoff/domain/user/enums/SocialType.java b/src/main/java/com/onnoff/onnoff/domain/user/enums/SocialType.java index c2fe68b..9668375 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/enums/SocialType.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/enums/SocialType.java @@ -1,5 +1,9 @@ package com.onnoff.onnoff.domain.user.enums; public enum SocialType { - KAKAO, APPLE + KAKAO, APPLE; + + public static boolean isApple(SocialType socialType){ + return socialType.equals(SocialType.APPLE); + } } From b7610e6ddb1b8621705df85683921d83dd5deaef Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 21:11:14 +0900 Subject: [PATCH 06/16] =?UTF-8?q?feat:=20=EC=86=8C=EC=85=9C=EA=B3=84?= =?UTF-8?q?=EC=A0=95=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=97=B0=EB=8F=99?= =?UTF-8?q?=ED=95=B4=EC=A7=80=20=EB=B0=8F=20=ED=86=A0=ED=81=B0=EB=A7=8C?= =?UTF-8?q?=EB=A3=8C=20=EC=9A=94=EC=B2=AD=20API=20=EC=9A=94=EC=B2=AD=20DTO?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/apple/RevokeTokenReqeust.java | 28 +++++++++++++++++++ .../feignClient/dto/kakao/UnlinkRequest.java | 22 +++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/main/java/com/onnoff/onnoff/auth/feignClient/dto/apple/RevokeTokenReqeust.java create mode 100644 src/main/java/com/onnoff/onnoff/auth/feignClient/dto/kakao/UnlinkRequest.java diff --git a/src/main/java/com/onnoff/onnoff/auth/feignClient/dto/apple/RevokeTokenReqeust.java b/src/main/java/com/onnoff/onnoff/auth/feignClient/dto/apple/RevokeTokenReqeust.java new file mode 100644 index 0000000..1b94d4f --- /dev/null +++ b/src/main/java/com/onnoff/onnoff/auth/feignClient/dto/apple/RevokeTokenReqeust.java @@ -0,0 +1,28 @@ +package com.onnoff.onnoff.auth.feignClient.dto.apple; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +@Getter +@Builder +@AllArgsConstructor +public class RevokeTokenReqeust { + private String clientId; + private String clientSecret; + private String token; + private String tokenTypeHint; + + public MultiValueMap toUrlEncoded(){ + LinkedMultiValueMap urlEncoded = new LinkedMultiValueMap<>(); + urlEncoded.add("client_id", clientId); + urlEncoded.add("client_secret", clientSecret); + urlEncoded.add("token", token); + urlEncoded.add("token_type_hint", "refresh_token"); + return urlEncoded; + } +} diff --git a/src/main/java/com/onnoff/onnoff/auth/feignClient/dto/kakao/UnlinkRequest.java b/src/main/java/com/onnoff/onnoff/auth/feignClient/dto/kakao/UnlinkRequest.java new file mode 100644 index 0000000..bead91c --- /dev/null +++ b/src/main/java/com/onnoff/onnoff/auth/feignClient/dto/kakao/UnlinkRequest.java @@ -0,0 +1,22 @@ +package com.onnoff.onnoff.auth.feignClient.dto.kakao; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +@Builder +@AllArgsConstructor +public class UnlinkRequest { + private String targetIdType; + private String targetId; + + public MultiValueMap toUrlEncoded(){ + LinkedMultiValueMap urlEncoded = new LinkedMultiValueMap<>(); + urlEncoded.add("target_id_type", targetIdType); + urlEncoded.add("target_id", targetId); + return urlEncoded; + } +} From 1d472b5a71bafd22f60f80badd2271c3b322d704 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 21:14:06 +0900 Subject: [PATCH 07/16] =?UTF-8?q?feat:=20=EC=95=A0=ED=94=8C=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=EB=A7=8C=EB=A3=8C=20=EB=B0=8F=20=EC=95=B1=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99=20=ED=95=B4=EC=A7=80=20=EC=9A=94=EC=B2=AD=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onnoff/auth/service/AppleLoginService.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/onnoff/onnoff/auth/service/AppleLoginService.java b/src/main/java/com/onnoff/onnoff/auth/service/AppleLoginService.java index 725a037..ee75b40 100644 --- a/src/main/java/com/onnoff/onnoff/auth/service/AppleLoginService.java +++ b/src/main/java/com/onnoff/onnoff/auth/service/AppleLoginService.java @@ -3,6 +3,7 @@ import com.onnoff.onnoff.auth.UserContext; import com.onnoff.onnoff.auth.feignClient.client.AppleAuthClient; +import com.onnoff.onnoff.auth.feignClient.dto.apple.RevokeTokenReqeust; import com.onnoff.onnoff.auth.feignClient.dto.apple.TokenRequest; import com.onnoff.onnoff.auth.feignClient.dto.TokenResponse; import com.onnoff.onnoff.auth.service.tokenValidator.SocialTokenValidator; @@ -27,8 +28,6 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Date; -import java.util.HashMap; -import java.util.Map; @Service @RequiredArgsConstructor @@ -116,4 +115,15 @@ public void validate(String identityToken){ String cleanedIdentityToken = cleanToken(identityToken); validator.validate(cleanedIdentityToken, SocialType.APPLE); } + + public void revokeTokens(String refreshToken) { + String clientSecret = createClientSecret(); + MultiValueMap urlEncoded = RevokeTokenReqeust.builder() + .clientId(clientId) + .clientSecret(clientSecret) + .token(refreshToken) + .build().toUrlEncoded(); + appleAuthClient.revokeTokens(urlEncoded); + } + } From 61e079ada32d0e051c13c9530aa871deae31f0e1 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 21:15:13 +0900 Subject: [PATCH 08/16] =?UTF-8?q?feat:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=EB=A7=8C=EB=A3=8C=20=EB=B0=8F=20=EC=95=B1=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=20=ED=95=B4=EC=A7=80=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/service/KakaoLoginService.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/onnoff/onnoff/auth/service/KakaoLoginService.java b/src/main/java/com/onnoff/onnoff/auth/service/KakaoLoginService.java index 7d3fa77..314fc14 100644 --- a/src/main/java/com/onnoff/onnoff/auth/service/KakaoLoginService.java +++ b/src/main/java/com/onnoff/onnoff/auth/service/KakaoLoginService.java @@ -6,12 +6,15 @@ import com.onnoff.onnoff.auth.feignClient.client.KakaoOauth2Client; import com.onnoff.onnoff.auth.feignClient.dto.TokenResponse; import com.onnoff.onnoff.auth.feignClient.dto.kakao.KakaoOauth2DTO; +import com.onnoff.onnoff.auth.feignClient.dto.kakao.UnlinkRequest; import com.onnoff.onnoff.auth.service.tokenValidator.SocialTokenValidator; import com.onnoff.onnoff.domain.user.enums.SocialType; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.util.MultiValueMap; @Service @@ -25,6 +28,8 @@ public class KakaoLoginService implements LoginService{ private String clientId; @Value("${kakao.redirect-uri}") private String redirectUri; + @Value("${kakao.admin-key}") + private String adminKey; /* 테스트 용으로 만든거, 실제로는 프론트에서 처리해서 액세스 토큰만 가져다 줌 */ @@ -41,9 +46,22 @@ public void validate(String idToken){ String cleanedAccessToken = cleanToken(idToken); validator.validate(cleanedAccessToken, SocialType.KAKAO); } - /* - 토큰으로 유저정보를 가져오는 메서드 - */ + + public void revokeTokens(String oauthId) { + MultiValueMap urlEncoded = UnlinkRequest.builder() + .targetIdType("user_id") + .targetId(oauthId) + .build() + .toUrlEncoded(); + adminKey = "KakaoAK " + adminKey; + log.info("adminkey = {}", adminKey); + ResponseEntity responseEntity = kakaoApiClient.unlink(adminKey, urlEncoded); + log.info("삭제된 회원 정보 = {}", responseEntity.getBody()); + } + + /* + 토큰으로 유저정보를 가져오는 메서드 + */ public KakaoOauth2DTO.UserInfoResponseDTO getUserInfo(String accessToken) throws JsonProcessingException { String cleanedAccessToken = cleanToken(accessToken); accessToken = "bearer " + cleanedAccessToken; From 4781b876ccd50100164fdb3f0f87025d577ed3d0 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 21:16:46 +0900 Subject: [PATCH 09/16] =?UTF-8?q?feat:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20api?= =?UTF-8?q?=20=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8=ED=8A=B8=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=EB=81=8A=EA=B8=B0=20=EC=9A=94=EC=B2=AD=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onnoff/auth/feignClient/client/KakaoApiClient.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/onnoff/onnoff/auth/feignClient/client/KakaoApiClient.java b/src/main/java/com/onnoff/onnoff/auth/feignClient/client/KakaoApiClient.java index 7a5a304..76c423f 100644 --- a/src/main/java/com/onnoff/onnoff/auth/feignClient/client/KakaoApiClient.java +++ b/src/main/java/com/onnoff/onnoff/auth/feignClient/client/KakaoApiClient.java @@ -3,8 +3,11 @@ import com.onnoff.onnoff.auth.feignClient.config.FeignConfig; import com.onnoff.onnoff.auth.feignClient.dto.kakao.KakaoOauth2DTO; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.Map; + /* 토큰 유효성 검증 하고 사용자 정보 가져오는 client */ @@ -15,5 +18,7 @@ public interface KakaoApiClient { KakaoOauth2DTO.TokenValidateResponseDTO getTokenValidate(@RequestHeader("Authorization") String accessToken); @GetMapping(value = "/v1/oidc/userinfo") KakaoOauth2DTO.UserInfoResponseDTO getUserInfo(@RequestHeader("Authorization") String accessToken); + @PostMapping(value = "/v1/user/unlink", consumes = "application/x-www-form-urlencoded") + ResponseEntity unlink(@RequestHeader("Authorization") String adminKey, @RequestBody Map requestBody); } From ced901bb9bbfc28bba129331dd8977850ebb0187 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 21:18:20 +0900 Subject: [PATCH 10/16] =?UTF-8?q?feat:=20=EC=95=A0=ED=94=8C=20auth=20?= =?UTF-8?q?=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8=ED=8A=B8=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=ED=8F=90=EA=B8=B0=20=EC=9A=94=EC=B2=AD=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onnoff/auth/feignClient/client/AppleAuthClient.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/onnoff/onnoff/auth/feignClient/client/AppleAuthClient.java b/src/main/java/com/onnoff/onnoff/auth/feignClient/client/AppleAuthClient.java index 165d31d..998cbd3 100644 --- a/src/main/java/com/onnoff/onnoff/auth/feignClient/client/AppleAuthClient.java +++ b/src/main/java/com/onnoff/onnoff/auth/feignClient/client/AppleAuthClient.java @@ -1,9 +1,11 @@ package com.onnoff.onnoff.auth.feignClient.client; +import com.onnoff.onnoff.auth.feignClient.config.FeignConfig; import com.onnoff.onnoff.auth.feignClient.dto.JwkResponse; import com.onnoff.onnoff.auth.feignClient.dto.TokenResponse; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.context.annotation.Lazy; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -11,7 +13,7 @@ import java.util.Map; -@FeignClient(name = "apple-auth-client",url = "https://appleid.apple.com/auth") +@FeignClient(name = "apple-auth-client",url = "https://appleid.apple.com/auth", configuration = FeignConfig.class) public interface AppleAuthClient{ @GetMapping("/keys") JwkResponse.JwkSet getKeys(); @@ -20,6 +22,6 @@ public interface AppleAuthClient{ TokenResponse getToken(@RequestBody Map requestBody); //회원 탈퇴 메서드 -// @GetMapping("/revoke") -// KakaoOauth2DTO.TokenValidateResponseDTO getTokenValidate(@RequestHeader("Authorization") String accessToken); + @GetMapping("/oauth2/v2/revoke") + void revokeTokens(@RequestBody Map requestBody); } From bf9cd14d0377e1b880bdad07d4df456b0fc2aa1b Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 21:20:38 +0900 Subject: [PATCH 11/16] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20hard=20delet?= =?UTF-8?q?e=20=EB=A9=94=EC=84=9C=EB=93=9C=EC=97=90=20=EC=95=B1=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=ED=95=B4=EC=A7=80/=ED=86=A0=ED=81=B0?= =?UTF-8?q?=ED=8F=90=EA=B8=B0=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/service/UserService.java | 3 ++- .../domain/user/service/UserServiceImpl.java | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/onnoff/onnoff/domain/user/service/UserService.java b/src/main/java/com/onnoff/onnoff/domain/user/service/UserService.java index a459cdf..4ecbd24 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/service/UserService.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/service/UserService.java @@ -2,7 +2,6 @@ import com.onnoff.onnoff.domain.user.User; import com.onnoff.onnoff.domain.user.dto.UserRequestDTO; -import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -18,5 +17,7 @@ public interface UserService { public User getUserByOauthId(String oauthId); public User withdrawUser(); + + public void deleteInactiveUsers(); public User modifyUser(UserRequestDTO.ModifyUserDTO modifyUserDTO); } diff --git a/src/main/java/com/onnoff/onnoff/domain/user/service/UserServiceImpl.java b/src/main/java/com/onnoff/onnoff/domain/user/service/UserServiceImpl.java index 58000a9..c3fe975 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/service/UserServiceImpl.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/service/UserServiceImpl.java @@ -3,8 +3,11 @@ import com.onnoff.onnoff.apiPayload.code.status.ErrorStatus; import com.onnoff.onnoff.apiPayload.exception.GeneralException; import com.onnoff.onnoff.auth.UserContext; +import com.onnoff.onnoff.auth.service.AppleLoginService; +import com.onnoff.onnoff.auth.service.KakaoLoginService; import com.onnoff.onnoff.domain.user.User; import com.onnoff.onnoff.domain.user.dto.UserRequestDTO; +import com.onnoff.onnoff.domain.user.enums.SocialType; import com.onnoff.onnoff.domain.user.enums.Status; import com.onnoff.onnoff.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; @@ -19,6 +22,10 @@ @RequiredArgsConstructor public class UserServiceImpl implements UserService{ private final UserRepository userRepository; + private final AppleLoginService appleLoginService; + private final KakaoLoginService kakaoLoginService; + + @Transactional @Override public User create(User user) { @@ -59,7 +66,6 @@ public User getUserByOauthId(String oauthId) { public User withdrawUser(){ User user = UserContext.getUser(); user.setUserStatusInactive(); - userRepository.save(user); return user; } @@ -78,5 +84,19 @@ public void deleteInactiveUsers() { LocalDateTime oneMonthAgo = LocalDateTime.now().minusMonths(1); List inactiveUsers = userRepository.findByStatusAndInactiveDateBefore(Status.INACTIVE, oneMonthAgo); inactiveUsers.forEach(userRepository::delete); + inactiveUsers.forEach(this::disconnectApp); } + // 유저 소셜계정 앱 연동 해지 + private void disconnectApp(User user){ + SocialType socialType = user.getSocialType(); + if(SocialType.isApple(socialType)) { + String appleRefreshToken = user.getAppleRefreshToken(); + appleLoginService.revokeTokens(appleRefreshToken); + } + else { + String oauthId = user.getOauthId(); + kakaoLoginService.revokeTokens(oauthId); + } + } + } From 258c168b90e74857ee05de05203310f1bb057e97 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 21:22:51 +0900 Subject: [PATCH 12/16] =?UTF-8?q?refactor:=20WebConfig,=20JwtAuthFilter=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EA=B5=AC=EC=A1=B0=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onnoff/onnoff/auth/controller/LoginController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/onnoff/onnoff/auth/controller/LoginController.java b/src/main/java/com/onnoff/onnoff/auth/controller/LoginController.java index a3545d6..def695f 100644 --- a/src/main/java/com/onnoff/onnoff/auth/controller/LoginController.java +++ b/src/main/java/com/onnoff/onnoff/auth/controller/LoginController.java @@ -10,8 +10,8 @@ import com.onnoff.onnoff.auth.feignClient.dto.TokenResponse; import com.onnoff.onnoff.auth.feignClient.dto.kakao.KakaoOauth2DTO; import com.onnoff.onnoff.auth.jwt.dto.JwtToken; -import com.onnoff.onnoff.auth.jwt.service.JwtTokenProvider; import com.onnoff.onnoff.auth.jwt.service.JwtUtil; +import com.onnoff.onnoff.auth.jwt.service.TokenProvider; import com.onnoff.onnoff.auth.service.AppleLoginService; import com.onnoff.onnoff.auth.service.KakaoLoginService; import com.onnoff.onnoff.domain.user.User; @@ -34,7 +34,7 @@ public class LoginController { private final KakaoLoginService kakaoLoginService; private final AppleLoginService appleLoginService; private final UserService userService; - private final JwtTokenProvider jwtTokenProvider; + private final TokenProvider tokenProvider; private final JwtUtil jwtUtil; @Value("${kakao.redirect-uri}") @@ -135,14 +135,14 @@ public ApiResponse validateAppleToken(@RequestBody Log public ApiResponse validateServerToken(@RequestBody JwtToken tokenDTO){ String accessToken = tokenDTO.getAccessToken(); String refreshToken = tokenDTO.getRefreshToken(); - if( jwtTokenProvider.verifyToken(accessToken) ){ + if( tokenProvider.verifyToken(accessToken) ){ // accessToken 유효 String userId = jwtUtil.getUserId(accessToken); User user = userService.getUser(Long.valueOf(userId)); UserResponseDTO.LoginDTO loginDTO = UserConverter.toLoginDTO(accessToken, refreshToken); return ApiResponse.onSuccess(loginDTO); } - if (jwtTokenProvider.verifyToken(refreshToken)) { + if ( tokenProvider.verifyToken(refreshToken)) { //refreshToken 유효 String userId = jwtUtil.getUserId(refreshToken); User user = userService.getUser(Long.valueOf(userId)); From 299f6e3a543c6a462a0e1819e3fa691bb11a4a66 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 21:24:50 +0900 Subject: [PATCH 13/16] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=EC=99=84?= =?UTF-8?q?=EC=A0=84=20=ED=9A=8C=EC=9B=90=ED=83=88=ED=87=B4=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onnoff/domain/user/controller/UserController.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/com/onnoff/onnoff/domain/user/controller/UserController.java b/src/main/java/com/onnoff/onnoff/domain/user/controller/UserController.java index 397d155..d77677a 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/controller/UserController.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/controller/UserController.java @@ -35,4 +35,12 @@ public ApiResponse withdrawUser(){ public ApiResponse modifyUser(@RequestBody UserRequestDTO.ModifyUserDTO modifyUserDTO) { return ApiResponse.onSuccess(UserConverter.toUserDetailDTO(userService.modifyUser(modifyUserDTO))); } + + //테스트용 + @PutMapping("/hard-delete") + @Operation(summary = "회원 완전 탈퇴 테스트 API",description = "30일 뒤에 자동 완전삭제 수동 테스트") + public ApiResponse hardDeleteTest(){ + userService.deleteInactiveUsers() ; + return ApiResponse.onSuccess("삭제완"); + } } From 73cbb74583329b9b860a28d43dfb19b7a599a907 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sat, 10 Feb 2024 22:40:12 +0900 Subject: [PATCH 14/16] =?UTF-8?q?feat:=20=EC=95=A0=ED=94=8C=20auth=20clien?= =?UTF-8?q?t=20=ED=86=A0=ED=81=B0=20=ED=8F=90=EA=B8=B0=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onnoff/auth/feignClient/client/AppleAuthClient.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/onnoff/onnoff/auth/feignClient/client/AppleAuthClient.java b/src/main/java/com/onnoff/onnoff/auth/feignClient/client/AppleAuthClient.java index 998cbd3..45277f6 100644 --- a/src/main/java/com/onnoff/onnoff/auth/feignClient/client/AppleAuthClient.java +++ b/src/main/java/com/onnoff/onnoff/auth/feignClient/client/AppleAuthClient.java @@ -5,8 +5,6 @@ import com.onnoff.onnoff.auth.feignClient.dto.JwkResponse; import com.onnoff.onnoff.auth.feignClient.dto.TokenResponse; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.context.annotation.Lazy; -import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -22,6 +20,6 @@ public interface AppleAuthClient{ TokenResponse getToken(@RequestBody Map requestBody); //회원 탈퇴 메서드 - @GetMapping("/oauth2/v2/revoke") + @PostMapping(value ="/oauth2/v2/revoke", consumes = "application/x-www-form-urlencoded") void revokeTokens(@RequestBody Map requestBody); } From 03cfc59ebbbd2a6d2a15ba1c9521a1326321e0a2 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sun, 11 Feb 2024 10:04:51 +0900 Subject: [PATCH 15/16] =?UTF-8?q?remove:=20=ED=9A=8C=EC=9B=90=ED=83=88?= =?UTF-8?q?=ED=87=B4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/service/UserServiceImplTest.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/src/test/java/com/onnoff/onnoff/domain/user/service/UserServiceImplTest.java b/src/test/java/com/onnoff/onnoff/domain/user/service/UserServiceImplTest.java index 658f7aa..2585534 100644 --- a/src/test/java/com/onnoff/onnoff/domain/user/service/UserServiceImplTest.java +++ b/src/test/java/com/onnoff/onnoff/domain/user/service/UserServiceImplTest.java @@ -1,8 +1,5 @@ package com.onnoff.onnoff.domain.user.service; -import com.onnoff.onnoff.apiPayload.code.status.ErrorStatus; -import com.onnoff.onnoff.apiPayload.exception.GeneralException; -import com.onnoff.onnoff.auth.UserContext; import com.onnoff.onnoff.domain.user.User; import jakarta.transaction.Transactional; import org.assertj.core.api.Assertions; @@ -10,13 +7,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import static org.junit.jupiter.api.Assertions.assertThrows; - @SpringBootTest @Transactional class UserServiceImplTest { - private final UserService userService; public UserServiceImplTest(@Autowired UserService userService) { @@ -32,21 +26,4 @@ public UserServiceImplTest(@Autowired UserService userService) { Assertions.assertThat(user.getName()).isEqualTo(findUser.getName()); } - @Test - void 회원탈퇴() { - // 유저가 회원가입을 했고 id가 6인 상황 - - //유저 id 6인 사용자가 회원탈퇴 버튼 누름 - User user = userService.getUser(6l); - user.setUserStatusInactive(); - //한달 후에 hard delete - userService.deleteInactiveUsers(); - // 삭제 됐는지 확인 - GeneralException exception = assertThrows(GeneralException.class, () -> { - userService.getUser(6l); - }); - Assertions.assertThat(ErrorStatus.USER_NOT_FOUND).isEqualTo(exception.getCode()); - // 카카오톡 들어가서 연결된 앱에서 해지 됐는지도 확인 - } - } \ No newline at end of file From 9fd17d7eeb3dd1f5ea049edc50e97b58b671f1a8 Mon Sep 17 00:00:00 2001 From: wuseong Date: Sun, 11 Feb 2024 10:06:17 +0900 Subject: [PATCH 16/16] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=20=EC=99=84?= =?UTF-8?q?=EC=A0=84=20=ED=83=88=ED=87=B4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?API=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onnoff/domain/user/controller/UserController.java | 2 +- .../com/onnoff/onnoff/domain/user/service/UserService.java | 2 ++ .../onnoff/onnoff/domain/user/service/UserServiceImpl.java | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/onnoff/onnoff/domain/user/controller/UserController.java b/src/main/java/com/onnoff/onnoff/domain/user/controller/UserController.java index 93effde..3eda6d0 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/controller/UserController.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/controller/UserController.java @@ -41,7 +41,7 @@ public ApiResponse modifyUser(@RequestBody UserRe @PutMapping("/hard-delete") @Operation(summary = "회원 완전 탈퇴 테스트 API",description = "30일 뒤에 자동 완전삭제 수동 테스트") public ApiResponse hardDeleteTest(){ - userService.deleteInactiveUsers() ; + userService.deleteInactiveUsersTest(); return ApiResponse.onSuccess("삭제완"); } diff --git a/src/main/java/com/onnoff/onnoff/domain/user/service/UserService.java b/src/main/java/com/onnoff/onnoff/domain/user/service/UserService.java index 3612b8f..47d55a8 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/service/UserService.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/service/UserService.java @@ -21,5 +21,7 @@ public interface UserService { public User withdrawUser(); public void deleteInactiveUsers(); + + public void deleteInactiveUsersTest(); public User modifyUser(UserRequestDTO.ModifyUserDTO modifyUserDTO); } diff --git a/src/main/java/com/onnoff/onnoff/domain/user/service/UserServiceImpl.java b/src/main/java/com/onnoff/onnoff/domain/user/service/UserServiceImpl.java index 6e553a2..c55256f 100644 --- a/src/main/java/com/onnoff/onnoff/domain/user/service/UserServiceImpl.java +++ b/src/main/java/com/onnoff/onnoff/domain/user/service/UserServiceImpl.java @@ -94,6 +94,13 @@ public void deleteInactiveUsers() { inactiveUsers.forEach(userRepository::delete); inactiveUsers.forEach(this::disconnectApp); } + @Transactional + public void deleteInactiveUsersTest() { + LocalDateTime oneMonthAgo = LocalDateTime.now(); + List inactiveUsers = userRepository.findByStatusAndInactiveDateBefore(Status.INACTIVE, oneMonthAgo); + inactiveUsers.forEach(userRepository::delete); + inactiveUsers.forEach(this::disconnectApp); + } // 유저 소셜계정 앱 연동 해지 private void disconnectApp(User user){ SocialType socialType = user.getSocialType();