diff --git a/src/main/java/stirling/software/SPDF/config/AppConfig.java b/src/main/java/stirling/software/SPDF/config/AppConfig.java index a3379df3..2cae2f54 100644 --- a/src/main/java/stirling/software/SPDF/config/AppConfig.java +++ b/src/main/java/stirling/software/SPDF/config/AppConfig.java @@ -34,10 +34,7 @@ public class AppConfig { } @Bean - @ConditionalOnProperty( - name = "system.customHTMLFiles", - havingValue = "true", - matchIfMissing = false) + @ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true") public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.addTemplateResolver(new FileFallbackTemplateResolver(resourceLoader)); @@ -137,8 +134,8 @@ public class AppConfig { } @ConditionalOnMissingClass("stirling.software.SPDF.config.security.SecurityConfiguration") - @Bean(name = "activSecurity") - public boolean missingActivSecurity() { + @Bean(name = "activeSecurity") + public boolean missingActiveSecurity() { return false; } diff --git a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java index 63c291fd..fce11ffd 100644 --- a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java @@ -258,7 +258,7 @@ public class SecurityConfiguration { } // Handle SAML if (applicationProperties.getSecurity().isSaml2Active()) { - // && runningEE + // todo: && runningEE // Configure the authentication provider OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider(); @@ -314,7 +314,7 @@ public class SecurityConfiguration { } @Bean - public boolean activSecurity() { + public boolean activeSecurity() { return true; } } diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java index 4addb9ab..04cc192a 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java +++ b/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java @@ -219,9 +219,7 @@ public class OAuth2Configuration { */ @Bean - @ConditionalOnProperty( - value = "security.oauth2.enabled", - havingValue = "true") + @ConditionalOnProperty(value = "security.oauth2.enabled", havingValue = "true") GrantedAuthoritiesMapper userAuthoritiesMapper() { return (authorities) -> { Set mappedAuthorities = new HashSet<>(); diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationFailureHandler.java b/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationFailureHandler.java index edd0a24a..b6c2deae 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationFailureHandler.java +++ b/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationFailureHandler.java @@ -8,7 +8,6 @@ import org.springframework.security.saml2.core.Saml2Error; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; @@ -21,7 +20,7 @@ public class CustomSaml2AuthenticationFailureHandler extends SimpleUrlAuthentica HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) - throws IOException, ServletException { + throws IOException { if (exception instanceof Saml2AuthenticationException) { Saml2Error error = ((Saml2AuthenticationException) exception).getSaml2Error(); getRedirectStrategy() diff --git a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java b/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java index df54d12d..4dfcf0ca 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java @@ -140,19 +140,23 @@ public class AccountWebController { case "userAlreadyExistsWeb" -> errorOAuth = "userAlreadyExistsWebMessage"; case "oAuth2AuthenticationErrorWeb" -> errorOAuth = "login.oauth2InvalidUserType"; case "invalid_token_response" -> errorOAuth = "login.oauth2InvalidTokenResponse"; - case "authorization_request_not_found" -> errorOAuth = "login.oauth2RequestNotFound"; + case "authorization_request_not_found" -> + errorOAuth = "login.oauth2RequestNotFound"; case "access_denied" -> errorOAuth = "login.oauth2AccessDenied"; - case "invalid_user_info_response" -> errorOAuth = "login.oauth2InvalidUserInfoResponse"; + case "invalid_user_info_response" -> + errorOAuth = "login.oauth2InvalidUserInfoResponse"; case "invalid_request" -> errorOAuth = "login.oauth2invalidRequest"; case "invalid_id_token" -> errorOAuth = "login.oauth2InvalidIdToken"; case "oAuth2AdminBlockedUser" -> errorOAuth = "login.oAuth2AdminBlockedUser"; case "userIsDisabled" -> errorOAuth = "login.userIsDisabled"; case "invalid_destination" -> errorOAuth = "login.invalid_destination"; - case "relying_party_registration_not_found" -> errorOAuth = "login.relyingPartyRegistrationNotFound"; + case "relying_party_registration_not_found" -> + errorOAuth = "login.relyingPartyRegistrationNotFound"; // Valid InResponseTo was not available from the validation context, unable to // evaluate case "invalid_in_response_to" -> errorOAuth = "login.invalid_in_response_to"; - case "not_authentication_provider_found" -> errorOAuth = "login.not_authentication_provider_found"; + case "not_authentication_provider_found" -> + errorOAuth = "login.not_authentication_provider_found"; } model.addAttribute("errorOAuth", errorOAuth); diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index 38f05b6e..badc676a 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -109,7 +109,7 @@ public class ApplicationProperties { private int loginAttemptCount; private long loginResetTimeMinutes; private String loginMethod = "all"; - private String customGlobalAPIKey; + private String customGlobalAPIKey; // todo: expose? public Boolean isAltLogin() { return saml2.getEnabled() || oauth2.getEnabled(); diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index 6e7681c1..42cb937d 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -17,6 +17,7 @@ security: loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1 loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts loginMethod: saml2 # Accepts values like 'all' and 'normal'(only Login with Username/Password), 'oauth2'(only Login with OAuth2) or 'saml2'(only Login with SAML2) + customGlobalAPIKey: 3R3T-WFPY-UNRW-LJFA-MMXM-YVJK-WCKY-PCRT # todo: this is in ApplicationProperties but not here. Should we add it initialLogin: username: '' # initial username for the first login password: '' # initial password for the first login @@ -28,20 +29,20 @@ security: clientId: '' # client ID for Keycloak OAuth2 clientSecret: '' # client secret for Keycloak OAuth2 scopes: openid, profile, email # scopes for Keycloak OAuth2 - useAsUsername: preferred_username # field to use as the username for Keycloak OAuth2 + useAsUsername: preferred_username # field to use as the username for Keycloak OAuth2. Available options are: [email | preferred_name] google: clientId: '' # client ID for Google OAuth2 clientSecret: '' # client secret for Google OAuth2 scopes: email, profile # scopes for Google OAuth2 - useAsUsername: email # field to use as the username for Google OAuth2 + useAsUsername: email # field to use as the username for Google OAuth2. Available options are: [email | name | given_name | family_name] github: clientId: '' # client ID for GitHub OAuth2 clientSecret: '' # client secret for GitHub OAuth2 scopes: read:user # scope for GitHub OAuth2 - useAsUsername: login # field to use as the username for GitHub OAuth2 - issuer: '' # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) endpoint - clientId: '' # client ID from your provider - clientSecret: '' # client secret from your provider + useAsUsername: login # field to use as the username for GitHub OAuth2. Available options are: [email | login | name] + issuer: 'https://authentik.dev.stirlingpdf.com/application/o/stirlingpdf-oauth/' # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) endpoint + clientId: '5ibI9Ud5cRNFIcS1gIJME0shO6VZOy6Ae6XUrZL0' # client ID from your provider + clientSecret: 'DFSD3B7MKLkWuEAasxxm2hghuzulPr37jdkrojPsGBz9MGwkfc' # client secret from your provider autoCreateUser: true # set to 'true' to allow auto-creation of non-existing users blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin useAsUsername: email # default is 'email'; custom fields can be used as the username diff --git a/src/main/resources/templates/fragments/navbar.html b/src/main/resources/templates/fragments/navbar.html index 403a8df3..d2a81956 100644 --- a/src/main/resources/templates/fragments/navbar.html +++ b/src/main/resources/templates/fragments/navbar.html @@ -253,11 +253,11 @@ - Account Settings diff --git a/src/test/java/stirling/software/SPDF/utils/validation/ValidatorTest.java b/src/test/java/stirling/software/SPDF/utils/validation/ValidatorTest.java index 98635198..57b8f1ba 100644 --- a/src/test/java/stirling/software/SPDF/utils/validation/ValidatorTest.java +++ b/src/test/java/stirling/software/SPDF/utils/validation/ValidatorTest.java @@ -29,7 +29,6 @@ class ValidatorTest { when(provider.getClientId()).thenReturn("clientId"); when(provider.getClientSecret()).thenReturn("clientSecret"); when(provider.getScopes()).thenReturn(List.of("read:user")); - when(provider.getUseAsUsername()).thenReturn(UsernameAttribute.EMAIL); assertTrue(Validator.validateProvider(provider)); } @@ -44,15 +43,11 @@ class ValidatorTest { Provider generic = null; var google = new GoogleProvider(null, "clientSecret", List.of("scope"), UsernameAttribute.EMAIL); var github = new GitHubProvider("clientId", "", List.of("scope"), UsernameAttribute.LOGIN); - var keycloak = new KeycloakProvider("issuer", "clientId", "clientSecret", List.of("scope"), UsernameAttribute.EMAIL); - - keycloak.setUseAsUsername(null); return Stream.of( Arguments.of(generic), Arguments.of(google), - Arguments.of(github), - Arguments.of(keycloak) + Arguments.of(github) ); }