mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-14 03:25:02 +00:00
Refactoring Provider
This commit is contained in:
parent
81c8b9f152
commit
06a5ba892c
@ -3,7 +3,7 @@ package stirling.software.SPDF.config.interfaces;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
import stirling.software.SPDF.utils.FileInfo;
|
import stirling.software.SPDF.utils.FileInfo;
|
||||||
|
|
||||||
public interface DatabaseInterface {
|
public interface DatabaseInterface {
|
||||||
|
@ -15,7 +15,6 @@ import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuc
|
|||||||
|
|
||||||
import com.coveo.saml.SamlClient;
|
import com.coveo.saml.SamlClient;
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
@ -28,8 +27,8 @@ import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrin
|
|||||||
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.SAML2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
||||||
import stirling.software.SPDF.model.Provider;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.provider.Provider;
|
||||||
import stirling.software.SPDF.utils.UrlUtils;
|
import stirling.software.SPDF.utils.UrlUtils;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -41,7 +40,7 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void onLogoutSuccess(
|
public void onLogoutSuccess(
|
||||||
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||||
throws IOException, ServletException {
|
throws IOException {
|
||||||
|
|
||||||
if (!response.isCommitted()) {
|
if (!response.isCommitted()) {
|
||||||
// Handle user logout due to disabled account
|
// Handle user logout due to disabled account
|
||||||
@ -60,30 +59,25 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
// Handle SAML2 logout redirection
|
// Handle SAML2 logout redirection
|
||||||
if (authentication instanceof Saml2Authentication) {
|
if (authentication instanceof Saml2Authentication) {
|
||||||
getRedirect_saml2(request, response, authentication);
|
getRedirect_saml2(request, response, authentication);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// Handle OAuth2 logout redirection
|
// Handle OAuth2 logout redirection
|
||||||
else if (authentication instanceof OAuth2AuthenticationToken) {
|
else if (authentication instanceof OAuth2AuthenticationToken) {
|
||||||
getRedirect_oauth2(request, response, authentication);
|
getRedirect_oauth2(request, response, authentication);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// Handle Username/Password logout
|
// Handle Username/Password logout
|
||||||
else if (authentication instanceof UsernamePasswordAuthenticationToken) {
|
else if (authentication instanceof UsernamePasswordAuthenticationToken) {
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// Handle unknown authentication types
|
// Handle unknown authentication types
|
||||||
else {
|
else {
|
||||||
log.error(
|
log.error(
|
||||||
"authentication class unknown: "
|
"authentication class unknown: {}",
|
||||||
+ authentication.getClass().getSimpleName());
|
authentication.getClass().getSimpleName());
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Redirect to login page after logout
|
// Redirect to login page after logout
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,17 +158,17 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
try {
|
try {
|
||||||
// Get OAuth2 provider details from configuration
|
// Get OAuth2 provider details from configuration
|
||||||
Provider provider = oauth.getClient().get(registrationId);
|
Provider provider = oauth.getClient().get(registrationId);
|
||||||
issuer = provider.getIssuer();
|
|
||||||
clientId = provider.getClientId();
|
|
||||||
} catch (UnsupportedProviderException e) {
|
} catch (UnsupportedProviderException e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
registrationId = oauth.getProvider() != null ? oauth.getProvider() : "";
|
registrationId = oauth.getProvider() != null ? oauth.getProvider() : "";
|
||||||
issuer = oauth.getIssuer();
|
|
||||||
clientId = oauth.getClientId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issuer = oauth.getIssuer();
|
||||||
|
clientId = oauth.getClientId();
|
||||||
String errorMessage = "";
|
String errorMessage = "";
|
||||||
|
|
||||||
// Handle different error scenarios during logout
|
// Handle different error scenarios during logout
|
||||||
if (request.getParameter("oauth2AuthenticationErrorWeb") != null) {
|
if (request.getParameter("oauth2AuthenticationErrorWeb") != null) {
|
||||||
param = "erroroauth=oauth2AuthenticationErrorWeb";
|
param = "erroroauth=oauth2AuthenticationErrorWeb";
|
||||||
@ -196,7 +190,7 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
|
|
||||||
// Redirect based on OAuth2 provider
|
// Redirect based on OAuth2 provider
|
||||||
switch (registrationId.toLowerCase()) {
|
switch (registrationId.toLowerCase()) {
|
||||||
case "keycloak":
|
case "keycloak" -> {
|
||||||
// Add Keycloak specific logout URL if needed
|
// Add Keycloak specific logout URL if needed
|
||||||
String logoutUrl =
|
String logoutUrl =
|
||||||
issuer
|
issuer
|
||||||
@ -207,27 +201,28 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
+ response.encodeRedirectURL(redirect_url);
|
+ response.encodeRedirectURL(redirect_url);
|
||||||
log.info("Redirecting to Keycloak logout URL: " + logoutUrl);
|
log.info("Redirecting to Keycloak logout URL: " + logoutUrl);
|
||||||
response.sendRedirect(logoutUrl);
|
response.sendRedirect(logoutUrl);
|
||||||
break;
|
}
|
||||||
case "github":
|
case "github" -> {
|
||||||
// Add GitHub specific logout URL if needed
|
// Add GitHub specific logout URL if needed
|
||||||
|
// todo: why does the redirect go to github? shouldn't it come to Stirling PDF?
|
||||||
String githubLogoutUrl = "https://github.com/logout";
|
String githubLogoutUrl = "https://github.com/logout";
|
||||||
log.info("Redirecting to GitHub logout URL: " + githubLogoutUrl);
|
log.info("Redirecting to GitHub logout URL: " + redirect_url);
|
||||||
response.sendRedirect(githubLogoutUrl);
|
response.sendRedirect(redirect_url);
|
||||||
break;
|
}
|
||||||
case "google":
|
case "google" -> {
|
||||||
// Add Google specific logout URL if needed
|
// Add Google specific logout URL if needed
|
||||||
// String googleLogoutUrl =
|
// String googleLogoutUrl =
|
||||||
// "https://accounts.google.com/Logout?continue=https://appengine.google.com/_ah/logout?continue="
|
// "https://accounts.google.com/Logout?continue=https://appengine.google.com/_ah/logout?continue="
|
||||||
// + response.encodeRedirectURL(redirect_url);
|
// + response.encodeRedirectURL(redirect_url);
|
||||||
log.info("Google does not have a specific logout URL");
|
log.info("Google does not have a specific logout URL");
|
||||||
// log.info("Redirecting to Google logout URL: " + googleLogoutUrl);
|
// log.info("Redirecting to Google logout URL: " + googleLogoutUrl);
|
||||||
// response.sendRedirect(googleLogoutUrl);
|
// response.sendRedirect(googleLogoutUrl);
|
||||||
// break;
|
}
|
||||||
default:
|
default -> {
|
||||||
String defaultRedirectUrl = request.getContextPath() + "/login?" + param;
|
String defaultRedirectUrl = request.getContextPath() + "/login?" + param;
|
||||||
log.info("Redirecting to default logout URL: " + defaultRedirectUrl);
|
log.info("Redirecting to default logout URL: {}", defaultRedirectUrl);
|
||||||
response.sendRedirect(defaultRedirectUrl);
|
response.sendRedirect(defaultRedirectUrl);
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
|
@ -27,7 +27,7 @@ import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrin
|
|||||||
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
||||||
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
||||||
import stirling.software.SPDF.model.*;
|
import stirling.software.SPDF.model.*;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
import stirling.software.SPDF.repository.AuthorityRepository;
|
import stirling.software.SPDF.repository.AuthorityRepository;
|
||||||
import stirling.software.SPDF.repository.UserRepository;
|
import stirling.software.SPDF.repository.UserRepository;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
|
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -8,7 +8,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
||||||
import stirling.software.SPDF.controller.api.H2SQLCondition;
|
import stirling.software.SPDF.controller.api.H2SQLCondition;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Conditional(H2SQLCondition.class)
|
@Conditional(H2SQLCondition.class)
|
||||||
|
@ -20,7 +20,7 @@ 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.AuthenticationType;
|
import stirling.software.SPDF.model.AuthenticationType;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
public class CustomOAuth2AuthenticationSuccessHandler
|
public class CustomOAuth2AuthenticationSuccessHandler
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package stirling.software.SPDF.config.security.oauth2;
|
package stirling.software.SPDF.config.security.oauth2;
|
||||||
|
|
||||||
|
import static org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -30,11 +32,13 @@ 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;
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
@ConditionalOnProperty(value = "security.oauth2.enabled", havingValue = "true")
|
@ConditionalOnProperty(value = "security.oauth2.enabled", havingValue = "true")
|
||||||
public class OAuth2Configuration {
|
public class OAuth2Configuration {
|
||||||
|
|
||||||
|
public static final String REDIRECT_URI_PATH = "{baseUrl}/login/oauth2/code/";
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
@Lazy private final UserService userService;
|
@Lazy private final UserService userService;
|
||||||
|
|
||||||
@ -62,13 +66,17 @@ public class OAuth2Configuration {
|
|||||||
|
|
||||||
private Optional<ClientRegistration> googleClientRegistration() {
|
private Optional<ClientRegistration> googleClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
if (oauth == null || !oauth.getEnabled()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
Client client = oauth.getClient();
|
Client client = oauth.getClient();
|
||||||
|
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
GoogleProvider google = client.getGoogle();
|
GoogleProvider google = client.getGoogle();
|
||||||
return google != null && google.isSettingsValid()
|
return google != null && google.isSettingsValid()
|
||||||
? Optional.of(
|
? Optional.of(
|
||||||
@ -76,15 +84,13 @@ public class OAuth2Configuration {
|
|||||||
.clientId(google.getClientId())
|
.clientId(google.getClientId())
|
||||||
.clientSecret(google.getClientSecret())
|
.clientSecret(google.getClientSecret())
|
||||||
.scope(google.getScopes())
|
.scope(google.getScopes())
|
||||||
.authorizationUri(google.getAuthorizationuri())
|
.authorizationUri(google.getAuthorizationUri())
|
||||||
.tokenUri(google.getTokenuri())
|
.tokenUri(google.getTokenUri())
|
||||||
.userInfoUri(google.getUserinfouri())
|
.userInfoUri(google.getUserinfoUri())
|
||||||
.userNameAttributeName(google.getUseAsUsername())
|
.userNameAttributeName(google.getUseAsUsername())
|
||||||
.clientName(google.getClientName())
|
.clientName(google.getClientName())
|
||||||
.redirectUri("{baseUrl}/login/oauth2/code/" + google.getName())
|
.redirectUri(REDIRECT_URI_PATH + google.getName())
|
||||||
.authorizationGrantType(
|
.authorizationGrantType(AUTHORIZATION_CODE)
|
||||||
org.springframework.security.oauth2.core
|
|
||||||
.AuthorizationGrantType.AUTHORIZATION_CODE)
|
|
||||||
.build())
|
.build())
|
||||||
: Optional.empty();
|
: Optional.empty();
|
||||||
}
|
}
|
||||||
@ -113,36 +119,33 @@ public class OAuth2Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> githubClientRegistration() {
|
private Optional<ClientRegistration> githubClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
if (isOauthOrClientEmpty()) {
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
Client client = oauth.getClient();
|
|
||||||
if (client == null) {
|
GithubProvider github =
|
||||||
return Optional.empty();
|
applicationProperties.getSecurity().getOauth2().getClient().getGithub();
|
||||||
}
|
|
||||||
GithubProvider github = client.getGithub();
|
|
||||||
return github != null && github.isSettingsValid()
|
return github != null && github.isSettingsValid()
|
||||||
? Optional.of(
|
? Optional.of(
|
||||||
ClientRegistration.withRegistrationId(github.getName())
|
ClientRegistration.withRegistrationId(github.getName())
|
||||||
.clientId(github.getClientId())
|
.clientId(github.getClientId())
|
||||||
.clientSecret(github.getClientSecret())
|
.clientSecret(github.getClientSecret())
|
||||||
.scope(github.getScopes())
|
.scope(github.getScopes())
|
||||||
.authorizationUri(github.getAuthorizationuri())
|
.authorizationUri(github.getAuthorizationUri())
|
||||||
.tokenUri(github.getTokenuri())
|
.tokenUri(github.getTokenUri())
|
||||||
.userInfoUri(github.getUserinfouri())
|
.userInfoUri(github.getUserinfoUri())
|
||||||
.userNameAttributeName(github.getUseAsUsername())
|
.userNameAttributeName(github.getUseAsUsername())
|
||||||
.clientName(github.getClientName())
|
.clientName(github.getClientName())
|
||||||
.redirectUri("{baseUrl}/login/oauth2/code/" + github.getName())
|
.redirectUri(REDIRECT_URI_PATH + github.getName())
|
||||||
.authorizationGrantType(
|
.authorizationGrantType(AUTHORIZATION_CODE)
|
||||||
org.springframework.security.oauth2.core
|
|
||||||
.AuthorizationGrantType.AUTHORIZATION_CODE)
|
|
||||||
.build())
|
.build())
|
||||||
: Optional.empty();
|
: Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> oidcClientRegistration() {
|
private Optional<ClientRegistration> oidcClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
if (oauth == null
|
if (oauth == null
|
||||||
|| oauth.getIssuer() == null
|
|| oauth.getIssuer() == null
|
||||||
|| oauth.getIssuer().isEmpty()
|
|| oauth.getIssuer().isEmpty()
|
||||||
@ -156,6 +159,7 @@ public class OAuth2Configuration {
|
|||||||
|| oauth.getUseAsUsername().isEmpty()) {
|
|| oauth.getUseAsUsername().isEmpty()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.of(
|
return Optional.of(
|
||||||
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
|
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
|
||||||
.registrationId("oidc")
|
.registrationId("oidc")
|
||||||
@ -164,13 +168,23 @@ public class OAuth2Configuration {
|
|||||||
.scope(oauth.getScopes())
|
.scope(oauth.getScopes())
|
||||||
.userNameAttributeName(oauth.getUseAsUsername())
|
.userNameAttributeName(oauth.getUseAsUsername())
|
||||||
.clientName("OIDC")
|
.clientName("OIDC")
|
||||||
.redirectUri("{baseUrl}/login/oauth2/code/oidc")
|
.redirectUri(REDIRECT_URI_PATH + "oidc")
|
||||||
.authorizationGrantType(
|
.authorizationGrantType(AUTHORIZATION_CODE)
|
||||||
org.springframework.security.oauth2.core.AuthorizationGrantType
|
|
||||||
.AUTHORIZATION_CODE)
|
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isOauthOrClientEmpty() {
|
||||||
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
|
if (oauth == null || !oauth.getEnabled()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client client = oauth.getClient();
|
||||||
|
|
||||||
|
return client != null;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This following function is to grant Authorities to the OAUTH2 user from the values stored in the database.
|
This following function is to grant Authorities to the OAUTH2 user from the values stored in the database.
|
||||||
This is required for the internal; 'hasRole()' function to give out the correct role.
|
This is required for the internal; 'hasRole()' function to give out the correct role.
|
||||||
|
@ -21,7 +21,7 @@ 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.SAML2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
||||||
import stirling.software.SPDF.model.AuthenticationType;
|
import stirling.software.SPDF.model.AuthenticationType;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -36,7 +36,7 @@ import stirling.software.SPDF.model.AuthenticationType;
|
|||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
import stirling.software.SPDF.model.api.user.UsernameAndPass;
|
import stirling.software.SPDF.model.api.user.UsernameAndPass;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@Tag(name = "User", description = "User APIs")
|
@Tag(name = "User", description = "User APIs")
|
||||||
|
@ -39,6 +39,7 @@ import stirling.software.SPDF.repository.UserRepository;
|
|||||||
@Tag(name = "Account Security", description = "Account Security APIs")
|
@Tag(name = "Account Security", description = "Account Security APIs")
|
||||||
public class AccountWebController {
|
public class AccountWebController {
|
||||||
|
|
||||||
|
public static final String OAUTH_2_AUTHORIZATION = "/oauth2/authorization/";
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
private final SessionPersistentRegistry sessionPersistentRegistry;
|
private final SessionPersistentRegistry sessionPersistentRegistry;
|
||||||
@ -67,26 +68,24 @@ public class AccountWebController {
|
|||||||
if (oauth != null) {
|
if (oauth != null) {
|
||||||
if (oauth.getEnabled()) {
|
if (oauth.getEnabled()) {
|
||||||
if (oauth.isSettingsValid()) {
|
if (oauth.isSettingsValid()) {
|
||||||
providerList.put("/oauth2/authorization/oidc", oauth.getProvider());
|
providerList.put(OAUTH_2_AUTHORIZATION + "oidc", oauth.getProvider());
|
||||||
}
|
}
|
||||||
Client client = oauth.getClient();
|
Client client = oauth.getClient();
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
GoogleProvider google = client.getGoogle();
|
GoogleProvider google = client.getGoogle();
|
||||||
if (google.isSettingsValid()) {
|
if (google.isSettingsValid()) {
|
||||||
providerList.put(
|
providerList.put(
|
||||||
"/oauth2/authorization/" + google.getName(),
|
OAUTH_2_AUTHORIZATION + google.getName(), google.getClientName());
|
||||||
google.getClientName());
|
|
||||||
}
|
}
|
||||||
GithubProvider github = client.getGithub();
|
GithubProvider github = client.getGithub();
|
||||||
if (github.isSettingsValid()) {
|
if (github.isSettingsValid()) {
|
||||||
providerList.put(
|
providerList.put(
|
||||||
"/oauth2/authorization/" + github.getName(),
|
OAUTH_2_AUTHORIZATION + github.getName(), github.getClientName());
|
||||||
github.getClientName());
|
|
||||||
}
|
}
|
||||||
KeycloakProvider keycloak = client.getKeycloak();
|
KeycloakProvider keycloak = client.getKeycloak();
|
||||||
if (keycloak.isSettingsValid()) {
|
if (keycloak.isSettingsValid()) {
|
||||||
providerList.put(
|
providerList.put(
|
||||||
"/oauth2/authorization/" + keycloak.getName(),
|
OAUTH_2_AUTHORIZATION + keycloak.getName(),
|
||||||
keycloak.getClientName());
|
keycloak.getClientName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,7 +102,7 @@ public class AccountWebController {
|
|||||||
.removeIf(entry -> entry.getKey() == null || entry.getValue() == null);
|
.removeIf(entry -> entry.getKey() == null || entry.getValue() == null);
|
||||||
model.addAttribute("providerlist", providerList);
|
model.addAttribute("providerlist", providerList);
|
||||||
model.addAttribute("loginMethod", securityProps.getLoginMethod());
|
model.addAttribute("loginMethod", securityProps.getLoginMethod());
|
||||||
boolean altLogin = providerList.size() > 0 ? securityProps.isAltLogin() : false;
|
boolean altLogin = !providerList.isEmpty() ? securityProps.isAltLogin() : false;
|
||||||
model.addAttribute("altLogin", altLogin);
|
model.addAttribute("altLogin", altLogin);
|
||||||
model.addAttribute("currentPage", "login");
|
model.addAttribute("currentPage", "login");
|
||||||
String error = request.getParameter("error");
|
String error = request.getParameter("error");
|
||||||
|
@ -34,10 +34,11 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
|
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
import stirling.software.SPDF.config.YamlPropertySourceFactory;
|
import stirling.software.SPDF.config.YamlPropertySourceFactory;
|
||||||
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
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;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.provider.Provider;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConfigurationProperties(prefix = "")
|
@ConfigurationProperties(prefix = "")
|
||||||
@ -230,7 +231,7 @@ public class ApplicationProperties {
|
|||||||
List<String> scopesList =
|
List<String> scopesList =
|
||||||
Arrays.stream(scopes.split(","))
|
Arrays.stream(scopes.split(","))
|
||||||
.map(String::trim)
|
.map(String::trim)
|
||||||
.collect(Collectors.toList());
|
.toList();
|
||||||
this.scopes.addAll(scopesList);
|
this.scopes.addAll(scopesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,18 +258,13 @@ public class ApplicationProperties {
|
|||||||
private KeycloakProvider keycloak = new KeycloakProvider();
|
private KeycloakProvider keycloak = new KeycloakProvider();
|
||||||
|
|
||||||
public Provider get(String registrationId) throws UnsupportedProviderException {
|
public Provider get(String registrationId) throws UnsupportedProviderException {
|
||||||
switch (registrationId.toLowerCase()) {
|
return switch (registrationId.toLowerCase()) {
|
||||||
case "google":
|
case "google" -> getGoogle();
|
||||||
return getGoogle();
|
case "github" -> getGithub();
|
||||||
case "github":
|
case "keycloak" -> getKeycloak();
|
||||||
return getGithub();
|
default -> throw new UnsupportedProviderException(
|
||||||
case "keycloak":
|
"Logout from the provider is not supported. Report it at https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
||||||
return getKeycloak();
|
};
|
||||||
default:
|
|
||||||
throw new UnsupportedProviderException(
|
|
||||||
"Logout from the provider is not supported? Report it at"
|
|
||||||
+ " https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,10 +331,10 @@ public class ApplicationProperties {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return """
|
return """
|
||||||
Driver {
|
Driver {
|
||||||
driverName='%s'
|
driverName='%s'
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
.formatted(driverName);
|
.formatted(driverName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
package stirling.software.SPDF.model;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class Provider implements ProviderInterface {
|
|
||||||
private String name;
|
|
||||||
private String clientName;
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientName() {
|
|
||||||
return clientName;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isValid(String value, String name) {
|
|
||||||
if (value != null && !value.trim().isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isValid(Collection<String> value, String name) {
|
|
||||||
if (value != null && !value.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<String> getScopes() {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getScope'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setScopes(String scopes) {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'setScope'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUseAsUsername() {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getUseAsUsername'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUseAsUsername(String useAsUsername) {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'setUseAsUsername'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIssuer() {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getIssuer'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setIssuer(String issuer) {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'setIssuer'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientSecret() {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getClientSecret'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setClientSecret(String clientSecret) {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'setClientSecret'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientId() {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getClientId'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setClientId(String clientId) {
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'setClientId'");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package stirling.software.SPDF.model;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public interface ProviderInterface {
|
|
||||||
|
|
||||||
public Collection<String> getScopes();
|
|
||||||
|
|
||||||
public void setScopes(String scopes);
|
|
||||||
|
|
||||||
public String getUseAsUsername();
|
|
||||||
|
|
||||||
public void setUseAsUsername(String useAsUsername);
|
|
||||||
|
|
||||||
public String getIssuer();
|
|
||||||
|
|
||||||
public void setIssuer(String issuer);
|
|
||||||
|
|
||||||
public String getClientSecret();
|
|
||||||
|
|
||||||
public void setClientSecret(String clientSecret);
|
|
||||||
|
|
||||||
public String getClientId();
|
|
||||||
|
|
||||||
public void setClientId(String clientId);
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package stirling.software.SPDF.model.provider;
|
package stirling.software.SPDF.model.exception;
|
||||||
|
|
||||||
public class UnsupportedProviderException extends Exception {
|
public class UnsupportedProviderException extends Exception {
|
||||||
public UnsupportedProviderException(String message) {
|
public UnsupportedProviderException(String message) {
|
@ -1,60 +1,44 @@
|
|||||||
package stirling.software.SPDF.model.provider;
|
package stirling.software.SPDF.model.provider;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.Provider;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
// @Setter
|
||||||
|
@NoArgsConstructor
|
||||||
public class GithubProvider extends Provider {
|
public class GithubProvider extends Provider {
|
||||||
|
|
||||||
private static final String authorizationUri = "https://github.com/login/oauth/authorize";
|
private static final String NAME = "github";
|
||||||
private static final String tokenUri = "https://github.com/login/oauth/access_token";
|
private static final String CLIENT_NAME = "GitHub";
|
||||||
private static final String userInfoUri = "https://api.github.com/user";
|
private static final String AUTHORIZATION_URI = "https://github.com/login/oauth/authorize";
|
||||||
|
private static final String TOKEN_URI = "https://github.com/login/oauth/access_token";
|
||||||
|
private static final String USER_INFO_URI = "https://api.github.com/user";
|
||||||
|
|
||||||
private String clientId;
|
private String clientId;
|
||||||
private String clientSecret;
|
private String clientSecret;
|
||||||
private Collection<String> scopes = new ArrayList<>();
|
private Collection<String> scopes = new ArrayList<>();
|
||||||
private String useAsUsername = "login";
|
private String useAsUsername = "login";
|
||||||
|
|
||||||
public String getAuthorizationuri() {
|
public GithubProvider(
|
||||||
return authorizationUri;
|
String clientId, String clientSecret, Collection<String> scopes, String useAsUsername) {
|
||||||
}
|
super(null, NAME, CLIENT_NAME, clientId, clientSecret, scopes, useAsUsername);
|
||||||
|
|
||||||
public String getTokenuri() {
|
|
||||||
return tokenUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserinfouri() {
|
|
||||||
return userInfoUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIssuer() {
|
|
||||||
return new String();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setIssuer(String issuer) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientId() {
|
|
||||||
return this.clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setClientId(String clientId) {
|
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientSecret() {
|
|
||||||
return this.clientSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setClientSecret(String clientSecret) {
|
|
||||||
this.clientSecret = clientSecret;
|
this.clientSecret = clientSecret;
|
||||||
|
this.scopes = scopes;
|
||||||
|
this.useAsUsername = useAsUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthorizationUri() {
|
||||||
|
return AUTHORIZATION_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTokenUri() {
|
||||||
|
return TOKEN_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserinfoUri() {
|
||||||
|
return USER_INFO_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -66,22 +50,6 @@ public class GithubProvider extends Provider {
|
|||||||
return scopes;
|
return scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setScopes(String scopes) {
|
|
||||||
this.scopes =
|
|
||||||
Arrays.stream(scopes.split(",")).map(String::trim).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUseAsUsername() {
|
|
||||||
return this.useAsUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUseAsUsername(String useAsUsername) {
|
|
||||||
this.useAsUsername = useAsUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "GitHub [clientId="
|
return "GitHub [clientId="
|
||||||
@ -94,21 +62,4 @@ public class GithubProvider extends Provider {
|
|||||||
+ useAsUsername
|
+ useAsUsername
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "github";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientName() {
|
|
||||||
return "GitHub";
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSettingsValid() {
|
|
||||||
return super.isValid(this.getClientId(), "clientId")
|
|
||||||
&& super.isValid(this.getClientSecret(), "clientSecret")
|
|
||||||
&& super.isValid(this.getScopes(), "scopes")
|
|
||||||
&& isValid(this.getUseAsUsername(), "useAsUsername");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,61 +1,45 @@
|
|||||||
package stirling.software.SPDF.model.provider;
|
package stirling.software.SPDF.model.provider;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.Provider;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
// @Setter
|
||||||
|
@NoArgsConstructor
|
||||||
public class GoogleProvider extends Provider {
|
public class GoogleProvider extends Provider {
|
||||||
|
|
||||||
private static final String authorizationUri = "https://accounts.google.com/o/oauth2/v2/auth";
|
private static final String NAME = "google";
|
||||||
private static final String tokenUri = "https://www.googleapis.com/oauth2/v4/token";
|
private static final String CLIENT_NAME = "Google";
|
||||||
private static final String userInfoUri =
|
private static final String AUTHORIZATION_URI = "https://accounts.google.com/o/oauth2/v2/auth";
|
||||||
|
private static final String TOKEN_URI = "https://www.googleapis.com/oauth2/v4/token";
|
||||||
|
private static final String USER_INFO_URI =
|
||||||
"https://www.googleapis.com/oauth2/v3/userinfo?alt=json";
|
"https://www.googleapis.com/oauth2/v3/userinfo?alt=json";
|
||||||
|
|
||||||
private String clientId;
|
private String clientId;
|
||||||
private String clientSecret;
|
private String clientSecret;
|
||||||
private Collection<String> scopes = new ArrayList<>();
|
private Collection<String> scopes = new ArrayList<>();
|
||||||
private String useAsUsername = "email";
|
private String useAsUsername = "email";
|
||||||
|
|
||||||
public String getAuthorizationuri() {
|
public GoogleProvider(
|
||||||
return authorizationUri;
|
String clientId, String clientSecret, Collection<String> scopes, String useAsUsername) {
|
||||||
}
|
super(null, NAME, CLIENT_NAME, clientId, clientSecret, scopes, useAsUsername);
|
||||||
|
|
||||||
public String getTokenuri() {
|
|
||||||
return tokenUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserinfouri() {
|
|
||||||
return userInfoUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIssuer() {
|
|
||||||
return new String();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setIssuer(String issuer) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientId() {
|
|
||||||
return this.clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setClientId(String clientId) {
|
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientSecret() {
|
|
||||||
return this.clientSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setClientSecret(String clientSecret) {
|
|
||||||
this.clientSecret = clientSecret;
|
this.clientSecret = clientSecret;
|
||||||
|
this.scopes = scopes;
|
||||||
|
this.useAsUsername = useAsUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthorizationUri() {
|
||||||
|
return AUTHORIZATION_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTokenUri() {
|
||||||
|
return TOKEN_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserinfoUri() {
|
||||||
|
return USER_INFO_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -68,22 +52,6 @@ public class GoogleProvider extends Provider {
|
|||||||
return scopes;
|
return scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setScopes(String scopes) {
|
|
||||||
this.scopes =
|
|
||||||
Arrays.stream(scopes.split(",")).map(String::trim).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUseAsUsername() {
|
|
||||||
return this.useAsUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUseAsUsername(String useAsUsername) {
|
|
||||||
this.useAsUsername = useAsUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Google [clientId="
|
return "Google [clientId="
|
||||||
@ -96,21 +64,4 @@ public class GoogleProvider extends Provider {
|
|||||||
+ useAsUsername
|
+ useAsUsername
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "google";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientName() {
|
|
||||||
return "Google";
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSettingsValid() {
|
|
||||||
return super.isValid(this.getClientId(), "clientId")
|
|
||||||
&& super.isValid(this.getClientSecret(), "clientSecret")
|
|
||||||
&& super.isValid(this.getScopes(), "scopes")
|
|
||||||
&& isValid(this.getUseAsUsername(), "useAsUsername");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,76 +1,50 @@
|
|||||||
package stirling.software.SPDF.model.provider;
|
package stirling.software.SPDF.model.provider;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.Provider;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
// @Setter
|
||||||
|
@NoArgsConstructor
|
||||||
public class KeycloakProvider extends Provider {
|
public class KeycloakProvider extends Provider {
|
||||||
|
|
||||||
|
private static final String NAME = "keycloak";
|
||||||
|
private static final String CLIENT_NAME = "Keycloak";
|
||||||
|
|
||||||
private String issuer;
|
private String issuer;
|
||||||
private String clientId;
|
private String clientId;
|
||||||
private String clientSecret;
|
private String clientSecret;
|
||||||
private Collection<String> scopes = new ArrayList<>();
|
private Collection<String> scopes;
|
||||||
private String useAsUsername = "email";
|
private String useAsUsername = "email";
|
||||||
|
|
||||||
@Override
|
public KeycloakProvider(
|
||||||
public String getIssuer() {
|
String issuer,
|
||||||
return this.issuer;
|
String clientId,
|
||||||
}
|
String clientSecret,
|
||||||
|
Collection<String> scopes,
|
||||||
@Override
|
String useAsUsername) {
|
||||||
public void setIssuer(String issuer) {
|
super(issuer, NAME, CLIENT_NAME, clientId, clientSecret, scopes, useAsUsername);
|
||||||
|
this.useAsUsername = useAsUsername;
|
||||||
this.issuer = issuer;
|
this.issuer = issuer;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientId() {
|
|
||||||
return this.clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setClientId(String clientId) {
|
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientSecret() {
|
|
||||||
return this.clientSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setClientSecret(String clientSecret) {
|
|
||||||
this.clientSecret = clientSecret;
|
this.clientSecret = clientSecret;
|
||||||
|
this.scopes = scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getScopes() {
|
public Collection<String> getScopes() {
|
||||||
|
var scopes = super.getScopes();
|
||||||
|
|
||||||
if (scopes == null || scopes.isEmpty()) {
|
if (scopes == null || scopes.isEmpty()) {
|
||||||
scopes = new ArrayList<>();
|
scopes = new ArrayList<>();
|
||||||
scopes.add("profile");
|
scopes.add("profile");
|
||||||
scopes.add("email");
|
scopes.add("email");
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes;
|
return scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setScopes(String scopes) {
|
|
||||||
this.scopes =
|
|
||||||
Arrays.stream(scopes.split(",")).map(String::trim).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUseAsUsername() {
|
|
||||||
return this.useAsUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUseAsUsername(String useAsUsername) {
|
|
||||||
this.useAsUsername = useAsUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Keycloak [issuer="
|
return "Keycloak [issuer="
|
||||||
@ -78,29 +52,11 @@ public class KeycloakProvider extends Provider {
|
|||||||
+ ", clientId="
|
+ ", clientId="
|
||||||
+ clientId
|
+ clientId
|
||||||
+ ", clientSecret="
|
+ ", clientSecret="
|
||||||
+ (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
|
+ (clientSecret != null && !clientSecret.isBlank() ? "MASKED" : "NULL")
|
||||||
+ ", scopes="
|
+ ", scopes="
|
||||||
+ scopes
|
+ scopes
|
||||||
+ ", useAsUsername="
|
+ ", useAsUsername="
|
||||||
+ useAsUsername
|
+ useAsUsername
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "keycloak";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClientName() {
|
|
||||||
return "Keycloak";
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSettingsValid() {
|
|
||||||
return isValid(this.getIssuer(), "issuer")
|
|
||||||
&& isValid(this.getClientId(), "clientId")
|
|
||||||
&& isValid(this.getClientSecret(), "clientSecret")
|
|
||||||
&& isValid(this.getScopes(), "scopes")
|
|
||||||
&& isValid(this.getUseAsUsername(), "useAsUsername");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
package stirling.software.SPDF.model.provider;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
public abstract class Provider {
|
||||||
|
|
||||||
|
private String issuer;
|
||||||
|
private String name;
|
||||||
|
private String clientName;
|
||||||
|
private String clientId;
|
||||||
|
private String clientSecret;
|
||||||
|
private Collection<String> scopes;
|
||||||
|
private String useAsUsername;
|
||||||
|
|
||||||
|
public Provider(
|
||||||
|
String issuer,
|
||||||
|
String name,
|
||||||
|
String clientName,
|
||||||
|
String clientId,
|
||||||
|
String clientSecret,
|
||||||
|
Collection<String> scopes,
|
||||||
|
String useAsUsername) {
|
||||||
|
this.issuer = issuer;
|
||||||
|
this.name = name;
|
||||||
|
this.clientName = clientName;
|
||||||
|
this.clientId = clientId;
|
||||||
|
this.clientSecret = clientSecret;
|
||||||
|
this.scopes = scopes;
|
||||||
|
this.useAsUsername = !useAsUsername.isBlank() ? useAsUsername : "email";
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: why are we passing name here if it's not used?
|
||||||
|
public boolean isSettingsValid() {
|
||||||
|
return isValid(this.getIssuer(), "issuer")
|
||||||
|
&& isValid(this.getClientId(), "clientId")
|
||||||
|
&& isValid(this.getClientSecret(), "clientSecret")
|
||||||
|
&& isValid(this.getScopes(), "scopes")
|
||||||
|
&& isValid(this.getUseAsUsername(), "useAsUsername");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValid(String value, String name) {
|
||||||
|
return value != null && !value.isBlank();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValid(Collection<String> value, String name) {
|
||||||
|
return value != null && !value.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIssuer(String issuer) {
|
||||||
|
this.issuer = issuer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientName(String clientName) {
|
||||||
|
this.clientName = clientName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(String clientId) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientSecret(String clientSecret) {
|
||||||
|
this.clientSecret = clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScopes(String scopes) {
|
||||||
|
this.scopes =
|
||||||
|
Arrays.stream(scopes.split(",")).map(String::trim).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseAsUsername(String useAsUsername) {
|
||||||
|
this.useAsUsername = useAsUsername;
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ import org.junit.jupiter.params.provider.ValueSource;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user