mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-11-01 01:21:18 +01:00 
			
		
		
		
	added: Differentiate login methods and more (#1471)
- Added Portuguese in the table (README.md) - ApplicationProperties.class diluted, provider outsourced to its own class - Added UnsupportedProviderException to indicate a meaningful error - Closes #1357 - Closes #1238
This commit is contained in:
		
							parent
							
								
									baa9410242
								
							
						
					
					
						commit
						036c10fc27
					
				@ -178,6 +178,7 @@ Stirling PDF currently supports 32!
 | 
			
		||||
| Romanian (Română) (ro_RO)                   |    |
 | 
			
		||||
| Korean (한국어) (ko_KR)                     |    |
 | 
			
		||||
| Portuguese Brazilian (Português) (pt_BR)    |    |
 | 
			
		||||
| Portuguese (Português) (pt_PT)              |    |
 | 
			
		||||
| Russian (Русский) (ru_RU)                   |    |
 | 
			
		||||
| Basque (Euskara) (eu_ES)                    |    |
 | 
			
		||||
| Japanese (日本語) (ja_JP)                   |    |
 | 
			
		||||
 | 
			
		||||
@ -38,12 +38,12 @@ import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationS
 | 
			
		||||
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2LogoutSuccessHandler;
 | 
			
		||||
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties.GithubProvider;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties.GoogleProvider;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties.KeycloakProvider;
 | 
			
		||||
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.provider.GithubProvider;
 | 
			
		||||
import stirling.software.SPDF.model.provider.GoogleProvider;
 | 
			
		||||
import stirling.software.SPDF.model.provider.KeycloakProvider;
 | 
			
		||||
import stirling.software.SPDF.repository.JPATokenRepositoryImpl;
 | 
			
		||||
 | 
			
		||||
@Configuration
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ import jakarta.servlet.http.HttpSession;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
 | 
			
		||||
import stirling.software.SPDF.model.Provider;
 | 
			
		||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
 | 
			
		||||
import stirling.software.SPDF.utils.UrlUtils;
 | 
			
		||||
 | 
			
		||||
public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
 | 
			
		||||
@ -51,8 +52,8 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand
 | 
			
		||||
                Provider provider = oauth.getClient().get(registrationId);
 | 
			
		||||
                issuer = provider.getIssuer();
 | 
			
		||||
                clientId = provider.getClientId();
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                logger.error("exception", e);
 | 
			
		||||
            } catch (UnsupportedProviderException e) {
 | 
			
		||||
                logger.error(e.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
@ -24,14 +24,14 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 | 
			
		||||
 | 
			
		||||
import jakarta.servlet.http.HttpServletRequest;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties.GithubProvider;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties.GoogleProvider;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties.KeycloakProvider;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
 | 
			
		||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
 | 
			
		||||
import stirling.software.SPDF.model.Authority;
 | 
			
		||||
import stirling.software.SPDF.model.Role;
 | 
			
		||||
import stirling.software.SPDF.model.User;
 | 
			
		||||
import stirling.software.SPDF.model.provider.GithubProvider;
 | 
			
		||||
import stirling.software.SPDF.model.provider.GoogleProvider;
 | 
			
		||||
import stirling.software.SPDF.model.provider.KeycloakProvider;
 | 
			
		||||
import stirling.software.SPDF.repository.UserRepository;
 | 
			
		||||
 | 
			
		||||
@Controller
 | 
			
		||||
@ -74,6 +74,7 @@ public class AccountWebController {
 | 
			
		||||
        }
 | 
			
		||||
        model.addAttribute("providerlist", providerList);
 | 
			
		||||
 | 
			
		||||
        model.addAttribute("loginMethod", applicationProperties.getSecurity().getLoginMethod());
 | 
			
		||||
        model.addAttribute(
 | 
			
		||||
                "oAuth2Enabled", applicationProperties.getSecurity().getOAUTH2().getEnabled());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,10 @@ import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.context.annotation.PropertySource;
 | 
			
		||||
 | 
			
		||||
import stirling.software.SPDF.config.YamlPropertySourceFactory;
 | 
			
		||||
import stirling.software.SPDF.model.provider.GithubProvider;
 | 
			
		||||
import stirling.software.SPDF.model.provider.GoogleProvider;
 | 
			
		||||
import stirling.software.SPDF.model.provider.KeycloakProvider;
 | 
			
		||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
 | 
			
		||||
 | 
			
		||||
@Configuration
 | 
			
		||||
@ConfigurationProperties(prefix = "")
 | 
			
		||||
@ -128,6 +132,15 @@ public class ApplicationProperties {
 | 
			
		||||
        private OAUTH2 oauth2;
 | 
			
		||||
        private int loginAttemptCount;
 | 
			
		||||
        private long loginResetTimeMinutes;
 | 
			
		||||
        private String loginMethod = "all";
 | 
			
		||||
 | 
			
		||||
        public String getLoginMethod() {
 | 
			
		||||
            return loginMethod;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setLoginMethod(String loginMethod) {
 | 
			
		||||
            this.loginMethod = loginMethod;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int getLoginAttemptCount() {
 | 
			
		||||
            return loginAttemptCount;
 | 
			
		||||
@ -187,6 +200,8 @@ public class ApplicationProperties {
 | 
			
		||||
                    + initialLogin
 | 
			
		||||
                    + ", csrfDisabled="
 | 
			
		||||
                    + csrfDisabled
 | 
			
		||||
                    + ", loginMethod="
 | 
			
		||||
                    + loginMethod
 | 
			
		||||
                    + "]";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -355,7 +370,7 @@ public class ApplicationProperties {
 | 
			
		||||
                private GithubProvider github = new GithubProvider();
 | 
			
		||||
                private KeycloakProvider keycloak = new KeycloakProvider();
 | 
			
		||||
 | 
			
		||||
                public Provider get(String registrationId) throws Exception {
 | 
			
		||||
                public Provider get(String registrationId) throws UnsupportedProviderException {
 | 
			
		||||
                    switch (registrationId.toLowerCase()) {
 | 
			
		||||
                        case "google":
 | 
			
		||||
                            return getGoogle();
 | 
			
		||||
@ -366,7 +381,8 @@ public class ApplicationProperties {
 | 
			
		||||
                        default:
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                    throw new Exception("Provider not supported, use custom setting.");
 | 
			
		||||
                    throw new UnsupportedProviderException(
 | 
			
		||||
                            "Logout from the provider is not supported? Report it at https://github.com/Stirling-Tools/Stirling-PDF/issues");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                public GoogleProvider getGoogle() {
 | 
			
		||||
@ -407,311 +423,6 @@ public class ApplicationProperties {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class GoogleProvider extends Provider {
 | 
			
		||||
 | 
			
		||||
        private static final String authorizationUri =
 | 
			
		||||
                "https://accounts.google.com/o/oauth2/v2/auth";
 | 
			
		||||
        private static final String tokenUri = "https://www.googleapis.com/oauth2/v4/token";
 | 
			
		||||
        private static final String userInfoUri =
 | 
			
		||||
                "https://www.googleapis.com/oauth2/v3/userinfo?alt=json";
 | 
			
		||||
 | 
			
		||||
        public String getAuthorizationuri() {
 | 
			
		||||
            return authorizationUri;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getTokenuri() {
 | 
			
		||||
            return tokenUri;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getUserinfouri() {
 | 
			
		||||
            return userInfoUri;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private String clientId;
 | 
			
		||||
        private String clientSecret;
 | 
			
		||||
        private Collection<String> scopes = new ArrayList<>();
 | 
			
		||||
        private String useAsUsername = "email";
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getClientId() {
 | 
			
		||||
            return this.clientId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void setClientId(String clientId) {
 | 
			
		||||
            this.clientId = clientId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getClientSecret() {
 | 
			
		||||
            return this.clientSecret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void setClientSecret(String clientSecret) {
 | 
			
		||||
            this.clientSecret = clientSecret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public Collection<String> getScopes() {
 | 
			
		||||
            if (scopes == null || scopes.isEmpty()) {
 | 
			
		||||
                scopes = new ArrayList<>();
 | 
			
		||||
                scopes.add("https://www.googleapis.com/auth/userinfo.email");
 | 
			
		||||
                scopes.add("https://www.googleapis.com/auth/userinfo.profile");
 | 
			
		||||
            }
 | 
			
		||||
            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
 | 
			
		||||
        public String toString() {
 | 
			
		||||
            return "Google [clientId="
 | 
			
		||||
                    + clientId
 | 
			
		||||
                    + ", clientSecret="
 | 
			
		||||
                    + (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
 | 
			
		||||
                    + ", scopes="
 | 
			
		||||
                    + scopes
 | 
			
		||||
                    + ", 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");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class GithubProvider extends Provider {
 | 
			
		||||
        private static final String authorizationUri = "https://github.com/login/oauth/authorize";
 | 
			
		||||
        private static final String tokenUri = "https://github.com/login/oauth/access_token";
 | 
			
		||||
        private static final String userInfoUri = "https://api.github.com/user";
 | 
			
		||||
 | 
			
		||||
        public String getAuthorizationuri() {
 | 
			
		||||
            return authorizationUri;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getTokenuri() {
 | 
			
		||||
            return tokenUri;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getUserinfouri() {
 | 
			
		||||
            return userInfoUri;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private String clientId;
 | 
			
		||||
        private String clientSecret;
 | 
			
		||||
        private Collection<String> scopes = new ArrayList<>();
 | 
			
		||||
        private String useAsUsername = "login";
 | 
			
		||||
 | 
			
		||||
        @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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getClientSecret() {
 | 
			
		||||
            return this.clientSecret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void setClientSecret(String clientSecret) {
 | 
			
		||||
            this.clientSecret = clientSecret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public Collection<String> getScopes() {
 | 
			
		||||
            if (scopes == null || scopes.isEmpty()) {
 | 
			
		||||
                scopes = new ArrayList<>();
 | 
			
		||||
                scopes.add("read:user");
 | 
			
		||||
            }
 | 
			
		||||
            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
 | 
			
		||||
        public String toString() {
 | 
			
		||||
            return "GitHub [clientId="
 | 
			
		||||
                    + clientId
 | 
			
		||||
                    + ", clientSecret="
 | 
			
		||||
                    + (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
 | 
			
		||||
                    + ", scopes="
 | 
			
		||||
                    + scopes
 | 
			
		||||
                    + ", 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");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class KeycloakProvider extends Provider {
 | 
			
		||||
        private String issuer;
 | 
			
		||||
        private String clientId;
 | 
			
		||||
        private String clientSecret;
 | 
			
		||||
        private Collection<String> scopes = new ArrayList<>();
 | 
			
		||||
        private String useAsUsername = "email";
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getIssuer() {
 | 
			
		||||
            return this.issuer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void setIssuer(String issuer) {
 | 
			
		||||
            this.issuer = issuer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getClientId() {
 | 
			
		||||
            return this.clientId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void setClientId(String clientId) {
 | 
			
		||||
            this.clientId = clientId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getClientSecret() {
 | 
			
		||||
            return this.clientSecret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void setClientSecret(String clientSecret) {
 | 
			
		||||
            this.clientSecret = clientSecret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public Collection<String> getScopes() {
 | 
			
		||||
            if (scopes == null || scopes.isEmpty()) {
 | 
			
		||||
                scopes = new ArrayList<>();
 | 
			
		||||
                scopes.add("profile");
 | 
			
		||||
                scopes.add("email");
 | 
			
		||||
            }
 | 
			
		||||
            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
 | 
			
		||||
        public String toString() {
 | 
			
		||||
            return "Keycloak [issuer="
 | 
			
		||||
                    + issuer
 | 
			
		||||
                    + ", clientId="
 | 
			
		||||
                    + clientId
 | 
			
		||||
                    + ", clientSecret="
 | 
			
		||||
                    + (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
 | 
			
		||||
                    + ", scopes="
 | 
			
		||||
                    + scopes
 | 
			
		||||
                    + ", 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");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class System {
 | 
			
		||||
        private String defaultLocale;
 | 
			
		||||
        private Boolean googlevisibility;
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,115 @@
 | 
			
		||||
package stirling.software.SPDF.model.provider;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import stirling.software.SPDF.model.Provider;
 | 
			
		||||
 | 
			
		||||
public class GithubProvider extends Provider {
 | 
			
		||||
 | 
			
		||||
    private static final String authorizationUri = "https://github.com/login/oauth/authorize";
 | 
			
		||||
    private static final String tokenUri = "https://github.com/login/oauth/access_token";
 | 
			
		||||
    private static final String userInfoUri = "https://api.github.com/user";
 | 
			
		||||
 | 
			
		||||
    public String getAuthorizationuri() {
 | 
			
		||||
        return authorizationUri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getTokenuri() {
 | 
			
		||||
        return tokenUri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getUserinfouri() {
 | 
			
		||||
        return userInfoUri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String clientId;
 | 
			
		||||
    private String clientSecret;
 | 
			
		||||
    private Collection<String> scopes = new ArrayList<>();
 | 
			
		||||
    private String useAsUsername = "login";
 | 
			
		||||
 | 
			
		||||
    @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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getClientSecret() {
 | 
			
		||||
        return this.clientSecret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setClientSecret(String clientSecret) {
 | 
			
		||||
        this.clientSecret = clientSecret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Collection<String> getScopes() {
 | 
			
		||||
        if (scopes == null || scopes.isEmpty()) {
 | 
			
		||||
            scopes = new ArrayList<>();
 | 
			
		||||
            scopes.add("read:user");
 | 
			
		||||
        }
 | 
			
		||||
        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
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "GitHub [clientId="
 | 
			
		||||
                + clientId
 | 
			
		||||
                + ", clientSecret="
 | 
			
		||||
                + (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
 | 
			
		||||
                + ", scopes="
 | 
			
		||||
                + scopes
 | 
			
		||||
                + ", 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");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,109 @@
 | 
			
		||||
package stirling.software.SPDF.model.provider;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import stirling.software.SPDF.model.Provider;
 | 
			
		||||
 | 
			
		||||
public class GoogleProvider extends Provider {
 | 
			
		||||
 | 
			
		||||
    private static final String authorizationUri = "https://accounts.google.com/o/oauth2/v2/auth";
 | 
			
		||||
    private static final String tokenUri = "https://www.googleapis.com/oauth2/v4/token";
 | 
			
		||||
    private static final String userInfoUri =
 | 
			
		||||
            "https://www.googleapis.com/oauth2/v3/userinfo?alt=json";
 | 
			
		||||
 | 
			
		||||
    public String getAuthorizationuri() {
 | 
			
		||||
        return authorizationUri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getTokenuri() {
 | 
			
		||||
        return tokenUri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getUserinfouri() {
 | 
			
		||||
        return userInfoUri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String clientId;
 | 
			
		||||
    private String clientSecret;
 | 
			
		||||
    private Collection<String> scopes = new ArrayList<>();
 | 
			
		||||
    private String useAsUsername = "email";
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getClientId() {
 | 
			
		||||
        return this.clientId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setClientId(String clientId) {
 | 
			
		||||
        this.clientId = clientId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getClientSecret() {
 | 
			
		||||
        return this.clientSecret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setClientSecret(String clientSecret) {
 | 
			
		||||
        this.clientSecret = clientSecret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Collection<String> getScopes() {
 | 
			
		||||
        if (scopes == null || scopes.isEmpty()) {
 | 
			
		||||
            scopes = new ArrayList<>();
 | 
			
		||||
            scopes.add("https://www.googleapis.com/auth/userinfo.email");
 | 
			
		||||
            scopes.add("https://www.googleapis.com/auth/userinfo.profile");
 | 
			
		||||
        }
 | 
			
		||||
        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
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "Google [clientId="
 | 
			
		||||
                + clientId
 | 
			
		||||
                + ", clientSecret="
 | 
			
		||||
                + (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
 | 
			
		||||
                + ", scopes="
 | 
			
		||||
                + scopes
 | 
			
		||||
                + ", 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");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,106 @@
 | 
			
		||||
package stirling.software.SPDF.model.provider;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import stirling.software.SPDF.model.Provider;
 | 
			
		||||
 | 
			
		||||
public class KeycloakProvider extends Provider {
 | 
			
		||||
 | 
			
		||||
    private String issuer;
 | 
			
		||||
    private String clientId;
 | 
			
		||||
    private String clientSecret;
 | 
			
		||||
    private Collection<String> scopes = new ArrayList<>();
 | 
			
		||||
    private String useAsUsername = "email";
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getIssuer() {
 | 
			
		||||
        return this.issuer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setIssuer(String issuer) {
 | 
			
		||||
        this.issuer = issuer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getClientId() {
 | 
			
		||||
        return this.clientId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setClientId(String clientId) {
 | 
			
		||||
        this.clientId = clientId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getClientSecret() {
 | 
			
		||||
        return this.clientSecret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setClientSecret(String clientSecret) {
 | 
			
		||||
        this.clientSecret = clientSecret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Collection<String> getScopes() {
 | 
			
		||||
        if (scopes == null || scopes.isEmpty()) {
 | 
			
		||||
            scopes = new ArrayList<>();
 | 
			
		||||
            scopes.add("profile");
 | 
			
		||||
            scopes.add("email");
 | 
			
		||||
        }
 | 
			
		||||
        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
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "Keycloak [issuer="
 | 
			
		||||
                + issuer
 | 
			
		||||
                + ", clientId="
 | 
			
		||||
                + clientId
 | 
			
		||||
                + ", clientSecret="
 | 
			
		||||
                + (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
 | 
			
		||||
                + ", scopes="
 | 
			
		||||
                + scopes
 | 
			
		||||
                + ", 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,7 @@
 | 
			
		||||
package stirling.software.SPDF.model.provider;
 | 
			
		||||
 | 
			
		||||
public class UnsupportedProviderException extends Exception {
 | 
			
		||||
    public UnsupportedProviderException(String message) {
 | 
			
		||||
        super(message);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -114,7 +114,7 @@
 | 
			
		||||
          <img class="mb-4" src="favicon.svg" alt="favicon" width="144" height="144">
 | 
			
		||||
 | 
			
		||||
          <h1 class="h1 mb-3 fw-normal" th:text="${@appName}">Stirling-PDF</h1>
 | 
			
		||||
          <div th:if="${oAuth2Enabled}">
 | 
			
		||||
          <div th:if="${oAuth2Enabled} and (${loginMethod} == 'all' or ${loginMethod} == 'oauth2')">
 | 
			
		||||
            <a href="#" class="w-100 btn btn-lg btn-primary" data-bs-toggle="modal" data-bs-target="#loginsModal" th:text="#{login.ssoSignIn}">Login Via SSO</a>
 | 
			
		||||
            <br>
 | 
			
		||||
            <br>
 | 
			
		||||
@ -134,7 +134,7 @@
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <form th:action="@{login}" method="post">
 | 
			
		||||
        <form th:if="${loginMethod} == 'all' or ${loginMethod} == 'normal'" th:action="@{login}" method="post">
 | 
			
		||||
          <h2 class="h5 mb-3 fw-normal" th:text="#{login.signinTitle}">Please sign in</h2>
 | 
			
		||||
          <div class="form-floating">
 | 
			
		||||
            <input type="text" class="form-control" id="username" name="username" placeholder="admin">
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user