Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.synapse.account_service.convert.authority.CustomAuthorityMapper;
import com.synapse.account_service.filter.JwtAuthenticationFilter;
import com.synapse.account_service.service.CustomOAuth2UserService;
import com.synapse.account_service.service.CustomOidcUserService;
import com.synapse.account_service.service.CustomUserDetailsService;
import com.synapse.account_service.service.handler.LoginFailureHandler;
import com.synapse.account_service.service.handler.LoginSuccessHandler;
Expand All @@ -32,6 +33,7 @@ public class SecurityConfig {
private final LoginSuccessHandler loginSuccessHandler;
private final LoginFailureHandler loginFailureHandler;
private final CustomOAuth2UserService customOAuth2UserService;
private final CustomOidcUserService customOidcUserService;
private final ObjectMapper objectMapper;
private final PasswordEncoder passwordEncoder;

Expand All @@ -48,7 +50,10 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http, JwtAuthenticat
.addFilterAt(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)

.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfo -> userInfo.userService(customOAuth2UserService))
.userInfoEndpoint(userInfo -> userInfo
.userService(customOAuth2UserService)
.oidcUserService(customOidcUserService)
)
.successHandler(loginSuccessHandler)
.failureHandler(loginFailureHandler)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ public DelegatingProviderUserConverter() {
new UserDetailsProviderUserConverter(),
new OAuth2GoogleProviderUserConverter(),
new OAuth2KakaoProviderUserConverter(),
new OAuth2KakaoOidcProviderUserConverter());
new OAuth2KakaoOidcProviderUserConverter(),
new OAuth2NaverProviderUserConverter()
);

this.converters = Collections.unmodifiableList(new LinkedList<>(providerUserConverters));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.synapse.account_service.convert;

import com.synapse.account_service.domain.ProviderUser;
import com.synapse.account_service.domain.enums.OAuth2Config;
import com.synapse.account_service.domain.socials.NaverUser;
import com.synapse.account_service.util.OAuth2Utils;

public final class OAuth2NaverProviderUserConverter implements ProviderUserConverter<ProviderUserRequest, ProviderUser> {

@Override
public ProviderUser convert(ProviderUserRequest providerUserRequest) {

if (!providerUserRequest.clientRegistration().getRegistrationId().equals(OAuth2Config.SocialType.NAVER.getSocialName())) {
return null;
}

return new NaverUser(OAuth2Utils.getSubAttributes(
providerUserRequest.oAuth2User(), "response"),
providerUserRequest.oAuth2User(),
providerUserRequest.clientRegistration());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
public class OAuth2Config {
public enum SocialType {
GOOGLE("google"),
KAKAO("kakao");
KAKAO("kakao"),
NAVER("naver")
;

private final String socialName;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.synapse.account_service.domain.socials;

import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.user.OAuth2User;

import com.synapse.account_service.domain.Attributes;

public class NaverUser extends OAuth2ProviderUser {

public NaverUser(Attributes attributes, OAuth2User oAuth2User, ClientRegistration clientRegistration) {
super(attributes.getSubAttributes(), oAuth2User, clientRegistration);
}

@Override
public String getId() {
return (String) getAttributes().get("id");
}

@Override
public String getUsername() {
return (String) getAttributes().get("name");
}

@Override
public String getPicture() {
return (String) getAttributes().get("profile_image");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum ExceptionType {
DUPLICATED_USERNAME(CONFLICT, "002", "이미 존재하는 사용자 이름입니다."),
EXCEPTION(INTERNAL_SERVER_ERROR, "003", "예상치 못한 오류가 발생했습니다."),
NOT_FOUND_MEMBER(NOT_FOUND, "004", "존재하지 않는 사용자입니다."),
DUPLICATED_USERNAME_AND_EMAIL(CONFLICT, "005", "이미 존재하는 사용자 이름과 이메일입니다."),

INVALID_TOKEN(UNAUTHORIZED, "005", "유효하지 않은 토큰입니다."),
EXPIRED_TOKEN(UNAUTHORIZED, "006", "만료된 토큰입니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public interface MemberRepository extends JpaRepository<Member, UUID> {
Optional<Member> findByUsername(String username);
Optional<Member> findByProviderAndRegistrationId(String provider, String registrationId);

@Query("SELECT m FROM Member m WHERE m.username = :username AND m.email = :email")
Optional<Member> findByUsernameAndEmail(@Param("username") String username, @Param("email") String email);

@Query("SELECT m FROM Member m WHERE (m.provider = :provider AND m.registrationId = :registrationId) OR m.email = :email OR m.username = :username")
Optional<Member> findBySocialIdOrEmailOrUsername(@Param("provider") String provider, @Param("registrationId") String registrationId, @Param("email") String email, @Param("username") String username);
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ public SignUpResponse registerMember(SignUpRequest request) {

private Member createAndSaveNewMember(String email, String username, String password, String provider, String registrationId) {
// 중복 검사
memberRepository.findByEmail(email).ifPresent(m -> {
throw new DuplicatedException(ExceptionType.DUPLICATED_EMAIL);
});
memberRepository.findByUsername(username).ifPresent(m -> {
throw new DuplicatedException(ExceptionType.DUPLICATED_USERNAME);
memberRepository.findByUsernameAndEmail(username, email).ifPresent(m -> {
throw new DuplicatedException(ExceptionType.DUPLICATED_USERNAME_AND_EMAIL);
});

Member member = Member.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ public static Attributes getMainAttributes(OAuth2User oAuth2User) {
.build();
}

@SuppressWarnings("unchecked")
public static Attributes getSubAttributes(OAuth2User oAuth2User, String subAttributesKey) {

Map<String, Object> subAttributes = (Map<String, Object>) oAuth2User.getAttributes().get(subAttributesKey);
return Attributes.builder()
.subAttributes(subAttributes)
.build();
}

@SuppressWarnings("unchecked")
public static Attributes getOtherAttributes(OAuth2User oAuth2User, String subAttributesKey, String otherAttributesKey) {

Expand Down
2 changes: 1 addition & 1 deletion account-service/src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ spring:
highlight:
sql: true
hbm2ddl:
auto: create-drop
auto: create
dialect: org.hibernate.dialect.PostgreSQLDialect
open-in-view: false
show-sql: true
Expand Down
1 change: 1 addition & 0 deletions account-service/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ spring:
import:
- security/application-db.yml
- security/application-jwt.yml
- security/application-oauth2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ void signUp_success() {
// given: 테스트 준비
SignUpRequest request = new SignUpRequest("test@example.com", "테스트유저", "password123");

given(memberRepository.findByEmail(anyString())).willReturn(Optional.empty());
given(memberRepository.findByUsername(anyString())).willReturn(Optional.empty());
given(memberRepository.findByUsernameAndEmail(anyString(), anyString())).willReturn(Optional.empty());
given(passwordEncoder.encode(anyString())).willReturn("encodedPassword");
given(memberRepository.save(any(Member.class))).willAnswer(invocation -> {
Member memberToSave = invocation.getArgument(0);
Expand All @@ -61,15 +60,15 @@ void signUp_success() {
}

@Test
@DisplayName("이메일 중복으로 회원가입 실패")
void signUp_fail_withDuplicateEmail() {
@DisplayName("이메일 또는 사용자명 중복으로 회원가입 실패")
void signUp_fail_withDuplicateUsernameAndEmail() {
// given
SignUpRequest request = new SignUpRequest("test@example.com", "테스트유저", "password123");

// memberRepository.findByEmail이 호출되면, 이미 존재하는 Member 객체를 반환하도록 설정
given(memberRepository.findByEmail(anyString())).willReturn(Optional.of(Member.builder().build()));
// memberRepository.findByUsernameAndEmail이 호출되면, 이미 존재하는 Member 객체를 반환하도록 설정
given(memberRepository.findByUsernameAndEmail(anyString(), anyString())).willReturn(Optional.of(Member.builder().build()));

// when & then: BusinessException이 발생하는지 검증
// when & then: DuplicatedException이 발생하는지 검증
assertThrows(DuplicatedException.class, () -> {
accountService.registerMember(request);
});
Expand Down
Loading