-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCustomOAuth2UserService.java
More file actions
110 lines (87 loc) · 4.06 KB
/
CustomOAuth2UserService.java
File metadata and controls
110 lines (87 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package doldol_server.doldol.auth.service;
import java.util.Optional;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import doldol_server.doldol.auth.dto.CustomUserDetails;
import doldol_server.doldol.auth.dto.OAuth2Response;
import doldol_server.doldol.common.exception.CustomOAuth2Exception;
import doldol_server.doldol.common.exception.errorCode.AuthErrorCode;
import doldol_server.doldol.common.exception.errorCode.CommonErrorCode;
import doldol_server.doldol.user.entity.SocialType;
import doldol_server.doldol.user.entity.User;
import doldol_server.doldol.user.repository.UserRepository;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
private static final String STATE = "state";
private static final String USER_ID_OPT = "_userId:";
private final OAuthSeperator oAuthSeperator;
private final UserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
String userId = extractUserIdFromState();
boolean isAccountLinking = false;
if (userId != null) {
isAccountLinking = true;
}
OAuth2Response oAuth2Response = oAuthSeperator.createResponse(registrationId, oAuth2User.getAttributes());
Optional<User> socialLinkedUser = userRepository.findBySocialId(oAuth2Response.getSocialId());
if (socialLinkedUser.isPresent() && !socialLinkedUser.get().isDeleted()) {
return handleExistingUser(socialLinkedUser.get(), oAuth2User, oAuth2Response.getSocialId());
}
else if (socialLinkedUser.isPresent() && socialLinkedUser.get().isDeleted()) {
throw new CustomOAuth2Exception(AuthErrorCode.ALREADY_WITHDRAWN);
}
if (isAccountLinking) {
return handleAccountLinking(userId, oAuth2Response, oAuth2User, registrationId);
} else {
return handleNewUser(oAuth2User, oAuth2Response.getSocialId());
}
}
private String extractUserIdFromState() {
ServletRequestAttributes attrs = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if (attrs != null) {
HttpServletRequest request = attrs.getRequest();
String state = request.getParameter(STATE);
if (state != null && state.contains(USER_ID_OPT)) {
String[] parts = state.split(USER_ID_OPT);
if (parts.length > 1) {
String userId = parts[1];
return userId;
}
}
}
return null;
}
private OAuth2User handleExistingUser(User user, OAuth2User oAuth2User, String registrationId) {
return new CustomUserDetails(user.getId(), oAuth2User.getAttributes(), registrationId);
}
private OAuth2User handleAccountLinking(String userId, OAuth2Response oAuth2Response,
OAuth2User oAuth2User, String registrationId) {
validateUserId(userId);
User existingUser = userRepository.findById(Long.parseLong(userId))
.orElseThrow(() -> new CustomOAuth2Exception(AuthErrorCode.USER_NOT_FOUND));
existingUser.updateSocialInfo(oAuth2Response.getSocialId(), SocialType.getSocialType(registrationId));
userRepository.save(existingUser);
return new CustomUserDetails(Long.parseLong(userId), oAuth2User.getAttributes(), oAuth2Response.getSocialId());
}
private OAuth2User handleNewUser(OAuth2User oAuth2User, String socialId) {
return new CustomUserDetails(oAuth2User.getAttributes(), socialId);
}
private void validateUserId(String userId) {
try {
Long.parseLong(userId);
} catch (NumberFormatException e) {
throw new CustomOAuth2Exception(CommonErrorCode.INVALID_ARGUMENT);
}
}
}