mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-02-07 00:17:07 +01:00
wip - added UsernameAttribute enum for useAsUsername
This commit is contained in:
parent
bc57977f9e
commit
eeb7498fe1
@ -16,8 +16,8 @@ import stirling.software.SPDF.config.security.LoginAttemptService;
|
|||||||
import stirling.software.SPDF.config.security.UserService;
|
import stirling.software.SPDF.config.security.UserService;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
|
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
|
import stirling.software.SPDF.model.UsernameAttribute;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class CustomOAuth2UserService implements OAuth2UserService<OidcUserRequest, OidcUser> {
|
public class CustomOAuth2UserService implements OAuth2UserService<OidcUserRequest, OidcUser> {
|
||||||
@ -41,28 +41,12 @@ public class CustomOAuth2UserService implements OAuth2UserService<OidcUserReques
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
|
public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
|
||||||
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
|
||||||
String usernameAttribute = oauth2.getUseAsUsername();
|
|
||||||
|
|
||||||
if (usernameAttribute == null || usernameAttribute.isEmpty()) {
|
|
||||||
Client client = oauth2.getClient();
|
|
||||||
|
|
||||||
if (client != null && client.getKeycloak() != null) {
|
|
||||||
usernameAttribute = client.getKeycloak().getUseAsUsername();
|
|
||||||
} else {
|
|
||||||
usernameAttribute = "email";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
OidcUser user = delegate.loadUser(userRequest);
|
OidcUser user = delegate.loadUser(userRequest);
|
||||||
String username = user.getUserInfo().getClaimAsString(usernameAttribute);
|
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
||||||
|
UsernameAttribute usernameAttribute =
|
||||||
// Check if the username claim is null or empty
|
UsernameAttribute.valueOf(oauth2.getUseAsUsername().toUpperCase());
|
||||||
if (username == null || username.isBlank()) {
|
String username = usernameAttribute.getName();
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Claim '" + usernameAttribute + "' cannot be null or empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<User> internalUser = userService.findByUsernameIgnoreCase(username);
|
Optional<User> internalUser = userService.findByUsernameIgnoreCase(username);
|
||||||
|
|
||||||
@ -78,10 +62,7 @@ public class CustomOAuth2UserService implements OAuth2UserService<OidcUserReques
|
|||||||
|
|
||||||
// Return a new OidcUser with adjusted attributes
|
// Return a new OidcUser with adjusted attributes
|
||||||
return new DefaultOidcUser(
|
return new DefaultOidcUser(
|
||||||
user.getAuthorities(),
|
user.getAuthorities(), userRequest.getIdToken(), user.getUserInfo(), username);
|
||||||
userRequest.getIdToken(),
|
|
||||||
user.getUserInfo(),
|
|
||||||
usernameAttribute);
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
log.error("Error loading OIDC user: {}", e.getMessage());
|
log.error("Error loading OIDC user: {}", e.getMessage());
|
||||||
throw new OAuth2AuthenticationException(new OAuth2Error(e.getMessage()), e);
|
throw new OAuth2AuthenticationException(new OAuth2Error(e.getMessage()), e);
|
||||||
|
@ -28,6 +28,7 @@ import stirling.software.SPDF.model.ApplicationProperties;
|
|||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
|
import stirling.software.SPDF.model.UsernameAttribute;
|
||||||
import stirling.software.SPDF.model.exception.NoProviderFoundException;
|
import stirling.software.SPDF.model.exception.NoProviderFoundException;
|
||||||
import stirling.software.SPDF.model.provider.GitHubProvider;
|
import stirling.software.SPDF.model.provider.GitHubProvider;
|
||||||
import stirling.software.SPDF.model.provider.GoogleProvider;
|
import stirling.software.SPDF.model.provider.GoogleProvider;
|
||||||
@ -92,7 +93,7 @@ public class OAuth2Configuration {
|
|||||||
.clientId(keycloak.getClientId())
|
.clientId(keycloak.getClientId())
|
||||||
.clientSecret(keycloak.getClientSecret())
|
.clientSecret(keycloak.getClientSecret())
|
||||||
.scope(keycloak.getScopes())
|
.scope(keycloak.getScopes())
|
||||||
.userNameAttributeName(keycloak.getUseAsUsername())
|
.userNameAttributeName(keycloak.getUseAsUsername().name())
|
||||||
.clientName(keycloak.getClientName())
|
.clientName(keycloak.getClientName())
|
||||||
.build())
|
.build())
|
||||||
: Optional.empty();
|
: Optional.empty();
|
||||||
@ -123,7 +124,7 @@ public class OAuth2Configuration {
|
|||||||
.authorizationUri(google.getAuthorizationUri())
|
.authorizationUri(google.getAuthorizationUri())
|
||||||
.tokenUri(google.getTokenUri())
|
.tokenUri(google.getTokenUri())
|
||||||
.userInfoUri(google.getUserInfoUri())
|
.userInfoUri(google.getUserInfoUri())
|
||||||
.userNameAttributeName(google.getUseAsUsername())
|
.userNameAttributeName(google.getUseAsUsername().name())
|
||||||
.clientName(google.getClientName())
|
.clientName(google.getClientName())
|
||||||
.redirectUri(REDIRECT_URI_PATH + google.getName())
|
.redirectUri(REDIRECT_URI_PATH + google.getName())
|
||||||
.authorizationGrantType(AUTHORIZATION_CODE)
|
.authorizationGrantType(AUTHORIZATION_CODE)
|
||||||
@ -156,7 +157,7 @@ public class OAuth2Configuration {
|
|||||||
.authorizationUri(github.getAuthorizationUri())
|
.authorizationUri(github.getAuthorizationUri())
|
||||||
.tokenUri(github.getTokenUri())
|
.tokenUri(github.getTokenUri())
|
||||||
.userInfoUri(github.getUserInfoUri())
|
.userInfoUri(github.getUserInfoUri())
|
||||||
.userNameAttributeName(github.getUseAsUsername())
|
.userNameAttributeName(github.getUseAsUsername().name())
|
||||||
.clientName(github.getClientName())
|
.clientName(github.getClientName())
|
||||||
.redirectUri(REDIRECT_URI_PATH + github.getName())
|
.redirectUri(REDIRECT_URI_PATH + github.getName())
|
||||||
.authorizationGrantType(AUTHORIZATION_CODE)
|
.authorizationGrantType(AUTHORIZATION_CODE)
|
||||||
@ -171,29 +172,36 @@ public class OAuth2Configuration {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStringEmpty(oauth.getIssuer())
|
|
||||||
|| isStringEmpty(oauth.getClientId())
|
|
||||||
|| isStringEmpty(oauth.getClientSecret())
|
|
||||||
|| isCollectionEmpty(oauth.getScopes())
|
|
||||||
|| isStringEmpty(oauth.getUseAsUsername())) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = oauth.getProvider();
|
String name = oauth.getProvider();
|
||||||
String firstChar = String.valueOf(name.charAt(0));
|
String firstChar = String.valueOf(name.charAt(0));
|
||||||
String clientName = name.replaceFirst(firstChar, firstChar.toUpperCase());
|
String clientName = name.replaceFirst(firstChar, firstChar.toUpperCase());
|
||||||
|
|
||||||
return Optional.of(
|
Provider oidcProvider =
|
||||||
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
|
new Provider(
|
||||||
.registrationId(name)
|
oauth.getIssuer(),
|
||||||
.clientId(oauth.getClientId())
|
name,
|
||||||
.clientSecret(oauth.getClientSecret())
|
clientName,
|
||||||
.scope(oauth.getScopes())
|
oauth.getClientId(),
|
||||||
.userNameAttributeName(oauth.getUseAsUsername())
|
oauth.getClientSecret(),
|
||||||
.clientName(clientName)
|
oauth.getScopes(),
|
||||||
.redirectUri(REDIRECT_URI_PATH + name)
|
UsernameAttribute.valueOf(oauth.getUseAsUsername().toUpperCase()),
|
||||||
.authorizationGrantType(AUTHORIZATION_CODE)
|
null,
|
||||||
.build());
|
null,
|
||||||
|
null);
|
||||||
|
|
||||||
|
return !isStringEmpty(oidcProvider.getIssuer()) || validateProvider(oidcProvider)
|
||||||
|
? Optional.of(
|
||||||
|
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
|
||||||
|
.registrationId(name)
|
||||||
|
.clientId(oidcProvider.getClientId())
|
||||||
|
.clientSecret(oidcProvider.getClientSecret())
|
||||||
|
.scope(oidcProvider.getScopes())
|
||||||
|
.userNameAttributeName(oidcProvider.getUseAsUsername().getName())
|
||||||
|
.clientName(clientName)
|
||||||
|
.redirectUri(REDIRECT_URI_PATH + name)
|
||||||
|
.authorizationGrantType(AUTHORIZATION_CODE)
|
||||||
|
.build())
|
||||||
|
: Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOAuth2Enabled(OAUTH2 oAuth2) {
|
private boolean isOAuth2Enabled(OAUTH2 oAuth2) {
|
||||||
@ -213,8 +221,7 @@ public class OAuth2Configuration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(
|
@ConditionalOnProperty(
|
||||||
value = "security.oauth2.enabled",
|
value = "security.oauth2.enabled",
|
||||||
havingValue = "true",
|
havingValue = "true")
|
||||||
matchIfMissing = false)
|
|
||||||
GrantedAuthoritiesMapper userAuthoritiesMapper() {
|
GrantedAuthoritiesMapper userAuthoritiesMapper() {
|
||||||
return (authorities) -> {
|
return (authorities) -> {
|
||||||
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
|
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
|
||||||
|
@ -140,23 +140,19 @@ public class AccountWebController {
|
|||||||
case "userAlreadyExistsWeb" -> errorOAuth = "userAlreadyExistsWebMessage";
|
case "userAlreadyExistsWeb" -> errorOAuth = "userAlreadyExistsWebMessage";
|
||||||
case "oAuth2AuthenticationErrorWeb" -> errorOAuth = "login.oauth2InvalidUserType";
|
case "oAuth2AuthenticationErrorWeb" -> errorOAuth = "login.oauth2InvalidUserType";
|
||||||
case "invalid_token_response" -> errorOAuth = "login.oauth2InvalidTokenResponse";
|
case "invalid_token_response" -> errorOAuth = "login.oauth2InvalidTokenResponse";
|
||||||
case "authorization_request_not_found" ->
|
case "authorization_request_not_found" -> errorOAuth = "login.oauth2RequestNotFound";
|
||||||
errorOAuth = "login.oauth2RequestNotFound";
|
|
||||||
case "access_denied" -> errorOAuth = "login.oauth2AccessDenied";
|
case "access_denied" -> errorOAuth = "login.oauth2AccessDenied";
|
||||||
case "invalid_user_info_response" ->
|
case "invalid_user_info_response" -> errorOAuth = "login.oauth2InvalidUserInfoResponse";
|
||||||
errorOAuth = "login.oauth2InvalidUserInfoResponse";
|
|
||||||
case "invalid_request" -> errorOAuth = "login.oauth2invalidRequest";
|
case "invalid_request" -> errorOAuth = "login.oauth2invalidRequest";
|
||||||
case "invalid_id_token" -> errorOAuth = "login.oauth2InvalidIdToken";
|
case "invalid_id_token" -> errorOAuth = "login.oauth2InvalidIdToken";
|
||||||
case "oAuth2AdminBlockedUser" -> errorOAuth = "login.oAuth2AdminBlockedUser";
|
case "oAuth2AdminBlockedUser" -> errorOAuth = "login.oAuth2AdminBlockedUser";
|
||||||
case "userIsDisabled" -> errorOAuth = "login.userIsDisabled";
|
case "userIsDisabled" -> errorOAuth = "login.userIsDisabled";
|
||||||
case "invalid_destination" -> errorOAuth = "login.invalid_destination";
|
case "invalid_destination" -> errorOAuth = "login.invalid_destination";
|
||||||
case "relying_party_registration_not_found" ->
|
case "relying_party_registration_not_found" -> errorOAuth = "login.relyingPartyRegistrationNotFound";
|
||||||
errorOAuth = "login.relyingPartyRegistrationNotFound";
|
|
||||||
// Valid InResponseTo was not available from the validation context, unable to
|
// Valid InResponseTo was not available from the validation context, unable to
|
||||||
// evaluate
|
// evaluate
|
||||||
case "invalid_in_response_to" -> errorOAuth = "login.invalid_in_response_to";
|
case "invalid_in_response_to" -> errorOAuth = "login.invalid_in_response_to";
|
||||||
case "not_authentication_provider_found" ->
|
case "not_authentication_provider_found" -> errorOAuth = "login.not_authentication_provider_found";
|
||||||
errorOAuth = "login.not_authentication_provider_found";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model.addAttribute("errorOAuth", errorOAuth);
|
model.addAttribute("errorOAuth", errorOAuth);
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package stirling.software.SPDF.model;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum UsernameAttribute {
|
||||||
|
NAME("name"),
|
||||||
|
EMAIL("email"),
|
||||||
|
GIVEN_NAME("given_name"),
|
||||||
|
PREFERRED_NAME("preferred_name"),
|
||||||
|
PREFERRED_USERNAME("preferred_username"),
|
||||||
|
LOGIN("login"),
|
||||||
|
FAMILY_NAME("family_name"),
|
||||||
|
NICKNAME("nickname");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
UsernameAttribute(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package stirling.software.SPDF.model.exception;
|
||||||
|
|
||||||
|
public class UnsupportedUsernameAttribute extends RuntimeException {
|
||||||
|
public UnsupportedUsernameAttribute(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import stirling.software.SPDF.model.UsernameAttribute;
|
||||||
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class GitHubProvider extends Provider {
|
public class GitHubProvider extends Provider {
|
||||||
@ -15,7 +16,10 @@ public class GitHubProvider extends Provider {
|
|||||||
private static final String USER_INFO_URI = "https://api.github.com/user";
|
private static final String USER_INFO_URI = "https://api.github.com/user";
|
||||||
|
|
||||||
public GitHubProvider(
|
public GitHubProvider(
|
||||||
String clientId, String clientSecret, Collection<String> scopes, String useAsUsername) {
|
String clientId,
|
||||||
|
String clientSecret,
|
||||||
|
Collection<String> scopes,
|
||||||
|
UsernameAttribute useAsUsername) {
|
||||||
super(
|
super(
|
||||||
null,
|
null,
|
||||||
NAME,
|
NAME,
|
||||||
@ -23,7 +27,7 @@ public class GitHubProvider extends Provider {
|
|||||||
clientId,
|
clientId,
|
||||||
clientSecret,
|
clientSecret,
|
||||||
scopes,
|
scopes,
|
||||||
useAsUsername != null ? useAsUsername : "login",
|
useAsUsername != null ? useAsUsername : UsernameAttribute.LOGIN,
|
||||||
AUTHORIZATION_URI,
|
AUTHORIZATION_URI,
|
||||||
TOKEN_URI,
|
TOKEN_URI,
|
||||||
USER_INFO_URI);
|
USER_INFO_URI);
|
||||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import stirling.software.SPDF.model.UsernameAttribute;
|
||||||
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class GoogleProvider extends Provider {
|
public class GoogleProvider extends Provider {
|
||||||
@ -16,7 +17,10 @@ public class GoogleProvider extends Provider {
|
|||||||
"https://www.googleapis.com/oauth2/v3/userinfo?alt=json";
|
"https://www.googleapis.com/oauth2/v3/userinfo?alt=json";
|
||||||
|
|
||||||
public GoogleProvider(
|
public GoogleProvider(
|
||||||
String clientId, String clientSecret, Collection<String> scopes, String useAsUsername) {
|
String clientId,
|
||||||
|
String clientSecret,
|
||||||
|
Collection<String> scopes,
|
||||||
|
UsernameAttribute useAsUsername) {
|
||||||
super(
|
super(
|
||||||
null,
|
null,
|
||||||
NAME,
|
NAME,
|
||||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import stirling.software.SPDF.model.UsernameAttribute;
|
||||||
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class KeycloakProvider extends Provider {
|
public class KeycloakProvider extends Provider {
|
||||||
@ -16,7 +17,7 @@ public class KeycloakProvider extends Provider {
|
|||||||
String clientId,
|
String clientId,
|
||||||
String clientSecret,
|
String clientSecret,
|
||||||
Collection<String> scopes,
|
Collection<String> scopes,
|
||||||
String useAsUsername) {
|
UsernameAttribute useAsUsername) {
|
||||||
super(
|
super(
|
||||||
issuer,
|
issuer,
|
||||||
NAME,
|
NAME,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package stirling.software.SPDF.model.provider;
|
package stirling.software.SPDF.model.provider;
|
||||||
|
|
||||||
import static stirling.software.SPDF.utils.validation.Validator.isStringEmpty;
|
import static stirling.software.SPDF.model.UsernameAttribute.EMAIL;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -9,6 +9,8 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import stirling.software.SPDF.model.UsernameAttribute;
|
||||||
|
import stirling.software.SPDF.model.exception.UnsupportedUsernameAttribute;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ -20,7 +22,7 @@ public class Provider {
|
|||||||
private String clientId;
|
private String clientId;
|
||||||
private String clientSecret;
|
private String clientSecret;
|
||||||
private Collection<String> scopes;
|
private Collection<String> scopes;
|
||||||
private String useAsUsername;
|
private UsernameAttribute useAsUsername;
|
||||||
private String authorizationUri;
|
private String authorizationUri;
|
||||||
private String tokenUri;
|
private String tokenUri;
|
||||||
private String userInfoUri;
|
private String userInfoUri;
|
||||||
@ -32,7 +34,7 @@ public class Provider {
|
|||||||
String clientId,
|
String clientId,
|
||||||
String clientSecret,
|
String clientSecret,
|
||||||
Collection<String> scopes,
|
Collection<String> scopes,
|
||||||
String useAsUsername,
|
UsernameAttribute useAsUsername,
|
||||||
String authorizationUri,
|
String authorizationUri,
|
||||||
String tokenUri,
|
String tokenUri,
|
||||||
String userInfoUri) {
|
String userInfoUri) {
|
||||||
@ -42,7 +44,8 @@ public class Provider {
|
|||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
this.clientSecret = clientSecret;
|
this.clientSecret = clientSecret;
|
||||||
this.scopes = scopes == null ? new ArrayList<>() : scopes;
|
this.scopes = scopes == null ? new ArrayList<>() : scopes;
|
||||||
this.useAsUsername = isStringEmpty(useAsUsername) ? "email" : useAsUsername;
|
this.useAsUsername =
|
||||||
|
useAsUsername != null ? validateUsernameAttribute(useAsUsername) : EMAIL;
|
||||||
this.authorizationUri = authorizationUri;
|
this.authorizationUri = authorizationUri;
|
||||||
this.tokenUri = tokenUri;
|
this.tokenUri = tokenUri;
|
||||||
this.userInfoUri = userInfoUri;
|
this.userInfoUri = userInfoUri;
|
||||||
@ -55,6 +58,69 @@ public class Provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UsernameAttribute validateUsernameAttribute(UsernameAttribute usernameAttribute) {
|
||||||
|
switch (name) {
|
||||||
|
case "google" -> {
|
||||||
|
return validateGoogleUsernameAttribute(usernameAttribute);
|
||||||
|
}
|
||||||
|
case "github" -> {
|
||||||
|
return validateGitHubUsernameAttribute(usernameAttribute);
|
||||||
|
}
|
||||||
|
case "keycloak" -> {
|
||||||
|
return validateKeycloakUsernameAttribute(usernameAttribute);
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
return usernameAttribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private UsernameAttribute validateKeycloakUsernameAttribute(
|
||||||
|
UsernameAttribute usernameAttribute) {
|
||||||
|
switch (usernameAttribute) {
|
||||||
|
case EMAIL, PREFERRED_NAME -> {
|
||||||
|
return usernameAttribute;
|
||||||
|
}
|
||||||
|
default ->
|
||||||
|
throw new UnsupportedUsernameAttribute(
|
||||||
|
"The attribute "
|
||||||
|
+ usernameAttribute
|
||||||
|
+ "is not supported for "
|
||||||
|
+ clientName
|
||||||
|
+ ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private UsernameAttribute validateGoogleUsernameAttribute(UsernameAttribute usernameAttribute) {
|
||||||
|
switch (usernameAttribute) {
|
||||||
|
case EMAIL, NAME, GIVEN_NAME, PREFERRED_NAME -> {
|
||||||
|
return usernameAttribute;
|
||||||
|
}
|
||||||
|
default ->
|
||||||
|
throw new UnsupportedUsernameAttribute(
|
||||||
|
"The attribute "
|
||||||
|
+ usernameAttribute
|
||||||
|
+ "is not supported for "
|
||||||
|
+ clientName
|
||||||
|
+ ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private UsernameAttribute validateGitHubUsernameAttribute(UsernameAttribute usernameAttribute) {
|
||||||
|
switch (usernameAttribute) {
|
||||||
|
case EMAIL, NAME, LOGIN -> {
|
||||||
|
return usernameAttribute;
|
||||||
|
}
|
||||||
|
default ->
|
||||||
|
throw new UnsupportedUsernameAttribute(
|
||||||
|
"The attribute "
|
||||||
|
+ usernameAttribute
|
||||||
|
+ "is not supported for "
|
||||||
|
+ clientName
|
||||||
|
+ ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Provider [name="
|
return "Provider [name="
|
||||||
|
@ -23,10 +23,6 @@ public class Validator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStringEmpty(provider.getUseAsUsername())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import stirling.software.SPDF.model.UsernameAttribute;
|
||||||
import stirling.software.SPDF.model.provider.GitHubProvider;
|
import stirling.software.SPDF.model.provider.GitHubProvider;
|
||||||
import stirling.software.SPDF.model.provider.GoogleProvider;
|
import stirling.software.SPDF.model.provider.GoogleProvider;
|
||||||
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
||||||
@ -28,7 +29,7 @@ class ValidatorTest {
|
|||||||
when(provider.getClientId()).thenReturn("clientId");
|
when(provider.getClientId()).thenReturn("clientId");
|
||||||
when(provider.getClientSecret()).thenReturn("clientSecret");
|
when(provider.getClientSecret()).thenReturn("clientSecret");
|
||||||
when(provider.getScopes()).thenReturn(List.of("read:user"));
|
when(provider.getScopes()).thenReturn(List.of("read:user"));
|
||||||
when(provider.getUseAsUsername()).thenReturn("email");
|
when(provider.getUseAsUsername()).thenReturn(UsernameAttribute.EMAIL);
|
||||||
|
|
||||||
assertTrue(Validator.validateProvider(provider));
|
assertTrue(Validator.validateProvider(provider));
|
||||||
}
|
}
|
||||||
@ -41,9 +42,9 @@ class ValidatorTest {
|
|||||||
|
|
||||||
public static Stream<Arguments> providerParams() {
|
public static Stream<Arguments> providerParams() {
|
||||||
Provider generic = null;
|
Provider generic = null;
|
||||||
var google = new GoogleProvider(null, "clientSecret", List.of("scope"), "email");
|
var google = new GoogleProvider(null, "clientSecret", List.of("scope"), UsernameAttribute.EMAIL);
|
||||||
var github = new GitHubProvider("clientId", "", List.of("scope"), "login");
|
var github = new GitHubProvider("clientId", "", List.of("scope"), UsernameAttribute.LOGIN);
|
||||||
var keycloak = new KeycloakProvider("issuer", "clientId", "clientSecret", List.of("scope"), "email");
|
var keycloak = new KeycloakProvider("issuer", "clientId", "clientSecret", List.of("scope"), UsernameAttribute.EMAIL);
|
||||||
|
|
||||||
keycloak.setUseAsUsername(null);
|
keycloak.setUseAsUsername(null);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user