-
Notifications
You must be signed in to change notification settings - Fork 2
[배포] #265까지 병합 및 배포 #266
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
[배포] #265까지 병합 및 배포 #266
Changes from all commits
b61bb05
50cba22
553dd16
5bc6c38
6341200
921b2ef
5d7fb7b
46e7c7a
34a04b5
6bd062b
caa0723
df0354e
572ddb0
b680c70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package life.mosu.mosuserver.application.oauth; | ||
|
|
||
| import life.mosu.mosuserver.domain.user.entity.AuthProvider; | ||
| import life.mosu.mosuserver.domain.user.entity.UserJpaEntity; | ||
| import life.mosu.mosuserver.domain.user.entity.UserRole; | ||
| import life.mosu.mosuserver.domain.user.repository.UserJpaRepository; | ||
| import life.mosu.mosuserver.global.processor.StepProcessor; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| @Component | ||
| @RequiredArgsConstructor | ||
| public class OAuthUserPersistenceProcessor implements StepProcessor<OAuthUserInfo, UserJpaEntity> { | ||
|
|
||
| private final UserJpaRepository userRepository; | ||
|
|
||
| @Override | ||
| @Transactional | ||
| public UserJpaEntity process(final OAuthUserInfo info) { | ||
| return userRepository.findByLoginId(info.email()) | ||
| .map(existingUser -> { | ||
| existingUser.updateOAuthUser( | ||
| info.gender(), | ||
| info.name(), | ||
| info.phoneNumber(), | ||
| info.birthDay(), | ||
| info.marketingAgreed()); | ||
| return existingUser; | ||
| }) | ||
| .orElseGet(() -> { | ||
| final UserJpaEntity newUser = UserJpaEntity.builder() | ||
| .loginId(info.email()) | ||
| .gender(info.gender()) | ||
| .name(info.name()) | ||
| .birth(info.birthDay()) | ||
| .phoneNumber(info.phoneNumber()) | ||
| .userRole(UserRole.ROLE_PENDING) | ||
| .provider(AuthProvider.KAKAO) | ||
| .agreedToTermsOfService(true) | ||
| .agreedToPrivacyPolicy(true) | ||
| .agreedToMarketing(info.marketingAgreed()) | ||
| .build(); | ||
| return userRepository.save(newUser); | ||
| }); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,15 +1,10 @@ | ||||||
| package life.mosu.mosuserver.application.oauth; | ||||||
|
|
||||||
| import java.time.LocalDate; | ||||||
| import java.util.Collections; | ||||||
| import java.util.List; | ||||||
| import java.util.Map; | ||||||
| import life.mosu.mosuserver.domain.profile.entity.Gender; | ||||||
| import life.mosu.mosuserver.domain.profile.repository.ProfileJpaRepository; | ||||||
| import life.mosu.mosuserver.domain.user.entity.AuthProvider; | ||||||
| import life.mosu.mosuserver.domain.user.entity.UserJpaEntity; | ||||||
| import life.mosu.mosuserver.domain.user.entity.UserRole; | ||||||
| import life.mosu.mosuserver.domain.user.repository.UserJpaRepository; | ||||||
| import lombok.RequiredArgsConstructor; | ||||||
| import lombok.extern.slf4j.Slf4j; | ||||||
| import org.springframework.core.ParameterizedTypeReference; | ||||||
|
|
@@ -25,7 +20,7 @@ | |||||
| @RequiredArgsConstructor | ||||||
| public class OAuthUserService extends DefaultOAuth2UserService { | ||||||
|
|
||||||
| private final UserJpaRepository userRepository; | ||||||
| private final OAuthUserPersistenceProcessor oAuthUserPersistenceProcessor; | ||||||
| private final ProfileJpaRepository profileRepository; | ||||||
| private final WebClient webClient; | ||||||
|
|
||||||
|
|
@@ -44,12 +39,15 @@ public OAuth2User loadUser(final OAuth2UserRequest userRequest) | |||||
| agreedToMarketing = termsList.stream() | ||||||
| .filter(term -> term instanceof Map) | ||||||
| .map(term -> (Map<String, Object>) term) | ||||||
| .filter(termMap -> "terms_03".equals(termMap.get("tag"))) | ||||||
| .filter(termMap -> | ||||||
| "terms_03".equals(termMap.get("tag"))) | ||||||
| .findFirst() | ||||||
| .map(termMap -> (Boolean) termMap.get("agreed")) | ||||||
| .orElse(false); | ||||||
| } | ||||||
|
|
||||||
| log.info("동의 여부{}", agreedToMarketing); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This log statement uses Additionally, the log message
Suggested change
|
||||||
|
|
||||||
| final String registrationId = userRequest.getClientRegistration().getRegistrationId(); | ||||||
| final String userNameAttributeName = userRequest.getClientRegistration() | ||||||
| .getProviderDetails() | ||||||
|
|
@@ -59,43 +57,14 @@ public OAuth2User loadUser(final OAuth2UserRequest userRequest) | |||||
| final OAuthUserInfo userInfo = OAuthUserInfo.of(OAuthProvider.from(registrationId), | ||||||
| oAuth2UserAttributes, agreedToMarketing); | ||||||
|
|
||||||
| final UserJpaEntity oAuthUser = updateOrWrite(userInfo); | ||||||
| final UserJpaEntity oAuthUser = oAuthUserPersistenceProcessor.process(userInfo); | ||||||
|
|
||||||
| Boolean isProfileRegistered = profileRepository.existsByUserId(oAuthUser.getId()); | ||||||
|
|
||||||
| return new OAuthUser(oAuthUser, oAuth2UserAttributes, userNameAttributeName, | ||||||
| isProfileRegistered); | ||||||
| } | ||||||
|
|
||||||
| private UserJpaEntity updateOrWrite(final OAuthUserInfo info) { | ||||||
| return userRepository.findByLoginId(info.email()) | ||||||
| .map(existingUser -> { | ||||||
| existingUser.updateOAuthUser( | ||||||
| info.gender(), | ||||||
| info.name(), | ||||||
| info.phoneNumber(), | ||||||
| info.birthDay() != null ? info.birthDay() : LocalDate.of(1900, 1, 1)); | ||||||
| return existingUser; | ||||||
| }) | ||||||
| .orElseGet(() -> { | ||||||
| final UserJpaEntity newUser = UserJpaEntity.builder() | ||||||
| .loginId(info.email() != null ? info.email() : "NA") | ||||||
| .gender(info.gender() != null ? info.gender() : Gender.PENDING) | ||||||
| .name(info.name() != null ? info.name() : "NA") | ||||||
| .birth(info.birthDay() != null ? info.birthDay() | ||||||
| : LocalDate.EPOCH) | ||||||
| .phoneNumber(info.phoneNumber() != null ? info.phoneNumber() | ||||||
| : "010-0000-0000") | ||||||
| .userRole(UserRole.ROLE_PENDING) | ||||||
| .provider(AuthProvider.KAKAO) | ||||||
| .agreedToTermsOfService(true) | ||||||
| .agreedToPrivacyPolicy(true) | ||||||
| .agreedToMarketing(info.marketingAgreed()) | ||||||
| .build(); | ||||||
| return userRepository.save(newUser); | ||||||
| }); | ||||||
| } | ||||||
|
|
||||||
| private Map<String, Object> getServiceTerms(String accessToken) { | ||||||
|
|
||||||
| String url = "https://kapi.kakao.com/v2/user/service_terms"; | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,16 @@ | ||
| package life.mosu.mosuserver.domain.caffeine.dto; | ||
|
|
||
| import lombok.Getter; | ||
| import java.util.concurrent.atomic.AtomicInteger; | ||
|
|
||
| @Getter | ||
| public class RequestCounter { | ||
| private int count = 0; | ||
|
|
||
| public void increment() { | ||
| count++; | ||
| private final AtomicInteger count = new AtomicInteger(); | ||
|
|
||
| public int incrementAndGet() { | ||
| return count.incrementAndGet(); | ||
| } | ||
|
|
||
| public int getCount() { | ||
| return count.get(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
processmethod doesn't handle the case whereinfo.email()isnull. If the OAuth provider doesn't return an email,userRepository.findByLoginId(null)will be called, which will likely cause aNullPointerExceptionor anIllegalArgumentException, breaking the login/signup flow for that user.The previous implementation had a fallback for a null email, but it was flawed as it used a non-unique value ("NA"). This refactoring seems to have lost the null-safety check entirely.
If an email is required for identifying users, you should validate that it's not null and throw an exception if it is. This makes the requirement explicit and prevents runtime errors.