Skip to content

Commit

Permalink
Merge pull request #181 from Funssion-SWM/develope
Browse files Browse the repository at this point in the history
hotfix: 구글로그인 redirect 문제 해결 및 테스트 코드 추가
  • Loading branch information
goathoon authored Nov 14, 2023
2 parents 49cb1a7 + 5d36a53 commit 2f7100a
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
Expand Down Expand Up @@ -100,9 +101,14 @@ private String makeRefreshCookieString(String token,boolean isHttpOnly) {
}

private String redirectUriByFirstJoinOrNot(Authentication authentication){
OAuth2User oAuth2User = (OAuth2User)authentication.getPrincipal();
return getRedirectUri(authentication);
}

@NotNull
public String getRedirectUri(Authentication authentication) {
OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal();
Collection<? extends GrantedAuthority> authorities = oAuth2User.getAuthorities();
if(authorities.stream().filter(o -> o.getAuthority().equals(Role.OAUTH_FIRST_JOIN)).findAny().isPresent()){
if(authorities.stream().filter(o -> o.getAuthority().equals(Role.OAUTH_FIRST_JOIN.getRoles())).findAny().isPresent()){
return UriComponentsBuilder.fromHttpUrl(signUpURI)
.path(authentication.getName())
.build().toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Funssion.Inforum.domain.member.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
Expand All @@ -33,6 +34,11 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic
OAuth2UserService delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String email = oAuth2User.getAttribute("email");
return getCustomUserDetails(oAuth2User, email);
}

@NotNull
public CustomUserDetails getCustomUserDetails(OAuth2User oAuth2User, String email) {
String nickname = UUID.randomUUID().toString().substring(0,15);

memberRepository.findNonSocialMemberByEmail(email).ifPresent(m->{
Expand All @@ -44,10 +50,10 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic
SocialMember savedSocialMember = SocialMember.createSocialMember(email, nickname);
SaveMemberResponseDto savedResponse = memberRepository.save(savedSocialMember);
String roles = Role.addRole(Role.getIncludingRoles(savedResponse.getRole()), Role.OAUTH_FIRST_JOIN);// 최초 회원가입을 위한 임시 role 추가
return new CustomUserDetails(String.valueOf(savedResponse.getId()),roles,oAuth2User.getAttributes());
return new CustomUserDetails(String.valueOf(savedResponse.getId()), roles, oAuth2User.getAttributes());
}
else{
return new CustomUserDetails(String.valueOf(socialMember.get().getUserId()),Role.getIncludingRoles(socialMember.get().getRole()),oAuth2User.getAttributes());
return new CustomUserDetails(String.valueOf(socialMember.get().getUserId()), Role.getIncludingRoles(socialMember.get().getRole()), oAuth2User.getAttributes());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package Funssion.Inforum.access_handler;

import Funssion.Inforum.common.constant.Role;
import Funssion.Inforum.domain.member.entity.CustomUserDetails;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.core.Authentication;

import java.io.IOException;
import java.util.Map;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@SpringBootTest
class AuthenticationSuccessHandlerTest {

@Value("${oauth-signup-uri}") String signUpURI;
@Value("${oauth-signin-uri}") String signInURI;

@Autowired
AuthenticationSuccessHandler authenticationSuccessHandler;
@Test
@DisplayName("OAuth 유저 최초로그인시 redirect uri 확인")
void firstLoginThenRedirectToNicknamePage() throws IOException {
Authentication mockAuthentication = mock(Authentication.class);
when(mockAuthentication.getPrincipal()).thenReturn(new CustomUserDetails(String.valueOf(1L), Role.addRole(Role.getIncludingRoles(Role.USER.toString()), Role.OAUTH_FIRST_JOIN), Map.of()));
when(mockAuthentication.getName()).thenReturn("name");
Assertions.assertThat(authenticationSuccessHandler.getRedirectUri(mockAuthentication)).isEqualTo(signUpURI+"name");
}
@Test
@DisplayName("OAuth 유저 로그인시 redirect uri 확인")
void LoginThenRedirectToMainPage() throws IOException {
Authentication mockAuthentication = mock(Authentication.class);
when(mockAuthentication.getPrincipal()).thenReturn(new CustomUserDetails(String.valueOf(1L), Role.USER.toString(), Map.of()));
when(mockAuthentication.getName()).thenReturn("name");
Assertions.assertThat(authenticationSuccessHandler.getRedirectUri(mockAuthentication)).isEqualTo(signInURI);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package Funssion.Inforum.domain.member.service;

import Funssion.Inforum.common.constant.Role;
import Funssion.Inforum.common.dto.IsSuccessResponseDto;
import Funssion.Inforum.domain.member.constant.LoginType;
import Funssion.Inforum.domain.member.dto.request.MemberSaveDto;
Expand All @@ -8,20 +9,28 @@
import Funssion.Inforum.domain.member.dto.response.SaveMemberResponseDto;
import Funssion.Inforum.domain.member.entity.NonSocialMember;
import Funssion.Inforum.domain.member.entity.SocialMember;
import Funssion.Inforum.domain.member.exception.DuplicateMemberException;
import Funssion.Inforum.domain.member.repository.AuthCodeRepository;
import Funssion.Inforum.domain.member.repository.MemberRepository;
import jakarta.mail.internet.MimeMessage;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.transaction.annotation.Transactional;

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

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

Expand All @@ -34,13 +43,15 @@ class MemberIntegrationTest {
@Autowired
MemberService memberService;


@Autowired
OAuthService oAuthService;
// 인증 메일 관련 주입
@Autowired
MailService mailService;

@MockBean
JavaMailSender mailSender;
@MockBean
OAuth2UserRequest oAuth2UserRequest;

@Autowired
AuthCodeRepository authCodeRepository;
Expand Down Expand Up @@ -124,12 +135,41 @@ void updatePassword(){

}
}
/*
* <requestMemberRegistration>
* 1.중복아닌거 가정하고 / NonSocial 로그인 타입 요청시 / 저장 객체 반환
* 2.중복이면 ? / .. / throw duplication
* 3.중복아니고, social 이면 / .. / throw
*
*/
@Nested
@DisplayName("회원가입")
class registerUser{
@Test
@DisplayName("OAuth 회원가입시 authentication 객체 확인")
void registerByOAuth(){
String userEmail = "[email protected]";
OAuth2User mockOAuth2User = mock(OAuth2User.class);
when(mockOAuth2User.getAttributes()).thenReturn(Map.of());
assertThat(oAuthService.getCustomUserDetails(mockOAuth2User,userEmail).
getAuthorities().stream().map(auth->auth.getAuthority()))
.contains(Role.USER.getRoles(),Role.OAUTH_FIRST_JOIN.getRoles());
}
@Test
@DisplayName("OAuth 에 회원가입된 것으로 로그인시 authentication 객체 확인")
void registerByOAuthWhenAlreadyRegistered(){
String userEmail = "[email protected]";
memberRepository.save(SocialMember.createSocialMember(userEmail,"nickname"));

OAuth2User mockOAuth2User = mock(OAuth2User.class);
when(mockOAuth2User.getAttributes()).thenReturn(Map.of());
assertThat(oAuthService.getCustomUserDetails(mockOAuth2User,userEmail).
getAuthorities().stream().map(auth->auth.getAuthority()))
.contains(Role.USER.getRoles());
}
@Test
@DisplayName("OAuth 에 일반 가입된 이메일로 로그인시 authentication 객체 확인")
void registerByOAuthWhenAlreadyRegisteredByNonSocial(){
String userEmail = "[email protected]";
memberRepository.save(NonSocialMember.createNonSocialMember(new MemberSaveDto("name",LoginType.NON_SOCIAL,userEmail,"a1234567@")));

OAuth2User mockOAuth2User = mock(OAuth2User.class);
when(mockOAuth2User.getAttributes()).thenReturn(Map.of());
assertThatThrownBy(()->oAuthService.getCustomUserDetails(mockOAuth2User,userEmail)).isExactlyInstanceOf(DuplicateMemberException.class);
}
}

}

0 comments on commit 2f7100a

Please sign in to comment.