Skip to content

Commit 0fec0d1

Browse files
refactor : Saver
1 parent f189da0 commit 0fec0d1

File tree

3 files changed

+46
-11
lines changed

3 files changed

+46
-11
lines changed

client/src/main/java/com/patternknife/securityhelper/oauth2/client/config/securityimpl/message/CustomSecurityUserExceptionMessage.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ public enum CustomSecurityUserExceptionMessage implements ExceptionMessageInterf
1717
AUTHENTICATION_PASSWORD_FAILED_EXCEEDED("1The number of password attempts has been exceeded."),
1818

1919
// Wrong Authorization Code
20-
AUTHORIZATION_CODE_NO_EXISTS("1The specified Authorization code does not exist."),
21-
20+
AUTHENTICATION_INVALID_RESPONSE_TYPE("1The specified Response Type is invalid."),
21+
AUTHENTICATION_INVALID_AUTHORIZATION_CODE("1The specified Authorization Code is invalid."),
22+
AUTHENTICATION_EXPIRED_AUTHORIZATION_CODE("1The specified Authorization Code has been expired."),
23+
AUTHENTICATION_INVALID_REDIRECT_URI("1The specified Redirect URI is invalid."),
24+
AUTHENTICATION_SCOPES_NOT_APPROVED("1The specified Scopes are not approved."),
2225
// CLIENT ID, SECRET
2326
AUTHENTICATION_WRONG_CLIENT_ID_SECRET("1Client information is not verified."),
2427

lib/src/main/java/io/github/patternknife/securityhelper/oauth2/api/config/security/message/DefaultSecurityUserExceptionMessage.java

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public enum DefaultSecurityUserExceptionMessage implements ExceptionMessageInter
1818
// Wrong Authorization Code
1919
AUTHENTICATION_INVALID_RESPONSE_TYPE("The specified Response Type is invalid."),
2020
AUTHENTICATION_INVALID_AUTHORIZATION_CODE("The specified Authorization Code is invalid."),
21+
AUTHENTICATION_EXPIRED_AUTHORIZATION_CODE("The specified Authorization Code has been expired."),
2122
AUTHENTICATION_INVALID_REDIRECT_URI("The specified Redirect URI is invalid."),
2223
AUTHENTICATION_SCOPES_NOT_APPROVED("The specified Scopes are not approved."),
2324
// CLIENT ID, SECRET

lib/src/main/java/io/github/patternknife/securityhelper/oauth2/api/config/security/serivce/CommonOAuth2AuthorizationSaverImpl.java

+40-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.github.patternknife.securityhelper.oauth2.api.config.security.serivce;
22

3-
43
import io.github.patternknife.securityhelper.oauth2.api.config.logger.KnifeSecurityLogConfig;
54
import io.github.patternknife.securityhelper.oauth2.api.config.security.message.DefaultSecurityUserExceptionMessage;
65
import io.github.patternknife.securityhelper.oauth2.api.config.security.message.ISecurityUserExceptionMessageService;
@@ -27,7 +26,11 @@
2726

2827
import java.util.Map;
2928

30-
29+
/*
30+
* Saver : Persist
31+
* Implements the logic for persisting OAuth2Authorization based on the provided grant type.
32+
* Supports various grant types and handles duplicate exceptions gracefully.
33+
* */
3134
@Service
3235
@RequiredArgsConstructor
3336
public class CommonOAuth2AuthorizationSaverImpl implements CommonOAuth2AuthorizationSaver {
@@ -38,18 +41,42 @@ public class CommonOAuth2AuthorizationSaverImpl implements CommonOAuth2Authoriza
3841
private final OAuth2AuthorizationServiceImpl oAuth2AuthorizationService;
3942
private final ISecurityUserExceptionMessageService iSecurityUserExceptionMessageService;
4043

41-
/*
42-
* While the Spring Authorization Server is generally not expected to cause duplicate exceptions,
43-
* I have observed such errors in the past. This is a preventive measure to handle potential issues gracefully.
44+
/**
45+
* Handles OAuth2Authorization persistence based on the grant type.
46+
*
47+
* <p><b>Grant Types:</b></p>
48+
* <ul>
49+
* <li><b>AUTHORIZATION_CODE</b>: Generates a "code" using "username" and "password".</li>
50+
* <li><b>CODE</b>: Generates an "access_token" using the "code".</li>
51+
* <li><b>PASSWORD</b>: Generates an "access_token" using "username" and "password".</li>
52+
* <li><b>REFRESH_TOKEN</b>: Generates a "refresh_token" using the "access_token".</li>
53+
* </ul>
54+
*
55+
* <p><b>retryOnDuplicateException:</b></p>
56+
* <p>
57+
* While the Spring Authorization Server is generally not expected to cause duplicate exceptions,
58+
* such errors have been observed in the past. This method includes preventive measures to handle
59+
* potential issues gracefully by retrying the operation.
60+
* </p>
61+
*
62+
* @param userDetails the details of the authenticated user.
63+
* @param authorizationGrantType the type of authorization grant.
64+
* @param clientId the client ID.
65+
* @param additionalParameters additional parameters for the OAuth2 flow.
66+
* @param modifiableAdditionalParameters additional parameters that may be modified during the flow.
67+
* @return the persisted {@link OAuth2Authorization} object.
68+
* @throws KnifeOauth2AuthenticationException if an authentication error occurs.
4469
*/
4570
@Override
4671
public @NotNull OAuth2Authorization save(UserDetails userDetails, AuthorizationGrantType authorizationGrantType, String clientId,
4772
Map<String, Object> additionalParameters, Map<String, Object> modifiableAdditionalParameters) {
4873

4974
if (authorizationGrantType.getValue().equals(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())) {
5075
return SecurityExceptionUtils.retryOnDuplicateException(() -> {
76+
// In-memory build
5177
OAuth2Authorization oAuth2Authorization = oAuth2AuthorizationBuildingService.build(
5278
userDetails, authorizationGrantType, clientId, additionalParameters, null);
79+
// Persist
5380
oAuth2AuthorizationService.save(oAuth2Authorization);
5481
return oAuth2Authorization;
5582
}, 5, logger, "[Authorization Code] An error occurred with the Key during the execution of persistOAuth2Authorization for " + userDetails.getUsername());
@@ -65,22 +92,24 @@ public class CommonOAuth2AuthorizationSaverImpl implements CommonOAuth2Authoriza
6592
if(authorizationGrantType.getValue().equals(OAuth2ParameterNames.CODE)){
6693
OAuth2Authorization oAuth2AuthorizationForCodeVerification = oAuth2AuthorizationService.findByAuthorizationCode(additionalParameters.get(OAuth2ParameterNames.CODE).toString());
6794
if(oAuth2AuthorizationForCodeVerification == null) {
68-
throw new KnifeOauth2AuthenticationException("No authorization code found");
95+
throw new KnifeOauth2AuthenticationException(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_INVALID_AUTHORIZATION_CODE));
6996
}else{
70-
OAuth2Authorization.Token oAuth2Token =oAuth2AuthorizationForCodeVerification.getToken(OAuth2AuthorizationCode.class);
97+
OAuth2Authorization.Token<OAuth2AuthorizationCode> oAuth2Token =oAuth2AuthorizationForCodeVerification.getToken(OAuth2AuthorizationCode.class);
7198
if(oAuth2Token == null){
72-
throw new KnifeOauth2AuthenticationException("No authorization code found2");
99+
throw new KnifeOauth2AuthenticationException(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_INVALID_AUTHORIZATION_CODE));
73100
}
74101
if(oAuth2Token.isExpired()){
75-
throw new KnifeOauth2AuthenticationException("authorization code expired");
102+
throw new KnifeOauth2AuthenticationException(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_EXPIRED_AUTHORIZATION_CODE));
76103
}
77104
}
78105
}
79106

80107
if (oAuth2Authorization == null || oAuth2Authorization.getAccessToken().isExpired()) {
81108
return SecurityExceptionUtils.retryOnDuplicateException(() -> {
109+
// In-memory build
82110
OAuth2Authorization authorization = oAuth2AuthorizationBuildingService.build(
83111
userDetails, authorizationGrantType, clientId, additionalParameters, null);
112+
// Persist
84113
oAuth2AuthorizationService.save(authorization);
85114
return authorization;
86115
}, 5, logger, "[Access Token] An error occurred with the Key during the execution of persistOAuth2Authorization for " + userDetails.getUsername());
@@ -100,8 +129,10 @@ public class CommonOAuth2AuthorizationSaverImpl implements CommonOAuth2Authoriza
100129
OAuth2RefreshToken shouldBePreservedRefreshToken = oAuth2AuthorizationFromRefreshToken.getRefreshToken().getToken();
101130
oAuth2AuthorizationService.remove(oAuth2AuthorizationFromRefreshToken);
102131

132+
// In-memory build
103133
OAuth2Authorization authorization = oAuth2AuthorizationBuildingService.build(
104134
userDetails, authorizationGrantType, clientId, additionalParameters, shouldBePreservedRefreshToken);
135+
// Persist
105136
oAuth2AuthorizationService.save(authorization);
106137
return authorization;
107138

0 commit comments

Comments
 (0)