From 6aaedf52eaf071d3746934940247046b6ef83c02 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Wed, 16 Apr 2025 16:56:18 +0100 Subject: [PATCH 01/15] wip - making db and sessions conditional --- .../SPDF/config/security/UserAuthenticationFilter.java | 2 ++ .../stirling/software/SPDF/config/security/UserService.java | 3 ++- .../SPDF/config/security/database/DatabaseConfig.java | 4 ++++ .../SPDF/config/security/session/SessionRegistryConfig.java | 2 ++ .../SPDF/config/security/session/SessionRepository.java | 2 ++ 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java b/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java index 70e65e23b..5208e8f25 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java +++ b/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; @@ -34,6 +35,7 @@ import stirling.software.common.model.ApplicationProperties.Security.SAML2; @Slf4j @Component +@ConditionalOnProperty(name = "premium.enabled", havingValue = "true") public class UserAuthenticationFilter extends OncePerRequestFilter { private final ApplicationProperties.Security securityProp; diff --git a/src/main/java/stirling/software/SPDF/config/security/UserService.java b/src/main/java/stirling/software/SPDF/config/security/UserService.java index 71aad721d..068fde1d4 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserService.java +++ b/src/main/java/stirling/software/SPDF/config/security/UserService.java @@ -11,6 +11,7 @@ import java.util.Optional; import java.util.UUID; import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Lazy; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -56,7 +57,7 @@ public class UserService implements UserServiceInterface { private final SessionPersistentRegistry sessionRegistry; - private final DatabaseInterface databaseService; + @Lazy private final DatabaseInterface databaseService; private final ApplicationProperties.Security.OAUTH2 oAuth2; diff --git a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java index 3deeee48a..73ccbe3b7 100644 --- a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java +++ b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java @@ -3,9 +3,11 @@ package stirling.software.SPDF.config.security.database; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -16,7 +18,9 @@ import stirling.software.common.model.exception.UnsupportedProviderException; @Slf4j @Getter +@Lazy @Configuration +@ConditionalOnProperty(name = "premium.proFeatures.database", havingValue = "true") public class DatabaseConfig { public final String DATASOURCE_DEFAULT_URL; diff --git a/src/main/java/stirling/software/SPDF/config/security/session/SessionRegistryConfig.java b/src/main/java/stirling/software/SPDF/config/security/session/SessionRegistryConfig.java index 8fa24e95a..18a84279c 100644 --- a/src/main/java/stirling/software/SPDF/config/security/session/SessionRegistryConfig.java +++ b/src/main/java/stirling/software/SPDF/config/security/session/SessionRegistryConfig.java @@ -1,10 +1,12 @@ package stirling.software.SPDF.config.security.session; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.session.SessionRegistryImpl; @Configuration +@ConditionalOnProperty(name = "premium.enabled", havingValue = "true") public class SessionRegistryConfig { @Bean diff --git a/src/main/java/stirling/software/SPDF/config/security/session/SessionRepository.java b/src/main/java/stirling/software/SPDF/config/security/session/SessionRepository.java index b7f0133f3..d4f2f4bcc 100644 --- a/src/main/java/stirling/software/SPDF/config/security/session/SessionRepository.java +++ b/src/main/java/stirling/software/SPDF/config/security/session/SessionRepository.java @@ -3,6 +3,7 @@ package stirling.software.SPDF.config.security.session; import java.util.Date; import java.util.List; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -14,6 +15,7 @@ import jakarta.transaction.Transactional; import stirling.software.SPDF.model.SessionEntity; @Repository +@ConditionalOnProperty(name = "premium.enabled", havingValue = "true") public interface SessionRepository extends JpaRepository { List findByPrincipalName(String principalName); From 3d312c2fd1312ab8f6c863cd6af0f23828e58c80 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Wed, 16 Apr 2025 16:56:18 +0100 Subject: [PATCH 02/15] creating new proprietary module --- src/main/resources/settings.yml.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index 0226776c5..2228b73a7 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -64,7 +64,7 @@ premium: key: 00000000-0000-0000-0000-000000000000 enabled: true # Enable license key checks for pro/enterprise features proFeatures: - database: true # Enable database features + customDatabase: false # Enable database features todo: use only for custom DB SSOAutoLogin: false CustomMetadata: autoUpdateMetadata: false From 58937a6e9187bf80a8c666cb5e63bfc3289438cc Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Fri, 9 May 2025 16:48:48 +0100 Subject: [PATCH 03/15] moving security package and relevant files over to proprietary --- LICENSE | 7 + build.gradle | 49 +-- .../gradle/wrapper/gradle-wrapper.properties | 6 + common/gradlew | 251 ++++++++++++++ common/gradlew.bat | 94 +++++ proprietary/.gitignore | 196 +++++++++++ proprietary/LICENSE-proprietary | 45 +++ proprietary/build.gradle | 68 ++++ .../gradle/wrapper/gradle-wrapper.properties | 6 + proprietary/gradlew | 251 ++++++++++++++ proprietary/gradlew.bat | 94 +++++ .../CustomAuthenticationFailureHandler.java | 18 +- .../CustomAuthenticationSuccessHandler.java | 16 +- .../security/CustomLogoutSuccessHandler.java | 32 +- .../security/InitialSecuritySetup.java | 19 +- .../security/RateLimitResetScheduler.java | 8 +- .../configuration}/DatabaseConfig.java | 35 +- .../security/configuration}/MailConfig.java | 3 +- .../configuration/SecurityConfiguration.java | 320 ++++++++++++++++++ .../controller/api/DatabaseController.java | 6 +- .../controller/api/EmailController.java | 6 +- .../controller/api/UserController.java | 16 +- .../controller/web/AccountWebController.java | 16 +- .../controller/web/DatabaseWebController.java | 4 +- .../security/database}/H2SQLCondition.java | 10 +- .../security/database/ScheduledTasks.java | 12 +- .../repository/AuthorityRepository.java | 5 +- .../repository/JPATokenRepositoryImpl.java | 5 +- .../repository/PersistentLoginRepository.java | 5 +- .../repository}/SessionRepository.java | 11 +- .../database}/repository/UserRepository.java | 5 +- .../filter}/EnterpriseEndpointFilter.java | 2 +- .../security/filter}/FirstLoginFilter.java | 27 +- .../filter}/IPRateLimitingFilter.java | 13 +- .../filter}/UserAuthenticationFilter.java | 27 +- .../filter}/UserBasedRateLimitingFilter.java | 24 +- .../model/ApiKeyAuthenticationToken.java | 2 +- .../security}/model/AttemptCounter.java | 2 +- .../security/model/AuthenticationType.java | 6 + .../security}/model/Authority.java | 2 +- .../security}/model/PersistentLogin.java | 2 +- .../security}/model/SessionEntity.java | 2 +- .../proprietary/security}/model/User.java | 3 +- .../proprietary/security/model/api/Email.java | 39 +++ .../model/api/user/UpdateUserDetails.java | 17 + .../model/api/user/UpdateUserUsername.java | 14 + .../security/model/api/user/Username.java | 14 + .../model/api/user/UsernameAndPass.java | 14 + .../exception/BackupNotFoundException.java | 2 +- .../exception/NoProviderFoundException.java | 2 +- ...tomOAuth2AuthenticationFailureHandler.java | 13 +- ...tomOAuth2AuthenticationSuccessHandler.java | 22 +- .../security/oauth2/OAuth2Configuration.java | 22 +- .../security/saml2/CertificateUtils.java | 3 +- .../CustomSaml2AuthenticatedPrincipal.java | 3 +- ...stomSaml2AuthenticationFailureHandler.java | 11 +- ...stomSaml2AuthenticationSuccessHandler.java | 24 +- ...mSaml2ResponseAuthenticationConverter.java | 19 +- .../security/saml2/SAML2Configuration.java | 12 +- .../service}/AppUpdateAuthService.java | 13 +- .../service}/CustomOAuth2UserService.java | 11 +- .../service}/CustomUserDetailsService.java | 13 +- .../security/service}/DatabaseService.java | 35 +- .../service/DatabaseServiceInterface.java | 4 +- .../security/service}/EmailService.java | 4 +- .../service}/LoginAttemptService.java | 14 +- .../security/service}/UserService.java | 32 +- .../session/CustomHttpSessionListener.java | 6 +- .../session/SessionPersistentRegistry.java | 22 +- .../session/SessionRegistryConfig.java | 8 +- .../security/session/SessionScheduled.java | 6 +- .../CustomLogoutSuccessHandlerTest.java | 15 +- .../configuration}/DatabaseConfigTest.java | 10 +- .../controller/api/EmailControllerTest.java | 6 +- .../security/service}/EmailServiceTest.java | 11 +- .../security/service}/MailConfigTest.java | 3 +- settings.gradle | 2 +- .../SPDF/config/AppUpdateService.java | 2 +- .../config/interfaces/ShowAdminInterface.java | 7 - .../security/SecurityConfiguration.java | 319 ----------------- .../converters/ConvertOfficeController.java | 2 +- .../api/pipeline/ApiDocService.java | 2 +- .../api/pipeline/PipelineProcessor.java | 2 +- .../api/security/SanitizeController.java | 13 +- .../SPDF/model/AuthenticationType.java | 6 - .../software/SPDF/model/PdfMetadata.java | 19 -- .../stirling/software/SPDF/model/Role.java | 66 ---- 87 files changed, 1758 insertions(+), 857 deletions(-) create mode 100644 common/gradle/wrapper/gradle-wrapper.properties create mode 100755 common/gradlew create mode 100644 common/gradlew.bat create mode 100644 proprietary/.gitignore create mode 100644 proprietary/LICENSE-proprietary create mode 100644 proprietary/build.gradle create mode 100644 proprietary/gradle/wrapper/gradle-wrapper.properties create mode 100755 proprietary/gradlew create mode 100644 proprietary/gradlew.bat rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/CustomAuthenticationFailureHandler.java (93%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/CustomAuthenticationSuccessHandler.java (92%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/CustomLogoutSuccessHandler.java (95%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/InitialSecuritySetup.java (91%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/RateLimitResetScheduler.java (78%) rename {src/main/java/stirling/software/SPDF/config/security/database => proprietary/src/main/java/stirling/software/proprietary/security/configuration}/DatabaseConfig.java (86%) rename {src/main/java/stirling/software/SPDF/config/security/mail => proprietary/src/main/java/stirling/software/proprietary/security/configuration}/MailConfig.java (96%) create mode 100644 proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/controller/api/DatabaseController.java (97%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/controller/api/EmailController.java (93%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/controller/api/UserController.java (97%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/controller/web/AccountWebController.java (97%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/controller/web/DatabaseWebController.java (92%) rename {src/main/java/stirling/software/SPDF/controller/api => proprietary/src/main/java/stirling/software/proprietary/security/database}/H2SQLCondition.java (77%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/database/ScheduledTasks.java (71%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security/database}/repository/AuthorityRepository.java (74%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security/database}/repository/JPATokenRepositoryImpl.java (93%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security/database}/repository/PersistentLoginRepository.java (65%) rename {src/main/java/stirling/software/SPDF/config/security/session => proprietary/src/main/java/stirling/software/proprietary/security/database/repository}/SessionRepository.java (79%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security/database}/repository/UserRepository.java (86%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary/security/filter}/EnterpriseEndpointFilter.java (95%) rename {src/main/java/stirling/software/SPDF/config/security => proprietary/src/main/java/stirling/software/proprietary/security/filter}/FirstLoginFilter.java (94%) rename {src/main/java/stirling/software/SPDF/config/security => proprietary/src/main/java/stirling/software/proprietary/security/filter}/IPRateLimitingFilter.java (90%) rename {src/main/java/stirling/software/SPDF/config/security => proprietary/src/main/java/stirling/software/proprietary/security/filter}/UserAuthenticationFilter.java (96%) rename {src/main/java/stirling/software/SPDF/config/security => proprietary/src/main/java/stirling/software/proprietary/security/filter}/UserBasedRateLimitingFilter.java (98%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/model/ApiKeyAuthenticationToken.java (96%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/model/AttemptCounter.java (93%) create mode 100644 proprietary/src/main/java/stirling/software/proprietary/security/model/AuthenticationType.java rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/model/Authority.java (94%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/model/PersistentLogin.java (91%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/model/SessionEntity.java (88%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/model/User.java (95%) create mode 100644 proprietary/src/main/java/stirling/software/proprietary/security/model/api/Email.java create mode 100644 proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UpdateUserDetails.java create mode 100644 proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UpdateUserUsername.java create mode 100644 proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/Username.java create mode 100644 proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UsernameAndPass.java rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/model/exception/BackupNotFoundException.java (70%) rename {src/main/java/stirling/software/SPDF => proprietary/src/main/java/stirling/software/proprietary/security}/model/exception/NoProviderFoundException.java (79%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java (97%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java (94%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/oauth2/OAuth2Configuration.java (96%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/saml2/CertificateUtils.java (97%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/saml2/CustomSaml2AuthenticatedPrincipal.java (93%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/saml2/CustomSaml2AuthenticationFailureHandler.java (96%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/saml2/CustomSaml2AuthenticationSuccessHandler.java (95%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/saml2/CustomSaml2ResponseAuthenticationConverter.java (94%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/saml2/SAML2Configuration.java (99%) rename {src/main/java/stirling/software/SPDF/config/security => proprietary/src/main/java/stirling/software/proprietary/security/service}/AppUpdateAuthService.java (83%) rename {src/main/java/stirling/software/SPDF/config/security/oauth2 => proprietary/src/main/java/stirling/software/proprietary/security/service}/CustomOAuth2UserService.java (94%) rename {src/main/java/stirling/software/SPDF/config/security => proprietary/src/main/java/stirling/software/proprietary/security/service}/CustomUserDetailsService.java (89%) rename {src/main/java/stirling/software/SPDF/config/security/database => proprietary/src/main/java/stirling/software/proprietary/security/service}/DatabaseService.java (91%) rename src/main/java/stirling/software/SPDF/config/interfaces/DatabaseInterface.java => proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseServiceInterface.java (77%) rename {src/main/java/stirling/software/SPDF/config/security/mail => proprietary/src/main/java/stirling/software/proprietary/security/service}/EmailService.java (96%) rename {src/main/java/stirling/software/SPDF/config/security => proprietary/src/main/java/stirling/software/proprietary/security/service}/LoginAttemptService.java (95%) rename {src/main/java/stirling/software/SPDF/config/security => proprietary/src/main/java/stirling/software/proprietary/security/service}/UserService.java (95%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/session/CustomHttpSessionListener.java (92%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/session/SessionPersistentRegistry.java (94%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/session/SessionRegistryConfig.java (57%) rename {src/main/java/stirling/software/SPDF/config => proprietary/src/main/java/stirling/software/proprietary}/security/session/SessionScheduled.java (95%) rename {src/test/java/stirling/software/SPDF/config => proprietary/src/test/java/stirling/software/proprietary}/security/CustomLogoutSuccessHandlerTest.java (98%) rename {src/test/java/stirling/software/SPDF/config/security/database => proprietary/src/test/java/stirling/software/proprietary/security/configuration}/DatabaseConfigTest.java (94%) rename {src/test/java/stirling/software/SPDF => proprietary/src/test/java/stirling/software/proprietary/security}/controller/api/EmailControllerTest.java (94%) rename {src/test/java/stirling/software/SPDF/config/security/mail => proprietary/src/test/java/stirling/software/proprietary/security/service}/EmailServiceTest.java (94%) rename {src/test/java/stirling/software/SPDF/config/security/mail => proprietary/src/test/java/stirling/software/proprietary/security/service}/MailConfigTest.java (94%) delete mode 100644 src/main/java/stirling/software/SPDF/config/interfaces/ShowAdminInterface.java delete mode 100644 src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java delete mode 100644 src/main/java/stirling/software/SPDF/model/AuthenticationType.java delete mode 100644 src/main/java/stirling/software/SPDF/model/PdfMetadata.java delete mode 100644 src/main/java/stirling/software/SPDF/model/Role.java diff --git a/LICENSE b/LICENSE index 10633f4a3..0cd290e88 100644 --- a/LICENSE +++ b/LICENSE @@ -2,6 +2,13 @@ MIT License Copyright (c) 2024 Stirling Tools +Portions of this software are licensed as follows: + +* All content that resides under the "proprietary/" directory of this repository, +if that directory exists, is licensed under the license defined in "proprietary/LICENSE". +* Content outside of the above mentioned directories or restrictions above is +available under the MIT License as defined below. + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff --git a/build.gradle b/build.gradle index 25d34635f..cf5a3b728 100644 --- a/build.gradle +++ b/build.gradle @@ -52,24 +52,7 @@ sourceSets { main { java { if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") { - exclude "stirling/software/SPDF/config/interfaces/DatabaseInterface.java" - exclude "stirling/software/SPDF/config/security/**" - exclude "stirling/software/SPDF/controller/api/DatabaseController.java" - exclude "stirling/software/SPDF/controller/api/EmailController.java" - exclude "stirling/software/SPDF/controller/api/H2SQLCondition.java" - exclude "stirling/software/SPDF/controller/api/UserController.java" - exclude "stirling/software/SPDF/controller/web/AccountWebController.java" - exclude "stirling/software/SPDF/controller/web/DatabaseWebController.java" - exclude "stirling/software/SPDF/model/api/Email.java" - exclude "stirling/software/SPDF/model/ApiKeyAuthenticationToken.java" - exclude "stirling/software/SPDF/model/AttemptCounter.java" - exclude "stirling/software/SPDF/model/Authority.java" - exclude "stirling/software/SPDF/model/exception/BackupNotFoundException.java" - exclude "stirling/software/SPDF/model/exception/NoProviderFoundException.java" - exclude "stirling/software/SPDF/model/PersistentLogin.java" - exclude "stirling/software/SPDF/model/SessionEntity.java" - exclude "stirling/software/SPDF/model/User.java" - exclude "stirling/software/SPDF/repository/**" + exclude "stirling/software/proprietary/security/**" } if (System.getenv("STIRLING_PDF_DESKTOP_UI") == "false") { @@ -82,10 +65,7 @@ sourceSets { test { java { if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") { - exclude "stirling/software/SPDF/config/security/**" - exclude "stirling/software/SPDF/model/ApiKeyAuthenticationTokenTest.java" - exclude "stirling/software/SPDF/controller/api/EmailControllerTest.java" - exclude "stirling/software/SPDF/repository/**" + exclude "stirling/software/proprietary/security/**" } if (System.getenv("STIRLING_PDF_DESKTOP_UI") == "false") { @@ -450,30 +430,7 @@ dependencies { if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") { - implementation 'io.micrometer:micrometer-registry-prometheus' - - implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion" - implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.3.RELEASE" - implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" - implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion" - implementation "org.springframework.boot:spring-boot-starter-mail:$springBootVersion" - - implementation "org.springframework.session:spring-session-core:3.5.0" - implementation "org.springframework:spring-jdbc:6.2.7" - - implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5' - // Don't upgrade h2database - runtimeOnly "com.h2database:h2:2.3.232" - runtimeOnly "org.postgresql:postgresql:42.7.6" - constraints { - implementation "org.opensaml:opensaml-core:$openSamlVersion" - implementation "org.opensaml:opensaml-saml-api:$openSamlVersion" - implementation "org.opensaml:opensaml-saml-impl:$openSamlVersion" - } - implementation "org.springframework.security:spring-security-saml2-service-provider:$springSecuritySamlVersion" - // implementation 'org.springframework.security:spring-security-core:$springSecuritySamlVersion' - implementation 'com.coveo:saml-client:5.0.0' - + implementation project(':proprietary') } implementation 'org.snakeyaml:snakeyaml-engine:2.9' diff --git a/common/gradle/wrapper/gradle-wrapper.properties b/common/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..f7664bccf --- /dev/null +++ b/common/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/common/gradlew b/common/gradlew new file mode 100755 index 000000000..23d15a936 --- /dev/null +++ b/common/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/common/gradlew.bat b/common/gradlew.bat new file mode 100644 index 000000000..db3a6ac20 --- /dev/null +++ b/common/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/proprietary/.gitignore b/proprietary/.gitignore new file mode 100644 index 000000000..90d48ccea --- /dev/null +++ b/proprietary/.gitignore @@ -0,0 +1,196 @@ +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.exe +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders +.classpath +.project +version.properties + +#### Stirling-PDF Files ### +pipeline/watchedFolders/ +pipeline/finishedFolders/ +customFiles/ +configs/ +watchedFolders/ +clientWebUI/ +!cucumber/ +!cucumber/exampleFiles/ +!cucumber/exampleFiles/example_html.zip +exampleYmlFiles/stirling/ +/testing/file_snapshots +SwaggerDoc.json + +# Gradle +.gradle +.lock + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +### Eclipse Patch ### +# Spring Boot Tooling +.sts4-cache/ + +### Git ### +# Created by git for backups. To disable backups in Git: +# $ git config --global mergetool.keepBackup false +*.orig + +# Created by git when using merge tools for conflicts +*.BACKUP.* +*.BASE.* +*.LOCAL.* +*.REMOTE.* +*_BACKUP_*.txt +*_BASE_*.txt +*_LOCAL_*.txt +*_REMOTE_*.txt + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar +*.db +/build + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*.pyo + +# Virtual environments +.env* +.venv* +env*/ +venv*/ +ENV/ +env.bak/ +venv.bak/ + +# VS Code +/.vscode/**/* +!/.vscode/settings.json +!/.vscode/extensions.json + +# IntelliJ IDEA +.idea/ +*.iml +out/ + +# Ignore Mac DS_Store files +.DS_Store +**/.DS_Store + +# cucumber +/cucumber/reports/** + +# Certs and Security Files +*.p12 +*.pk8 +*.pem +*.crt +*.cer +*.cert +*.der +*.key +*.csr +*.kdbx +*.jks +*.asc + +# SSH Keys +*.pub +*.priv +id_rsa +id_rsa.pub +id_ecdsa +id_ecdsa.pub +id_ed25519 +id_ed25519.pub +.ssh/ +*ssh + +# cache +.cache +.ruff_cache +.mypy_cache +.pytest_cache +.ipynb_checkpoints + +**/jcef-bundle/ + +# node_modules +node_modules/ +*.mjs diff --git a/proprietary/LICENSE-proprietary b/proprietary/LICENSE-proprietary new file mode 100644 index 000000000..f723a2809 --- /dev/null +++ b/proprietary/LICENSE-proprietary @@ -0,0 +1,45 @@ +Stirling PDF Enterprise Edition (EE) license (the “EE License”) + +Copyright (c) 2025-present Stirling Tools + +With regard to the Stirling PDF Software: + +This software and associated documentation files (the "Software") may only be +used in production, if you (and any entity that you represent) have agreed to, +and are in compliance with, the Stirling PDF Terms of Service, available +at https://www.stirlingpdf.com/terms-and-conditions (the “EE Terms”), or other +agreement governing the use of the Software, as agreed by you and Stirling PDF, +and otherwise have a valid Stirling PDF Enterprise Edition subscription for the +correct number of user seats. Subject to the foregoing sentence, you are free to +modify this Software and publish patches to the Software. You agree that Stirling PDF +and/or its licensors (as applicable) retain all right, title and interest in and +to all such modifications and/or patches, and all such modifications and/or +patches may only be used, copied, modified, displayed, distributed, or otherwise +exploited with a valid Stirling PDF Enterprise Edition subscription for the correct +number of user seats. Notwithstanding the foregoing, you may copy and modify +the Software for development and testing purposes, without requiring a +subscription. You agree that Stirling PDF and/or its licensors (as applicable) retain +all right, title and interest in and to all such modifications. You are not +granted any other rights beyond what is expressly stated herein. Subject to the +foregoing, it is forbidden to copy, merge, publish, distribute, sublicense, +and/or sell the Software. + +This EE License applies only to the part of this Software that is not +distributed as part of MIT License. Any part of this Software +distributed as part of MIT License or is served client-side as an image, font, +cascading stylesheet (CSS), file which produces or is compiled, arranged, +augmented, or combined into client-side JavaScript, in whole or in part, is +copyrighted under the MIT Expat license. The full text of this EE License shall +be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +For all third party components incorporated into the Stirling PDF Software, those +components are licensed under the original license provided by the owner of the +applicable component. diff --git a/proprietary/build.gradle b/proprietary/build.gradle new file mode 100644 index 000000000..8f548a785 --- /dev/null +++ b/proprietary/build.gradle @@ -0,0 +1,68 @@ +plugins { + id 'java-library' + id 'io.spring.dependency-management' version '1.1.7' +} + +repositories { + mavenCentral() + maven { url = "https://build.shibboleth.net/maven/releases" } +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 +} + +configurations.all { + exclude group: 'commons-logging', module: 'commons-logging' + exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat" +} + +dependencyManagement { + imports { + mavenBom 'org.springframework.boot:spring-boot-dependencies:3.4.5' + } +} + +dependencies { + implementation project(':common') + + implementation 'org.springframework:spring-jdbc:6.2.7' + implementation 'org.springframework:spring-webmvc:6.2.7' + implementation 'org.springframework.boot:spring-boot-starter-jetty' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation 'org.springframework.boot:spring-boot-starter-mail' + implementation "org.springframework.security:spring-security-core:$springSecuritySamlVersion" + implementation "org.springframework.security:spring-security-saml2-service-provider:$springSecuritySamlVersion" + implementation 'org.springframework.session:spring-session-core:3.4.3' + implementation 'io.swagger.core.v3:swagger-core-jakarta:2.2.30' + + implementation 'com.bucket4j:bucket4j_jdk17-core:8.14.0' + + // https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17 + implementation 'org.bouncycastle:bcprov-jdk18on:1.80' + + implementation 'io.github.pixee:java-security-toolkit:1.2.1' + implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.3.RELEASE' + implementation 'io.micrometer:micrometer-registry-prometheus' + implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5' + runtimeOnly 'com.h2database:h2:2.3.232' // Don't upgrade h2database + runtimeOnly 'org.postgresql:postgresql:42.7.5' + constraints { + implementation "org.opensaml:opensaml-core:$openSamlVersion" + implementation "org.opensaml:opensaml-saml-api:$openSamlVersion" + implementation "org.opensaml:opensaml-saml-impl:$openSamlVersion" + } + implementation 'com.coveo:saml-client:5.0.0' + + compileOnly "org.projectlombok:lombok:$lombokVersion" + annotationProcessor "org.projectlombok:lombok:$lombokVersion" + + testImplementation platform('org.junit:junit-bom:5.10.0') + testImplementation 'org.junit.jupiter:junit-jupiter' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testRuntimeOnly 'org.mockito:mockito-inline:5.2.0' +} + +tasks.register('prepareKotlinBuildScriptModel') {} diff --git a/proprietary/gradle/wrapper/gradle-wrapper.properties b/proprietary/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..f7664bccf --- /dev/null +++ b/proprietary/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/proprietary/gradlew b/proprietary/gradlew new file mode 100755 index 000000000..23d15a936 --- /dev/null +++ b/proprietary/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/proprietary/gradlew.bat b/proprietary/gradlew.bat new file mode 100644 index 000000000..db3a6ac20 --- /dev/null +++ b/proprietary/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationFailureHandler.java similarity index 93% rename from src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationFailureHandler.java rename to proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationFailureHandler.java index f4f103190..ee726b9fb 100644 --- a/src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationFailureHandler.java @@ -1,8 +1,11 @@ -package stirling.software.SPDF.config.security; +package stirling.software.proprietary.security; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Optional; - +import lombok.extern.slf4j.Slf4j; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.DisabledException; import org.springframework.security.authentication.InternalAuthenticationServiceException; @@ -10,14 +13,9 @@ import org.springframework.security.authentication.LockedException; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UsernameNotFoundException; 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; - -import stirling.software.SPDF.model.User; +import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.service.LoginAttemptService; +import stirling.software.proprietary.security.service.UserService; @Slf4j public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { diff --git a/src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationSuccessHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationSuccessHandler.java similarity index 92% rename from src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationSuccessHandler.java rename to proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationSuccessHandler.java index 0f4fbecb8..b9379ec74 100644 --- a/src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationSuccessHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationSuccessHandler.java @@ -1,19 +1,17 @@ -package stirling.software.SPDF.config.security; - -import java.io.IOException; - -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import org.springframework.security.web.savedrequest.SavedRequest; +package stirling.software.proprietary.security; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; - +import java.io.IOException; import lombok.extern.slf4j.Slf4j; - +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; +import org.springframework.security.web.savedrequest.SavedRequest; import stirling.software.common.util.RequestUriUtils; +import stirling.software.proprietary.security.service.LoginAttemptService; +import stirling.software.proprietary.security.service.UserService; @Slf4j public class CustomAuthenticationSuccessHandler diff --git a/src/main/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/CustomLogoutSuccessHandler.java similarity index 95% rename from src/main/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandler.java rename to proprietary/src/main/java/stirling/software/proprietary/security/CustomLogoutSuccessHandler.java index 2f7fb25de..244e16da0 100644 --- a/src/main/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/CustomLogoutSuccessHandler.java @@ -1,35 +1,30 @@ -package stirling.software.SPDF.config.security; +package stirling.software.proprietary.security; +import com.coveo.saml.SamlClient; +import com.coveo.saml.SamlException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.List; - +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.Resource; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler; - -import com.coveo.saml.SamlClient; -import com.coveo.saml.SamlException; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.SPDFApplication; -import stirling.software.SPDF.config.security.saml2.CertificateUtils; -import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal; +import stirling.software.common.configuration.AppConfig; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.ApplicationProperties.Security.SAML2; import stirling.software.common.model.oauth2.KeycloakProvider; import stirling.software.common.util.UrlUtils; +import stirling.software.proprietary.security.saml2.CertificateUtils; +import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; @Slf4j @RequiredArgsConstructor @@ -38,6 +33,7 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { public static final String LOGOUT_PATH = "/login?logout=true"; private final ApplicationProperties applicationProperties; + private final AppConfig appConfig; @Override public void onLogoutSuccess( @@ -102,7 +98,7 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { // Set service provider keys for the SamlClient samlClient.setSPKeys(certificate, privateKey); - // Redirect to identity provider for logout + // Redirect to identity provider for logout. todo: add relay state samlClient.redirectToIdentityProvider(response, null, nameIdValue); } catch (Exception e) { log.error( @@ -172,11 +168,11 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { } } - private static SamlClient getSamlClient( + private SamlClient getSamlClient( String registrationId, SAML2 samlConf, List certificates) throws SamlException { String serverUrl = - SPDFApplication.getStaticBaseUrl() + ":" + SPDFApplication.getStaticPort(); + appConfig.getBaseUrl() + ":" + appConfig.getServerPort(); String relyingPartyIdentifier = serverUrl + "/saml2/service-provider-metadata/" + registrationId; diff --git a/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java b/proprietary/src/main/java/stirling/software/proprietary/security/InitialSecuritySetup.java similarity index 91% rename from src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java rename to proprietary/src/main/java/stirling/software/proprietary/security/InitialSecuritySetup.java index 3b1a8d5fb..1353f2151 100644 --- a/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/InitialSecuritySetup.java @@ -1,19 +1,16 @@ -package stirling.software.SPDF.config.security; - -import java.sql.SQLException; -import java.util.UUID; - -import org.springframework.stereotype.Component; +package stirling.software.proprietary.security; import jakarta.annotation.PostConstruct; - +import java.sql.SQLException; +import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.interfaces.DatabaseInterface; -import stirling.software.SPDF.model.Role; +import org.springframework.stereotype.Component; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.exception.UnsupportedProviderException; +import stirling.software.common.model.enumeration.Role; +import stirling.software.proprietary.security.service.DatabaseServiceInterface; +import stirling.software.proprietary.security.service.UserService; @Slf4j @Component @@ -24,7 +21,7 @@ public class InitialSecuritySetup { private final ApplicationProperties applicationProperties; - private final DatabaseInterface databaseService; + private final DatabaseServiceInterface databaseService; @PostConstruct public void init() { diff --git a/src/main/java/stirling/software/SPDF/config/security/RateLimitResetScheduler.java b/proprietary/src/main/java/stirling/software/proprietary/security/RateLimitResetScheduler.java similarity index 78% rename from src/main/java/stirling/software/SPDF/config/security/RateLimitResetScheduler.java rename to proprietary/src/main/java/stirling/software/proprietary/security/RateLimitResetScheduler.java index 5751ec871..4faeb9041 100644 --- a/src/main/java/stirling/software/SPDF/config/security/RateLimitResetScheduler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/RateLimitResetScheduler.java @@ -1,9 +1,9 @@ -package stirling.software.SPDF.config.security; - -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; +package stirling.software.proprietary.security; import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import stirling.software.proprietary.security.filter.IPRateLimitingFilter; @Component @RequiredArgsConstructor diff --git a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java similarity index 86% rename from src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java rename to proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java index 73ccbe3b7..8d686e4d7 100644 --- a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java @@ -1,34 +1,30 @@ -package stirling.software.SPDF.config.security.database; +package stirling.software.proprietary.security.configuration; import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; - import lombok.Getter; import lombok.extern.slf4j.Slf4j; - +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import stirling.software.common.configuration.InstallationPathConfig; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.exception.UnsupportedProviderException; @Slf4j @Getter -@Lazy @Configuration -@ConditionalOnProperty(name = "premium.proFeatures.database", havingValue = "true") +@EnableJpaRepositories(basePackages = "stirling.software.proprietary.security.database.repository") +@EntityScan({"stirling.software.proprietary.security.model"}) public class DatabaseConfig { public final String DATASOURCE_DEFAULT_URL; public static final String DATASOURCE_URL_TEMPLATE = "jdbc:%s://%s:%4d/%s"; - public static final String DEFAULT_DRIVER = "org.h2.Driver"; public static final String DEFAULT_USERNAME = "sa"; - public static final String POSTGRES_DRIVER = "org.postgresql.Driver"; private final ApplicationProperties.Datasource datasource; private final boolean runningProOrHigher; @@ -70,7 +66,7 @@ public class DatabaseConfig { if (!datasource.getCustomDatabaseUrl().isBlank()) { if (datasource.getCustomDatabaseUrl().contains("postgresql")) { - dataSourceBuilder.driverClassName(POSTGRES_DRIVER); + dataSourceBuilder.driverClassName(DatabaseDriver.POSTGRESQL.getDriverClassName()); } dataSourceBuilder.url(datasource.getCustomDatabaseUrl()); @@ -92,8 +88,9 @@ public class DatabaseConfig { private DataSource useDefaultDataSource(DataSourceBuilder dataSourceBuilder) { log.info("Using default H2 database"); - dataSourceBuilder.url(DATASOURCE_DEFAULT_URL); - dataSourceBuilder.username(DEFAULT_USERNAME); + dataSourceBuilder.url(DATASOURCE_DEFAULT_URL) + .driverClassName(DatabaseDriver.H2.getDriverClassName()) + .username(DEFAULT_USERNAME); return dataSourceBuilder.build(); } @@ -127,11 +124,11 @@ public class DatabaseConfig { switch (driver) { case H2 -> { log.debug("H2 driver selected"); - return DEFAULT_DRIVER; + return DatabaseDriver.H2.getDriverClassName(); } case POSTGRESQL -> { log.debug("Postgres driver selected"); - return POSTGRES_DRIVER; + return DatabaseDriver.POSTGRESQL.getDriverClassName(); } default -> { log.warn("{} driver selected", driverName); diff --git a/src/main/java/stirling/software/SPDF/config/security/mail/MailConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java similarity index 96% rename from src/main/java/stirling/software/SPDF/config/security/mail/MailConfig.java rename to proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java index 0181271d3..82d794d6e 100644 --- a/src/main/java/stirling/software/SPDF/config/security/mail/MailConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.config.security.mail; +package stirling.software.proprietary.security.configuration; import java.util.Properties; @@ -10,7 +10,6 @@ import org.springframework.mail.javamail.JavaMailSenderImpl; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; - import stirling.software.common.model.ApplicationProperties; /** diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java new file mode 100644 index 000000000..c31d42dde --- /dev/null +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java @@ -0,0 +1,320 @@ +package stirling.software.proprietary.security.configuration; + +import java.util.Optional; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Lazy; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider; +import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; +import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; +import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler; +import org.springframework.security.web.savedrequest.NullRequestCache; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import stirling.software.common.configuration.AppConfig; +import stirling.software.common.model.ApplicationProperties; +import stirling.software.proprietary.security.CustomAuthenticationFailureHandler; +import stirling.software.proprietary.security.CustomAuthenticationSuccessHandler; +import stirling.software.proprietary.security.CustomLogoutSuccessHandler; +import stirling.software.proprietary.security.database.repository.JPATokenRepositoryImpl; +import stirling.software.proprietary.security.database.repository.PersistentLoginRepository; +import stirling.software.proprietary.security.filter.FirstLoginFilter; +import stirling.software.proprietary.security.filter.IPRateLimitingFilter; +import stirling.software.proprietary.security.filter.UserAuthenticationFilter; +import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.oauth2.CustomOAuth2AuthenticationFailureHandler; +import stirling.software.proprietary.security.oauth2.CustomOAuth2AuthenticationSuccessHandler; +import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticationFailureHandler; +import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticationSuccessHandler; +import stirling.software.proprietary.security.saml2.CustomSaml2ResponseAuthenticationConverter; +import stirling.software.proprietary.security.service.CustomOAuth2UserService; +import stirling.software.proprietary.security.service.CustomUserDetailsService; +import stirling.software.proprietary.security.service.LoginAttemptService; +import stirling.software.proprietary.security.service.UserService; +import stirling.software.proprietary.security.session.SessionPersistentRegistry; + +@Slf4j +@Configuration +@EnableWebSecurity +@EnableMethodSecurity +@DependsOn("runningProOrHigher") +public class SecurityConfiguration { + + private final CustomUserDetailsService userDetailsService; + private final UserService userService; + private final boolean loginEnabledValue; + private final boolean runningProOrHigher; + + private final ApplicationProperties applicationProperties; + private final AppConfig appConfig; + private final UserAuthenticationFilter userAuthenticationFilter; + private final LoginAttemptService loginAttemptService; + private final FirstLoginFilter firstLoginFilter; + private final SessionPersistentRegistry sessionRegistry; + private final PersistentLoginRepository persistentLoginRepository; + private final GrantedAuthoritiesMapper oAuth2userAuthoritiesMapper; + private final RelyingPartyRegistrationRepository saml2RelyingPartyRegistrations; + private final OpenSaml4AuthenticationRequestResolver saml2AuthenticationRequestResolver; + + public SecurityConfiguration( + PersistentLoginRepository persistentLoginRepository, + CustomUserDetailsService userDetailsService, + @Lazy UserService userService, + @Qualifier("loginEnabled") boolean loginEnabledValue, + @Qualifier("runningProOrHigher") boolean runningProOrHigher, + AppConfig appConfig, + ApplicationProperties applicationProperties, + UserAuthenticationFilter userAuthenticationFilter, + LoginAttemptService loginAttemptService, + FirstLoginFilter firstLoginFilter, + SessionPersistentRegistry sessionRegistry, + @Autowired(required = false) GrantedAuthoritiesMapper oAuth2userAuthoritiesMapper, + @Autowired(required = false) + RelyingPartyRegistrationRepository saml2RelyingPartyRegistrations, + @Autowired(required = false) + OpenSaml4AuthenticationRequestResolver saml2AuthenticationRequestResolver) { + this.userDetailsService = userDetailsService; + this.userService = userService; + this.loginEnabledValue = loginEnabledValue; + this.runningProOrHigher = runningProOrHigher; + this.appConfig = appConfig; + this.applicationProperties = applicationProperties; + this.userAuthenticationFilter = userAuthenticationFilter; + this.loginAttemptService = loginAttemptService; + this.firstLoginFilter = firstLoginFilter; + this.sessionRegistry = sessionRegistry; + this.persistentLoginRepository = persistentLoginRepository; + this.oAuth2userAuthoritiesMapper = oAuth2userAuthoritiesMapper; + this.saml2RelyingPartyRegistrations = saml2RelyingPartyRegistrations; + this.saml2AuthenticationRequestResolver = saml2AuthenticationRequestResolver; + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + if (applicationProperties.getSecurity().getCsrfDisabled() || !loginEnabledValue) { + http.csrf(csrf -> csrf.disable()); + } + + if (loginEnabledValue) { + http.addFilterBefore( + userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + if (!applicationProperties.getSecurity().getCsrfDisabled()) { + CookieCsrfTokenRepository cookieRepo = + CookieCsrfTokenRepository.withHttpOnlyFalse(); + CsrfTokenRequestAttributeHandler requestHandler = + new CsrfTokenRequestAttributeHandler(); + requestHandler.setCsrfRequestAttributeName(null); + http.csrf( + csrf -> + csrf.ignoringRequestMatchers( + request -> { + String apiKey = request.getHeader("X-API-KEY"); + // If there's no API key, don't ignore CSRF + // (return false) + if (apiKey == null || apiKey.trim().isEmpty()) { + return false; + } + // Validate API key using existing UserService + try { + Optional user = + userService.getUserByApiKey(apiKey); + // If API key is valid, ignore CSRF (return + // true) + // If API key is invalid, don't ignore CSRF + // (return false) + return user.isPresent(); + } catch (Exception e) { + // If there's any error validating the API + // key, don't ignore CSRF + return false; + } + }) + .csrfTokenRepository(cookieRepo) + .csrfTokenRequestHandler(requestHandler)); + } + http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class); + http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class); + http.sessionManagement( + sessionManagement -> + sessionManagement + .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) + .maximumSessions(10) + .maxSessionsPreventsLogin(false) + .sessionRegistry(sessionRegistry) + .expiredUrl("/login?logout=true")); + http.authenticationProvider(daoAuthenticationProvider()); + http.requestCache(requestCache -> requestCache.requestCache(new NullRequestCache())); + http.logout( + logout -> + logout.logoutRequestMatcher(new AntPathRequestMatcher("/logout")) + .logoutSuccessHandler( + new CustomLogoutSuccessHandler(applicationProperties, appConfig)) + .clearAuthentication(true) + .invalidateHttpSession(true) + .deleteCookies("JSESSIONID", "remember-me")); + http.rememberMe( + rememberMeConfigurer -> // Use the configurator directly + rememberMeConfigurer + .tokenRepository(persistentTokenRepository()) + .tokenValiditySeconds( // 14 days + 14 * 24 * 60 * 60) + .userDetailsService( // Your existing UserDetailsService + userDetailsService) + .useSecureCookie( // Enable secure cookie + true) + .rememberMeParameter( // Form parameter name + "remember-me") + .rememberMeCookieName( // Cookie name + "remember-me") + .alwaysRemember(false)); + http.authorizeHttpRequests( + authz -> + authz.requestMatchers( + req -> { + String uri = req.getRequestURI(); + String contextPath = req.getContextPath(); + // Remove the context path from the URI + String trimmedUri = + uri.startsWith(contextPath) + ? uri.substring( + contextPath.length()) + : uri; + return trimmedUri.startsWith("/login") + || trimmedUri.startsWith("/oauth") + || trimmedUri.startsWith("/saml2") + || trimmedUri.endsWith(".svg") + || trimmedUri.startsWith("/register") + || trimmedUri.startsWith("/error") + || trimmedUri.startsWith("/images/") + || trimmedUri.startsWith("/public/") + || trimmedUri.startsWith("/css/") + || trimmedUri.startsWith("/fonts/") + || trimmedUri.startsWith("/js/") + || trimmedUri.startsWith( + "/api/v1/info/status"); + }) + .permitAll() + .anyRequest() + .authenticated()); + // Handle User/Password Logins + if (applicationProperties.getSecurity().isUserPass()) { + http.formLogin( + formLogin -> + formLogin + .loginPage("/login") + .successHandler( + new CustomAuthenticationSuccessHandler( + loginAttemptService, userService)) + .failureHandler( + new CustomAuthenticationFailureHandler( + loginAttemptService, userService)) + .defaultSuccessUrl("/") + .permitAll()); + } + // Handle OAUTH2 Logins + if (applicationProperties.getSecurity().isOauth2Active()) { + http.oauth2Login( + oauth2 -> + oauth2.loginPage("/oauth2") + /* + This Custom handler is used to check if the OAUTH2 user trying to log in, already exists in the database. + If user exists, login proceeds as usual. If user does not exist, then it is auto-created but only if 'OAUTH2AutoCreateUser' + is set as true, else login fails with an error message advising the same. + */ + .successHandler( + new CustomOAuth2AuthenticationSuccessHandler( + loginAttemptService, + applicationProperties, + userService)) + .failureHandler( + new CustomOAuth2AuthenticationFailureHandler()) + . // Add existing Authorities from the database + userInfoEndpoint( + userInfoEndpoint -> + userInfoEndpoint + .oidcUserService( + new CustomOAuth2UserService( + applicationProperties, + userService, + loginAttemptService)) + .userAuthoritiesMapper( + oAuth2userAuthoritiesMapper)) + .permitAll()); + } + // Handle SAML + if (applicationProperties.getSecurity().isSaml2Active() && runningProOrHigher) { + // Configure the authentication provider + OpenSaml4AuthenticationProvider authenticationProvider = + new OpenSaml4AuthenticationProvider(); + authenticationProvider.setResponseAuthenticationConverter( + new CustomSaml2ResponseAuthenticationConverter(userService)); + http.authenticationProvider(authenticationProvider) + .saml2Login( + saml2 -> { + try { + saml2.loginPage("/saml2") + .relyingPartyRegistrationRepository( + saml2RelyingPartyRegistrations) + .authenticationManager( + new ProviderManager(authenticationProvider)) + .successHandler( + new CustomSaml2AuthenticationSuccessHandler( + loginAttemptService, + applicationProperties, + userService)) + .failureHandler( + new CustomSaml2AuthenticationFailureHandler()) + .authenticationRequestResolver( + saml2AuthenticationRequestResolver); + } catch (Exception e) { + log.error("Error configuring SAML 2 login", e); + throw new RuntimeException(e); + } + }); + } + } else { + log.debug("Login is not enabled."); + http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll()); + } + return http.build(); + } + + public DaoAuthenticationProvider daoAuthenticationProvider() { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); + provider.setPasswordEncoder(passwordEncoder()); + return provider; + } + + @Bean + public IPRateLimitingFilter rateLimitingFilter() { + // Example limit TODO add config level + int maxRequestsPerIp = 1000000; + return new IPRateLimitingFilter(maxRequestsPerIp, maxRequestsPerIp); + } + + @Bean + public PersistentTokenRepository persistentTokenRepository() { + return new JPATokenRepositoryImpl(persistentLoginRepository); + } +} diff --git a/src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/DatabaseController.java similarity index 97% rename from src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java rename to proprietary/src/main/java/stirling/software/proprietary/security/controller/api/DatabaseController.java index 8e3484f23..bbc84821f 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/DatabaseController.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.controller.api; +package stirling.software.proprietary.security.controller.api; import java.io.IOException; import java.io.InputStream; @@ -26,8 +26,8 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.security.database.DatabaseService; +import stirling.software.proprietary.security.database.H2SQLCondition; +import stirling.software.proprietary.security.service.DatabaseService; @Slf4j @Controller diff --git a/src/main/java/stirling/software/SPDF/controller/api/EmailController.java b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/EmailController.java similarity index 93% rename from src/main/java/stirling/software/SPDF/controller/api/EmailController.java rename to proprietary/src/main/java/stirling/software/proprietary/security/controller/api/EmailController.java index dc1c9dff4..7fb767573 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/EmailController.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/EmailController.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.controller.api; +package stirling.software.proprietary.security.controller.api; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpStatus; @@ -18,8 +18,8 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import stirling.software.SPDF.config.security.mail.EmailService; -import stirling.software.SPDF.model.api.Email; +import stirling.software.proprietary.security.model.api.Email; +import stirling.software.proprietary.security.service.EmailService; /** * Controller for handling email-related API requests. This controller exposes an endpoint for diff --git a/src/main/java/stirling/software/SPDF/controller/api/UserController.java b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/UserController.java similarity index 97% rename from src/main/java/stirling/software/SPDF/controller/api/UserController.java rename to proprietary/src/main/java/stirling/software/proprietary/security/controller/api/UserController.java index 1f2ccd1fd..dec5905ba 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/UserController.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/UserController.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.controller.api; +package stirling.software.proprietary.security.controller.api; import java.io.IOException; import java.security.Principal; @@ -29,15 +29,15 @@ import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import stirling.software.SPDF.config.security.UserService; -import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal; -import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; -import stirling.software.SPDF.model.AuthenticationType; -import stirling.software.SPDF.model.Role; -import stirling.software.SPDF.model.User; -import stirling.software.SPDF.model.api.user.UsernameAndPass; +import stirling.software.proprietary.security.model.AuthenticationType; +import stirling.software.common.model.enumeration.Role; +import stirling.software.proprietary.security.model.User; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.exception.UnsupportedProviderException; +import stirling.software.proprietary.security.model.api.user.UsernameAndPass; +import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; +import stirling.software.proprietary.security.service.UserService; +import stirling.software.proprietary.security.session.SessionPersistentRegistry; @Controller @Tag(name = "User", description = "User APIs") diff --git a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java b/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/AccountWebController.java similarity index 97% rename from src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java rename to proprietary/src/main/java/stirling/software/proprietary/security/controller/web/AccountWebController.java index 1962dffb8..311f81a4f 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/AccountWebController.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.controller.web; +package stirling.software.proprietary.security.controller.web; import static stirling.software.common.util.ProviderUtils.validateProvider; @@ -29,13 +29,7 @@ import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; -import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal; -import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; -import stirling.software.SPDF.model.Authority; -import stirling.software.SPDF.model.Role; -import stirling.software.SPDF.model.SessionEntity; -import stirling.software.SPDF.model.User; -import stirling.software.SPDF.repository.UserRepository; +import stirling.software.common.model.enumeration.Role; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; @@ -44,6 +38,12 @@ import stirling.software.common.model.ApplicationProperties.Security.SAML2; import stirling.software.common.model.oauth2.GitHubProvider; import stirling.software.common.model.oauth2.GoogleProvider; import stirling.software.common.model.oauth2.KeycloakProvider; +import stirling.software.proprietary.security.database.repository.UserRepository; +import stirling.software.proprietary.security.model.Authority; +import stirling.software.proprietary.security.model.SessionEntity; +import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; +import stirling.software.proprietary.security.session.SessionPersistentRegistry; @Controller @Slf4j diff --git a/src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java b/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/DatabaseWebController.java similarity index 92% rename from src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java rename to proprietary/src/main/java/stirling/software/proprietary/security/controller/web/DatabaseWebController.java index 1291895f3..940c0c13f 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/DatabaseWebController.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.controller.web; +package stirling.software.proprietary.security.controller.web; import java.util.List; @@ -14,8 +14,8 @@ import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; -import stirling.software.SPDF.config.security.database.DatabaseService; import stirling.software.common.model.FileInfo; +import stirling.software.proprietary.security.service.DatabaseService; @Controller @Tag(name = "Database Management", description = "Database management and security APIs") diff --git a/src/main/java/stirling/software/SPDF/controller/api/H2SQLCondition.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/H2SQLCondition.java similarity index 77% rename from src/main/java/stirling/software/SPDF/controller/api/H2SQLCondition.java rename to proprietary/src/main/java/stirling/software/proprietary/security/database/H2SQLCondition.java index ebdb1f058..4e259e49b 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/H2SQLCondition.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/H2SQLCondition.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.controller.api; +package stirling.software.proprietary.security.database; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; @@ -12,8 +12,12 @@ public class H2SQLCondition implements Condition { Boolean.parseBoolean( context.getEnvironment() .getProperty("system.datasource.enableCustomDatabase")); + + if (!enableCustomDatabase) { + return false; + } + String dataSourceType = context.getEnvironment().getProperty("system.datasource.type"); - return !enableCustomDatabase - || (enableCustomDatabase && "h2".equalsIgnoreCase(dataSourceType)); + return "h2".equalsIgnoreCase(dataSourceType); } } diff --git a/src/main/java/stirling/software/SPDF/config/security/database/ScheduledTasks.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/ScheduledTasks.java similarity index 71% rename from src/main/java/stirling/software/SPDF/config/security/database/ScheduledTasks.java rename to proprietary/src/main/java/stirling/software/proprietary/security/database/ScheduledTasks.java index 73a33972a..835dc1917 100644 --- a/src/main/java/stirling/software/SPDF/config/security/database/ScheduledTasks.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/ScheduledTasks.java @@ -1,23 +1,19 @@ -package stirling.software.SPDF.config.security.database; +package stirling.software.proprietary.security.database; import java.sql.SQLException; - +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Conditional; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; - -import lombok.RequiredArgsConstructor; - -import stirling.software.SPDF.config.interfaces.DatabaseInterface; -import stirling.software.SPDF.controller.api.H2SQLCondition; import stirling.software.common.model.exception.UnsupportedProviderException; +import stirling.software.proprietary.security.service.DatabaseServiceInterface; @Component @Conditional(H2SQLCondition.class) @RequiredArgsConstructor public class ScheduledTasks { - private final DatabaseInterface databaseService; + private final DatabaseServiceInterface databaseService; @Scheduled(cron = "0 0 0 * * ?") public void performBackup() throws SQLException, UnsupportedProviderException { diff --git a/src/main/java/stirling/software/SPDF/repository/AuthorityRepository.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/AuthorityRepository.java similarity index 74% rename from src/main/java/stirling/software/SPDF/repository/AuthorityRepository.java rename to proprietary/src/main/java/stirling/software/proprietary/security/database/repository/AuthorityRepository.java index 01f23dd91..a7773d859 100644 --- a/src/main/java/stirling/software/SPDF/repository/AuthorityRepository.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/AuthorityRepository.java @@ -1,11 +1,10 @@ -package stirling.software.SPDF.repository; +package stirling.software.proprietary.security.database.repository; import java.util.Set; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; - -import stirling.software.SPDF.model.Authority; +import stirling.software.proprietary.security.model.Authority; @Repository public interface AuthorityRepository extends JpaRepository { diff --git a/src/main/java/stirling/software/SPDF/repository/JPATokenRepositoryImpl.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/JPATokenRepositoryImpl.java similarity index 93% rename from src/main/java/stirling/software/SPDF/repository/JPATokenRepositoryImpl.java rename to proprietary/src/main/java/stirling/software/proprietary/security/database/repository/JPATokenRepositoryImpl.java index 98becfd48..b98a8094f 100644 --- a/src/main/java/stirling/software/SPDF/repository/JPATokenRepositoryImpl.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/JPATokenRepositoryImpl.java @@ -1,12 +1,11 @@ -package stirling.software.SPDF.repository; +package stirling.software.proprietary.security.database.repository; import java.util.Date; import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.transaction.annotation.Transactional; - -import stirling.software.SPDF.model.PersistentLogin; +import stirling.software.proprietary.security.model.PersistentLogin; public class JPATokenRepositoryImpl implements PersistentTokenRepository { diff --git a/src/main/java/stirling/software/SPDF/repository/PersistentLoginRepository.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/PersistentLoginRepository.java similarity index 65% rename from src/main/java/stirling/software/SPDF/repository/PersistentLoginRepository.java rename to proprietary/src/main/java/stirling/software/proprietary/security/database/repository/PersistentLoginRepository.java index e8ef19ce2..a9ddf8a37 100644 --- a/src/main/java/stirling/software/SPDF/repository/PersistentLoginRepository.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/PersistentLoginRepository.java @@ -1,9 +1,8 @@ -package stirling.software.SPDF.repository; +package stirling.software.proprietary.security.database.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; - -import stirling.software.SPDF.model.PersistentLogin; +import stirling.software.proprietary.security.model.PersistentLogin; @Repository public interface PersistentLoginRepository extends JpaRepository { diff --git a/src/main/java/stirling/software/SPDF/config/security/session/SessionRepository.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/SessionRepository.java similarity index 79% rename from src/main/java/stirling/software/SPDF/config/security/session/SessionRepository.java rename to proprietary/src/main/java/stirling/software/proprietary/security/database/repository/SessionRepository.java index d4f2f4bcc..b7a7d7a84 100644 --- a/src/main/java/stirling/software/SPDF/config/security/session/SessionRepository.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/SessionRepository.java @@ -1,21 +1,16 @@ -package stirling.software.SPDF.config.security.session; +package stirling.software.proprietary.security.database.repository; +import jakarta.transaction.Transactional; import java.util.Date; import java.util.List; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; - -import jakarta.transaction.Transactional; - -import stirling.software.SPDF.model.SessionEntity; +import stirling.software.proprietary.security.model.SessionEntity; @Repository -@ConditionalOnProperty(name = "premium.enabled", havingValue = "true") public interface SessionRepository extends JpaRepository { List findByPrincipalName(String principalName); diff --git a/src/main/java/stirling/software/SPDF/repository/UserRepository.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/UserRepository.java similarity index 86% rename from src/main/java/stirling/software/SPDF/repository/UserRepository.java rename to proprietary/src/main/java/stirling/software/proprietary/security/database/repository/UserRepository.java index e1f53efb8..dcf84ee19 100644 --- a/src/main/java/stirling/software/SPDF/repository/UserRepository.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/UserRepository.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.repository; +package stirling.software.proprietary.security.database.repository; import java.util.List; import java.util.Optional; @@ -7,8 +7,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; - -import stirling.software.SPDF.model.User; +import stirling.software.proprietary.security.model.User; @Repository public interface UserRepository extends JpaRepository { diff --git a/src/main/java/stirling/software/SPDF/config/EnterpriseEndpointFilter.java b/proprietary/src/main/java/stirling/software/proprietary/security/filter/EnterpriseEndpointFilter.java similarity index 95% rename from src/main/java/stirling/software/SPDF/config/EnterpriseEndpointFilter.java rename to proprietary/src/main/java/stirling/software/proprietary/security/filter/EnterpriseEndpointFilter.java index 040e0e070..5ee61f8ff 100644 --- a/src/main/java/stirling/software/SPDF/config/EnterpriseEndpointFilter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/filter/EnterpriseEndpointFilter.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.config; +package stirling.software.proprietary.security.filter; import java.io.IOException; diff --git a/src/main/java/stirling/software/SPDF/config/security/FirstLoginFilter.java b/proprietary/src/main/java/stirling/software/proprietary/security/filter/FirstLoginFilter.java similarity index 94% rename from src/main/java/stirling/software/SPDF/config/security/FirstLoginFilter.java rename to proprietary/src/main/java/stirling/software/proprietary/security/filter/FirstLoginFilter.java index edada16dd..a96e6e769 100644 --- a/src/main/java/stirling/software/SPDF/config/security/FirstLoginFilter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/filter/FirstLoginFilter.java @@ -1,26 +1,23 @@ -package stirling.software.SPDF.config.security; - -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Optional; - -import org.springframework.context.annotation.Lazy; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; +package stirling.software.proprietary.security.filter; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; - +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Optional; import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.model.User; +import org.springframework.context.annotation.Lazy; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; import stirling.software.common.util.RequestUriUtils; +import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.service.UserService; @Slf4j @Component diff --git a/src/main/java/stirling/software/SPDF/config/security/IPRateLimitingFilter.java b/proprietary/src/main/java/stirling/software/proprietary/security/filter/IPRateLimitingFilter.java similarity index 90% rename from src/main/java/stirling/software/SPDF/config/security/IPRateLimitingFilter.java rename to proprietary/src/main/java/stirling/software/proprietary/security/filter/IPRateLimitingFilter.java index 5d2c67350..ebc0f949e 100644 --- a/src/main/java/stirling/software/SPDF/config/security/IPRateLimitingFilter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/filter/IPRateLimitingFilter.java @@ -1,14 +1,15 @@ -package stirling.software.SPDF.config.security; +package stirling.software.proprietary.security.filter; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; - -import jakarta.servlet.*; -import jakarta.servlet.http.HttpServletRequest; - import lombok.RequiredArgsConstructor; - import stirling.software.common.util.RequestUriUtils; @RequiredArgsConstructor diff --git a/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java b/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserAuthenticationFilter.java similarity index 96% rename from src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java rename to proprietary/src/main/java/stirling/software/proprietary/security/filter/UserAuthenticationFilter.java index 5208e8f25..de97ec785 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserAuthenticationFilter.java @@ -1,11 +1,14 @@ -package stirling.software.SPDF.config.security; +package stirling.software.proprietary.security.filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; import java.util.Optional; - +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; @@ -17,25 +20,17 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; - -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal; -import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; -import stirling.software.SPDF.model.ApiKeyAuthenticationToken; -import stirling.software.SPDF.model.User; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.ApplicationProperties.Security.SAML2; +import stirling.software.proprietary.security.model.ApiKeyAuthenticationToken; +import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; +import stirling.software.proprietary.security.service.UserService; +import stirling.software.proprietary.security.session.SessionPersistentRegistry; @Slf4j @Component -@ConditionalOnProperty(name = "premium.enabled", havingValue = "true") public class UserAuthenticationFilter extends OncePerRequestFilter { private final ApplicationProperties.Security securityProp; diff --git a/src/main/java/stirling/software/SPDF/config/security/UserBasedRateLimitingFilter.java b/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserBasedRateLimitingFilter.java similarity index 98% rename from src/main/java/stirling/software/SPDF/config/security/UserBasedRateLimitingFilter.java rename to proprietary/src/main/java/stirling/software/proprietary/security/filter/UserBasedRateLimitingFilter.java index 5ca7df214..31db979b0 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserBasedRateLimitingFilter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserBasedRateLimitingFilter.java @@ -1,10 +1,17 @@ -package stirling.software.SPDF.config.security; +package stirling.software.proprietary.security.filter; +import io.github.bucket4j.Bandwidth; +import io.github.bucket4j.Bucket; +import io.github.bucket4j.ConsumptionProbe; +import io.github.pixee.security.Newlines; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.Duration; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; @@ -13,18 +20,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; - -import io.github.bucket4j.Bandwidth; -import io.github.bucket4j.Bucket; -import io.github.bucket4j.ConsumptionProbe; -import io.github.pixee.security.Newlines; - -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import stirling.software.SPDF.model.Role; +import stirling.software.common.model.enumeration.Role; @Component public class UserBasedRateLimitingFilter extends OncePerRequestFilter { diff --git a/src/main/java/stirling/software/SPDF/model/ApiKeyAuthenticationToken.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/ApiKeyAuthenticationToken.java similarity index 96% rename from src/main/java/stirling/software/SPDF/model/ApiKeyAuthenticationToken.java rename to proprietary/src/main/java/stirling/software/proprietary/security/model/ApiKeyAuthenticationToken.java index f19fa1e95..1db14aaaf 100644 --- a/src/main/java/stirling/software/SPDF/model/ApiKeyAuthenticationToken.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/ApiKeyAuthenticationToken.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.model; +package stirling.software.proprietary.security.model; import java.util.Collection; diff --git a/src/main/java/stirling/software/SPDF/model/AttemptCounter.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/AttemptCounter.java similarity index 93% rename from src/main/java/stirling/software/SPDF/model/AttemptCounter.java rename to proprietary/src/main/java/stirling/software/proprietary/security/model/AttemptCounter.java index 8267bddb7..18ca598ae 100644 --- a/src/main/java/stirling/software/SPDF/model/AttemptCounter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/AttemptCounter.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.model; +package stirling.software.proprietary.security.model; public class AttemptCounter { private int attemptCount; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/AuthenticationType.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/AuthenticationType.java new file mode 100644 index 000000000..ca8140bca --- /dev/null +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/AuthenticationType.java @@ -0,0 +1,6 @@ +package stirling.software.proprietary.security.model; + +public enum AuthenticationType { + WEB, + SSO +} diff --git a/src/main/java/stirling/software/SPDF/model/Authority.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/Authority.java similarity index 94% rename from src/main/java/stirling/software/SPDF/model/Authority.java rename to proprietary/src/main/java/stirling/software/proprietary/security/model/Authority.java index 4a0ed7255..382d3a71e 100644 --- a/src/main/java/stirling/software/SPDF/model/Authority.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/Authority.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.model; +package stirling.software.proprietary.security.model; import java.io.Serializable; diff --git a/src/main/java/stirling/software/SPDF/model/PersistentLogin.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/PersistentLogin.java similarity index 91% rename from src/main/java/stirling/software/SPDF/model/PersistentLogin.java rename to proprietary/src/main/java/stirling/software/proprietary/security/model/PersistentLogin.java index c0990199c..ef096f7fb 100644 --- a/src/main/java/stirling/software/SPDF/model/PersistentLogin.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/PersistentLogin.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.model; +package stirling.software.proprietary.security.model; import java.util.Date; diff --git a/src/main/java/stirling/software/SPDF/model/SessionEntity.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/SessionEntity.java similarity index 88% rename from src/main/java/stirling/software/SPDF/model/SessionEntity.java rename to proprietary/src/main/java/stirling/software/proprietary/security/model/SessionEntity.java index bba7b33dc..db94eae6f 100644 --- a/src/main/java/stirling/software/SPDF/model/SessionEntity.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/SessionEntity.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.model; +package stirling.software.proprietary.security.model; import java.io.Serializable; import java.util.Date; diff --git a/src/main/java/stirling/software/SPDF/model/User.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java similarity index 95% rename from src/main/java/stirling/software/SPDF/model/User.java rename to proprietary/src/main/java/stirling/software/proprietary/security/model/User.java index 1eb9da991..6dc32a85d 100644 --- a/src/main/java/stirling/software/SPDF/model/User.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.model; +package stirling.software.proprietary.security.model; import java.io.Serializable; import java.util.HashMap; @@ -14,6 +14,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; +import stirling.software.common.model.enumeration.Role; @Entity @Table(name = "users") diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/api/Email.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/Email.java new file mode 100644 index 000000000..8fe3cebe6 --- /dev/null +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/Email.java @@ -0,0 +1,39 @@ +package stirling.software.proprietary.security.model.api; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import stirling.software.common.model.api.GeneralFile; + +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +@ConditionalOnProperty(value = "mail.enabled", havingValue = "true", matchIfMissing = false) +public class Email extends GeneralFile { + + @Schema( + description = "The recipient's email address", + requiredMode = Schema.RequiredMode.REQUIRED, + format = "email") + private String to; + + @Schema( + description = "The subject of the email", + defaultValue = "Stirling Software PDF Notification", + requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String subject; + + @Schema( + description = "The body of the email", + requiredMode = Schema.RequiredMode.NOT_REQUIRED, + defaultValue = + "This message was automatically generated by Stirling-PDF, an innovative" + + " solution from Stirling Software. For more information, visit our website.

Please do" + + " not reply directly to this email.") + private String body; +} diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UpdateUserDetails.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UpdateUserDetails.java new file mode 100644 index 000000000..3f630f61d --- /dev/null +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UpdateUserDetails.java @@ -0,0 +1,17 @@ +package stirling.software.proprietary.security.model.api.user; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class UpdateUserDetails extends UpdateUserUsername { + + @Schema( + description = "new password for user", + format = "password", + requiredMode = Schema.RequiredMode.REQUIRED) + private String newPassword; +} diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UpdateUserUsername.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UpdateUserUsername.java new file mode 100644 index 000000000..d158e6b32 --- /dev/null +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UpdateUserUsername.java @@ -0,0 +1,14 @@ +package stirling.software.proprietary.security.model.api.user; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class UpdateUserUsername extends UsernameAndPass { + + @Schema(description = "new username for user") + private String newUsername; +} diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/Username.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/Username.java new file mode 100644 index 000000000..c5fd081f6 --- /dev/null +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/Username.java @@ -0,0 +1,14 @@ +package stirling.software.proprietary.security.model.api.user; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode +public class Username { + + @Schema(description = "username of user", requiredMode = Schema.RequiredMode.REQUIRED) + private String username; +} diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UsernameAndPass.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UsernameAndPass.java new file mode 100644 index 000000000..0a21cba87 --- /dev/null +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/user/UsernameAndPass.java @@ -0,0 +1,14 @@ +package stirling.software.proprietary.security.model.api.user; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class UsernameAndPass extends Username { + + @Schema(description = "password of user", format = "password") + private String password; +} diff --git a/src/main/java/stirling/software/SPDF/model/exception/BackupNotFoundException.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/exception/BackupNotFoundException.java similarity index 70% rename from src/main/java/stirling/software/SPDF/model/exception/BackupNotFoundException.java rename to proprietary/src/main/java/stirling/software/proprietary/security/model/exception/BackupNotFoundException.java index 7e0649ce9..3aeb0096b 100644 --- a/src/main/java/stirling/software/SPDF/model/exception/BackupNotFoundException.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/exception/BackupNotFoundException.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.model.exception; +package stirling.software.proprietary.security.model.exception; public class BackupNotFoundException extends RuntimeException { public BackupNotFoundException(String message) { diff --git a/src/main/java/stirling/software/SPDF/model/exception/NoProviderFoundException.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/exception/NoProviderFoundException.java similarity index 79% rename from src/main/java/stirling/software/SPDF/model/exception/NoProviderFoundException.java rename to proprietary/src/main/java/stirling/software/proprietary/security/model/exception/NoProviderFoundException.java index 162070f38..310821253 100644 --- a/src/main/java/stirling/software/SPDF/model/exception/NoProviderFoundException.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/exception/NoProviderFoundException.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.model.exception; +package stirling.software.proprietary.security.model.exception; public class NoProviderFoundException extends Exception { public NoProviderFoundException(String message) { diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java similarity index 97% rename from src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java rename to proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java index 9440a6718..92b053b8a 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java @@ -1,7 +1,10 @@ -package stirling.software.SPDF.config.security.oauth2; +package stirling.software.proprietary.security.oauth2; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; - +import lombok.extern.slf4j.Slf4j; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.DisabledException; import org.springframework.security.authentication.LockedException; @@ -10,12 +13,6 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2Error; 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; - @Slf4j public class CustomOAuth2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java similarity index 94% rename from src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java rename to proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java index 986118466..1c4d04e55 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java @@ -1,29 +1,25 @@ -package stirling.software.SPDF.config.security.oauth2; +package stirling.software.proprietary.security.oauth2; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.sql.SQLException; - +import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.LockedException; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.savedrequest.SavedRequest; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.http.HttpSession; - -import lombok.RequiredArgsConstructor; - -import stirling.software.SPDF.config.security.LoginAttemptService; -import stirling.software.SPDF.config.security.UserService; -import stirling.software.SPDF.model.AuthenticationType; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.exception.UnsupportedProviderException; import stirling.software.common.util.RequestUriUtils; +import stirling.software.proprietary.security.model.AuthenticationType; +import stirling.software.proprietary.security.service.LoginAttemptService; +import stirling.software.proprietary.security.service.UserService; @RequiredArgsConstructor public class CustomOAuth2AuthenticationSuccessHandler diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java similarity index 96% rename from src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java rename to proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java index 98d69113c..a0f11c5b2 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java @@ -1,15 +1,12 @@ -package stirling.software.SPDF.config.security.oauth2; - -import static org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE; -import static stirling.software.common.util.ProviderUtils.validateProvider; -import static stirling.software.common.util.ValidationUtils.isStringEmpty; +package stirling.software.proprietary.security.oauth2; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; - +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -22,24 +19,25 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio import org.springframework.security.oauth2.client.registration.ClientRegistrations; import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; - -import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.security.UserService; -import stirling.software.SPDF.model.User; -import stirling.software.SPDF.model.exception.NoProviderFoundException; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2.Client; import stirling.software.common.model.enumeration.UsernameAttribute; +import stirling.software.proprietary.security.model.exception.NoProviderFoundException; import stirling.software.common.model.oauth2.GitHubProvider; import stirling.software.common.model.oauth2.GoogleProvider; import stirling.software.common.model.oauth2.KeycloakProvider; import stirling.software.common.model.oauth2.Provider; +import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.service.UserService; +import static org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE; +import static stirling.software.common.util.ProviderUtils.validateProvider; +import static stirling.software.common.util.ValidationUtils.isStringEmpty; @Slf4j @Configuration @ConditionalOnProperty(value = "security.oauth2.enabled", havingValue = "true") +@ConditionalOnExpression("${docker.enable.security:true}") // todo: change this public class OAuth2Configuration { public static final String REDIRECT_URI_PATH = "{baseUrl}/login/oauth2/code/"; diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CertificateUtils.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java similarity index 97% rename from src/main/java/stirling/software/SPDF/config/security/saml2/CertificateUtils.java rename to proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java index 354e78750..c2957e241 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CertificateUtils.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.config.security.saml2; +package stirling.software.proprietary.security.saml2; import java.io.ByteArrayInputStream; import java.io.InputStreamReader; @@ -6,7 +6,6 @@ import java.nio.charset.StandardCharsets; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; - import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticatedPrincipal.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java similarity index 93% rename from src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticatedPrincipal.java rename to proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java index fbcdb31b4..055ac8f4e 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticatedPrincipal.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java @@ -1,9 +1,8 @@ -package stirling.software.SPDF.config.security.saml2; +package stirling.software.proprietary.security.saml2; import java.io.Serializable; import java.util.List; import java.util.Map; - import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java similarity index 96% rename from src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationFailureHandler.java rename to proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java index 884c3bd2e..a7e663aac 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java @@ -1,7 +1,9 @@ -package stirling.software.SPDF.config.security.saml2; +package stirling.software.proprietary.security.saml2; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; - +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.authentication.ProviderNotFoundException; import org.springframework.security.core.AuthenticationException; @@ -9,11 +11,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.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import lombok.extern.slf4j.Slf4j; - @Slf4j @ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true") public class CustomSaml2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationSuccessHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationSuccessHandler.java similarity index 95% rename from src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationSuccessHandler.java rename to proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationSuccessHandler.java index 94fddae62..47391e4d0 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2AuthenticationSuccessHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationSuccessHandler.java @@ -1,28 +1,24 @@ -package stirling.software.SPDF.config.security.saml2; - -import java.io.IOException; -import java.sql.SQLException; - -import org.springframework.security.authentication.LockedException; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import org.springframework.security.web.savedrequest.SavedRequest; +package stirling.software.proprietary.security.saml2; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; - +import java.io.IOException; +import java.sql.SQLException; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.security.LoginAttemptService; -import stirling.software.SPDF.config.security.UserService; -import stirling.software.SPDF.model.AuthenticationType; +import org.springframework.security.authentication.LockedException; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; +import org.springframework.security.web.savedrequest.SavedRequest; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.SAML2; import stirling.software.common.model.exception.UnsupportedProviderException; import stirling.software.common.util.RequestUriUtils; +import stirling.software.proprietary.security.model.AuthenticationType; +import stirling.software.proprietary.security.service.LoginAttemptService; +import stirling.software.proprietary.security.service.UserService; @AllArgsConstructor @Slf4j diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2ResponseAuthenticationConverter.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2ResponseAuthenticationConverter.java similarity index 94% rename from src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2ResponseAuthenticationConverter.java rename to proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2ResponseAuthenticationConverter.java index 4a9cdd284..d1c24b420 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/CustomSaml2ResponseAuthenticationConverter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2ResponseAuthenticationConverter.java @@ -1,7 +1,12 @@ -package stirling.software.SPDF.config.security.saml2; - -import java.util.*; +package stirling.software.proprietary.security.saml2; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.opensaml.core.xml.XMLObject; import org.opensaml.saml.saml2.core.Assertion; import org.opensaml.saml.saml2.core.Attribute; @@ -12,12 +17,8 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.ResponseToken; import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.security.UserService; -import stirling.software.SPDF.model.User; +import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.service.UserService; @Slf4j @ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true") diff --git a/src/main/java/stirling/software/SPDF/config/security/saml2/SAML2Configuration.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java similarity index 99% rename from src/main/java/stirling/software/SPDF/config/security/saml2/SAML2Configuration.java rename to proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java index 8a6ff10cc..8482b8753 100644 --- a/src/main/java/stirling/software/SPDF/config/security/saml2/SAML2Configuration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java @@ -1,9 +1,11 @@ -package stirling.software.SPDF.config.security.saml2; +package stirling.software.proprietary.security.saml2; +import jakarta.servlet.http.HttpServletRequest; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.UUID; - +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.opensaml.saml.saml2.core.AuthnRequest; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -18,12 +20,6 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository; import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; - -import jakarta.servlet.http.HttpServletRequest; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.SAML2; diff --git a/src/main/java/stirling/software/SPDF/config/security/AppUpdateAuthService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/AppUpdateAuthService.java similarity index 83% rename from src/main/java/stirling/software/SPDF/config/security/AppUpdateAuthService.java rename to proprietary/src/main/java/stirling/software/proprietary/security/service/AppUpdateAuthService.java index 7139fc686..5687a3b92 100644 --- a/src/main/java/stirling/software/SPDF/config/security/AppUpdateAuthService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/AppUpdateAuthService.java @@ -1,17 +1,14 @@ -package stirling.software.SPDF.config.security; +package stirling.software.proprietary.security.service; import java.util.Optional; - +import lombok.RequiredArgsConstructor; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; - -import lombok.RequiredArgsConstructor; - -import stirling.software.SPDF.config.interfaces.ShowAdminInterface; -import stirling.software.SPDF.model.User; -import stirling.software.SPDF.repository.UserRepository; +import stirling.software.common.configuration.interfaces.ShowAdminInterface; import stirling.software.common.model.ApplicationProperties; +import stirling.software.proprietary.security.database.repository.UserRepository; +import stirling.software.proprietary.security.model.User; @Service @RequiredArgsConstructor diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2UserService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomOAuth2UserService.java similarity index 94% rename from src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2UserService.java rename to proprietary/src/main/java/stirling/software/proprietary/security/service/CustomOAuth2UserService.java index 458dd3477..b889a06e5 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2UserService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomOAuth2UserService.java @@ -1,7 +1,7 @@ -package stirling.software.SPDF.config.security.oauth2; +package stirling.software.proprietary.security.service; import java.util.Optional; - +import lombok.extern.slf4j.Slf4j; import org.springframework.security.authentication.LockedException; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; @@ -10,15 +10,10 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.security.oauth2.core.oidc.user.OidcUser; - -import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.security.LoginAttemptService; -import stirling.software.SPDF.config.security.UserService; -import stirling.software.SPDF.model.User; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.enumeration.UsernameAttribute; +import stirling.software.proprietary.security.model.User; @Slf4j public class CustomOAuth2UserService implements OAuth2UserService { diff --git a/src/main/java/stirling/software/SPDF/config/security/CustomUserDetailsService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java similarity index 89% rename from src/main/java/stirling/software/SPDF/config/security/CustomUserDetailsService.java rename to proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java index 74c3fb9a4..014666971 100644 --- a/src/main/java/stirling/software/SPDF/config/security/CustomUserDetailsService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java @@ -1,8 +1,8 @@ -package stirling.software.SPDF.config.security; +package stirling.software.proprietary.security.service; import java.util.Collection; import java.util.Set; - +import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.LockedException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -10,12 +10,9 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; - -import lombok.RequiredArgsConstructor; - -import stirling.software.SPDF.model.Authority; -import stirling.software.SPDF.model.User; -import stirling.software.SPDF.repository.UserRepository; +import stirling.software.proprietary.security.database.repository.UserRepository; +import stirling.software.proprietary.security.model.Authority; +import stirling.software.proprietary.security.model.User; @Service @RequiredArgsConstructor diff --git a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseService.java similarity index 91% rename from src/main/java/stirling/software/SPDF/config/security/database/DatabaseService.java rename to proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseService.java index f973079b6..37de87cf4 100644 --- a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseService.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.config.security.database; +package stirling.software.proprietary.security.service; import java.io.IOException; import java.nio.file.DirectoryStream; @@ -18,24 +18,19 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; - import javax.sql.DataSource; - +import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.datasource.init.CannotReadScriptException; import org.springframework.jdbc.datasource.init.ScriptException; import org.springframework.stereotype.Service; - -import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.interfaces.DatabaseInterface; -import stirling.software.SPDF.model.exception.BackupNotFoundException; import stirling.software.common.configuration.InstallationPathConfig; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.FileInfo; +import stirling.software.proprietary.security.model.exception.BackupNotFoundException; @Slf4j @Service -public class DatabaseService implements DatabaseInterface { +public class DatabaseService implements DatabaseServiceInterface { public static final String BACKUP_PREFIX = "backup_"; public static final String SQL_SUFFIX = ".sql"; @@ -240,27 +235,27 @@ public class DatabaseService implements DatabaseInterface { private boolean isH2Database() { boolean isTypeH2 = - datasourceProps.getType().equalsIgnoreCase(ApplicationProperties.Driver.H2.name()); + datasourceProps.getType().equalsIgnoreCase(ApplicationProperties.Driver.H2.name()); boolean isDBUrlH2 = - datasourceProps.getCustomDatabaseUrl().contains("h2") - || datasourceProps.getCustomDatabaseUrl().contains("H2"); + datasourceProps.getCustomDatabaseUrl().contains("h2") + || datasourceProps.getCustomDatabaseUrl().contains("H2"); boolean isCustomDatabase = datasourceProps.isEnableCustomDatabase(); if (isCustomDatabase) { if (isTypeH2 && !isDBUrlH2) { log.warn( - "Datasource type is H2, but the URL does not contain 'h2'. " - + "Please check your configuration."); + "Datasource type is H2, but the URL does not contain 'h2'. " + + "Please check your configuration."); throw new IllegalStateException( - "Datasource type is H2, but the URL does not contain 'h2'. Please check" - + " your configuration."); + "Datasource type is H2, but the URL does not contain 'h2'. Please check" + + " your configuration."); } else if (!isTypeH2 && isDBUrlH2) { log.warn( - "Datasource URL contains 'h2', but the type is not H2. " - + "Please check your configuration."); + "Datasource URL contains 'h2', but the type is not H2. " + + "Please check your configuration."); throw new IllegalStateException( - "Datasource URL contains 'h2', but the type is not H2. Please check your" - + " configuration."); + "Datasource URL contains 'h2', but the type is not H2. Please check your" + + " configuration."); } } boolean isH2 = isTypeH2 && isDBUrlH2; diff --git a/src/main/java/stirling/software/SPDF/config/interfaces/DatabaseInterface.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseServiceInterface.java similarity index 77% rename from src/main/java/stirling/software/SPDF/config/interfaces/DatabaseInterface.java rename to proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseServiceInterface.java index ae802fdc5..613432f0a 100644 --- a/src/main/java/stirling/software/SPDF/config/interfaces/DatabaseInterface.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseServiceInterface.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.config.interfaces; +package stirling.software.proprietary.security.service; import java.sql.SQLException; import java.util.List; @@ -6,7 +6,7 @@ import java.util.List; import stirling.software.common.model.FileInfo; import stirling.software.common.model.exception.UnsupportedProviderException; -public interface DatabaseInterface { +public interface DatabaseServiceInterface { void exportDatabase() throws SQLException, UnsupportedProviderException; void importDatabase(); diff --git a/src/main/java/stirling/software/SPDF/config/security/mail/EmailService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/EmailService.java similarity index 96% rename from src/main/java/stirling/software/SPDF/config/security/mail/EmailService.java rename to proprietary/src/main/java/stirling/software/proprietary/security/service/EmailService.java index e27a2b681..08860a340 100644 --- a/src/main/java/stirling/software/SPDF/config/security/mail/EmailService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/EmailService.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.config.security.mail; +package stirling.software.proprietary.security.service; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.mail.javamail.JavaMailSender; @@ -12,8 +12,8 @@ import jakarta.mail.internet.MimeMessage; import lombok.RequiredArgsConstructor; -import stirling.software.SPDF.model.api.Email; import stirling.software.common.model.ApplicationProperties; +import stirling.software.proprietary.security.model.api.Email; /** * Service class responsible for sending emails, including those with attachments. It uses diff --git a/src/main/java/stirling/software/SPDF/config/security/LoginAttemptService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/LoginAttemptService.java similarity index 95% rename from src/main/java/stirling/software/SPDF/config/security/LoginAttemptService.java rename to proprietary/src/main/java/stirling/software/proprietary/security/service/LoginAttemptService.java index 9beba4760..852fc8ab9 100644 --- a/src/main/java/stirling/software/SPDF/config/security/LoginAttemptService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/LoginAttemptService.java @@ -1,17 +1,13 @@ -package stirling.software.SPDF.config.security; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; - -import org.springframework.stereotype.Service; +package stirling.software.proprietary.security.service; import jakarta.annotation.PostConstruct; - +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.model.AttemptCounter; +import org.springframework.stereotype.Service; import stirling.software.common.model.ApplicationProperties; +import stirling.software.proprietary.security.model.AttemptCounter; @Service @Slf4j diff --git a/src/main/java/stirling/software/SPDF/config/security/UserService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/UserService.java similarity index 95% rename from src/main/java/stirling/software/SPDF/config/security/UserService.java rename to proprietary/src/main/java/stirling/software/proprietary/security/service/UserService.java index 068fde1d4..7bf3e2643 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/UserService.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.config.security; +package stirling.software.proprietary.security.service; import java.io.IOException; import java.sql.SQLException; @@ -9,9 +9,9 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; - +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.MessageSource; -import org.springframework.context.annotation.Lazy; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -25,22 +25,17 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.interfaces.DatabaseInterface; -import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal; -import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; -import stirling.software.SPDF.model.AuthenticationType; -import stirling.software.SPDF.model.Authority; -import stirling.software.SPDF.model.Role; -import stirling.software.SPDF.model.User; -import stirling.software.SPDF.repository.AuthorityRepository; -import stirling.software.SPDF.repository.UserRepository; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.exception.UnsupportedProviderException; import stirling.software.common.service.UserServiceInterface; +import stirling.software.common.model.enumeration.Role; +import stirling.software.proprietary.security.database.repository.AuthorityRepository; +import stirling.software.proprietary.security.database.repository.UserRepository; +import stirling.software.proprietary.security.model.AuthenticationType; +import stirling.software.proprietary.security.model.Authority; +import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; +import stirling.software.proprietary.security.session.SessionPersistentRegistry; @Service @Slf4j @@ -57,7 +52,7 @@ public class UserService implements UserServiceInterface { private final SessionPersistentRegistry sessionRegistry; - @Lazy private final DatabaseInterface databaseService; + private final DatabaseServiceInterface databaseService; private final ApplicationProperties.Security.OAUTH2 oAuth2; @@ -307,7 +302,6 @@ public class UserService implements UserServiceInterface { public void changeUsername(User user, String newUsername) throws IllegalArgumentException, - IOException, SQLException, UnsupportedProviderException { if (!isUsernameValid(newUsername)) { @@ -419,7 +413,7 @@ public class UserService implements UserServiceInterface { if (principal instanceof UserDetails detailsUser) { return detailsUser.getUsername(); - } else if (principal instanceof stirling.software.SPDF.model.User domainUser) { + } else if (principal instanceof User domainUser) { return domainUser.getUsername(); } else if (principal instanceof OAuth2User oAuth2User) { return oAuth2User.getAttribute(oAuth2.getUseAsUsername()); diff --git a/src/main/java/stirling/software/SPDF/config/security/session/CustomHttpSessionListener.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/CustomHttpSessionListener.java similarity index 92% rename from src/main/java/stirling/software/SPDF/config/security/session/CustomHttpSessionListener.java rename to proprietary/src/main/java/stirling/software/proprietary/security/session/CustomHttpSessionListener.java index 09868eff9..7ed0f6506 100644 --- a/src/main/java/stirling/software/SPDF/config/security/session/CustomHttpSessionListener.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/CustomHttpSessionListener.java @@ -1,11 +1,9 @@ -package stirling.software.SPDF.config.security.session; - -import org.springframework.stereotype.Component; +package stirling.software.proprietary.security.session; import jakarta.servlet.http.HttpSessionEvent; import jakarta.servlet.http.HttpSessionListener; - import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; @Component @Slf4j diff --git a/src/main/java/stirling/software/SPDF/config/security/session/SessionPersistentRegistry.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionPersistentRegistry.java similarity index 94% rename from src/main/java/stirling/software/SPDF/config/security/session/SessionPersistentRegistry.java rename to proprietary/src/main/java/stirling/software/proprietary/security/session/SessionPersistentRegistry.java index 9e249f3a4..5d482e94d 100644 --- a/src/main/java/stirling/software/SPDF/config/security/session/SessionPersistentRegistry.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionPersistentRegistry.java @@ -1,21 +1,23 @@ -package stirling.software.SPDF.config.security.session; +package stirling.software.proprietary.security.session; +import jakarta.transaction.Transactional; import java.time.Duration; -import java.util.*; - +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.session.SessionInformation; import org.springframework.security.core.session.SessionRegistry; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Component; - -import jakarta.transaction.Transactional; - -import lombok.RequiredArgsConstructor; - -import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal; -import stirling.software.SPDF.model.SessionEntity; +import stirling.software.proprietary.security.database.repository.SessionRepository; +import stirling.software.proprietary.security.model.SessionEntity; +import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; @Component @RequiredArgsConstructor diff --git a/src/main/java/stirling/software/SPDF/config/security/session/SessionRegistryConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java similarity index 57% rename from src/main/java/stirling/software/SPDF/config/security/session/SessionRegistryConfig.java rename to proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java index 18a84279c..75afbea9b 100644 --- a/src/main/java/stirling/software/SPDF/config/security/session/SessionRegistryConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java @@ -1,12 +1,11 @@ -package stirling.software.SPDF.config.security.session; +package stirling.software.proprietary.security.session; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.session.SessionRegistryImpl; +import stirling.software.proprietary.security.database.repository.SessionRepository; @Configuration -@ConditionalOnProperty(name = "premium.enabled", havingValue = "true") public class SessionRegistryConfig { @Bean @@ -15,8 +14,7 @@ public class SessionRegistryConfig { } @Bean - public SessionPersistentRegistry sessionPersistentRegistry( - SessionRepository sessionRepository) { + public SessionPersistentRegistry sessionPersistentRegistry(SessionRepository sessionRepository) { return new SessionPersistentRegistry(sessionRepository); } } diff --git a/src/main/java/stirling/software/SPDF/config/security/session/SessionScheduled.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java similarity index 95% rename from src/main/java/stirling/software/SPDF/config/security/session/SessionScheduled.java rename to proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java index 46c17a77e..83403f9f7 100644 --- a/src/main/java/stirling/software/SPDF/config/security/session/SessionScheduled.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java @@ -1,16 +1,14 @@ -package stirling.software.SPDF.config.security.session; +package stirling.software.proprietary.security.session; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.List; - +import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.core.session.SessionInformation; import org.springframework.stereotype.Component; -import lombok.RequiredArgsConstructor; - @Component @RequiredArgsConstructor public class SessionScheduled { diff --git a/src/test/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandlerTest.java b/proprietary/src/test/java/stirling/software/proprietary/security/CustomLogoutSuccessHandlerTest.java similarity index 98% rename from src/test/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandlerTest.java rename to proprietary/src/test/java/stirling/software/proprietary/security/CustomLogoutSuccessHandlerTest.java index 79638cafe..a5abd6be5 100644 --- a/src/test/java/stirling/software/SPDF/config/security/CustomLogoutSuccessHandlerTest.java +++ b/proprietary/src/test/java/stirling/software/proprietary/security/CustomLogoutSuccessHandlerTest.java @@ -1,22 +1,17 @@ -package stirling.software.SPDF.config.security; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +package stirling.software.proprietary.security; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; - import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - import stirling.software.common.model.ApplicationProperties; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class CustomLogoutSuccessHandlerTest { diff --git a/src/test/java/stirling/software/SPDF/config/security/database/DatabaseConfigTest.java b/proprietary/src/test/java/stirling/software/proprietary/security/configuration/DatabaseConfigTest.java similarity index 94% rename from src/test/java/stirling/software/SPDF/config/security/database/DatabaseConfigTest.java rename to proprietary/src/test/java/stirling/software/proprietary/security/configuration/DatabaseConfigTest.java index 45bbd28c0..b1dc3a29e 100644 --- a/src/test/java/stirling/software/SPDF/config/security/database/DatabaseConfigTest.java +++ b/proprietary/src/test/java/stirling/software/proprietary/security/configuration/DatabaseConfigTest.java @@ -1,11 +1,6 @@ -package stirling.software.SPDF.config.security.database; - -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.when; +package stirling.software.proprietary.security.configuration; import javax.sql.DataSource; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -13,9 +8,10 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.exception.UnsupportedProviderException; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class DatabaseConfigTest { diff --git a/src/test/java/stirling/software/SPDF/controller/api/EmailControllerTest.java b/proprietary/src/test/java/stirling/software/proprietary/security/controller/api/EmailControllerTest.java similarity index 94% rename from src/test/java/stirling/software/SPDF/controller/api/EmailControllerTest.java rename to proprietary/src/test/java/stirling/software/proprietary/security/controller/api/EmailControllerTest.java index dfd68e069..74bf88404 100644 --- a/src/test/java/stirling/software/SPDF/controller/api/EmailControllerTest.java +++ b/proprietary/src/test/java/stirling/software/proprietary/security/controller/api/EmailControllerTest.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.controller.api; +package stirling.software.proprietary.security.controller.api; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; @@ -23,8 +23,8 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import jakarta.mail.MessagingException; -import stirling.software.SPDF.config.security.mail.EmailService; -import stirling.software.SPDF.model.api.Email; +import stirling.software.proprietary.security.model.api.Email; +import stirling.software.proprietary.security.service.EmailService; @ExtendWith(MockitoExtension.class) class EmailControllerTest { diff --git a/src/test/java/stirling/software/SPDF/config/security/mail/EmailServiceTest.java b/proprietary/src/test/java/stirling/software/proprietary/security/service/EmailServiceTest.java similarity index 94% rename from src/test/java/stirling/software/SPDF/config/security/mail/EmailServiceTest.java rename to proprietary/src/test/java/stirling/software/proprietary/security/service/EmailServiceTest.java index 64f02799b..e953783a8 100644 --- a/src/test/java/stirling/software/SPDF/config/security/mail/EmailServiceTest.java +++ b/proprietary/src/test/java/stirling/software/proprietary/security/service/EmailServiceTest.java @@ -1,9 +1,9 @@ -package stirling.software.SPDF.config.security.mail; +package stirling.software.proprietary.security.service; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.Mockito.*; - +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -15,8 +15,11 @@ import org.springframework.web.multipart.MultipartFile; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; -import stirling.software.SPDF.model.api.Email; import stirling.software.common.model.ApplicationProperties; +import stirling.software.proprietary.security.model.api.Email; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class EmailServiceTest { diff --git a/src/test/java/stirling/software/SPDF/config/security/mail/MailConfigTest.java b/proprietary/src/test/java/stirling/software/proprietary/security/service/MailConfigTest.java similarity index 94% rename from src/test/java/stirling/software/SPDF/config/security/mail/MailConfigTest.java rename to proprietary/src/test/java/stirling/software/proprietary/security/service/MailConfigTest.java index bff1cb5eb..3db3493f4 100644 --- a/src/test/java/stirling/software/SPDF/config/security/mail/MailConfigTest.java +++ b/proprietary/src/test/java/stirling/software/proprietary/security/service/MailConfigTest.java @@ -1,4 +1,4 @@ -package stirling.software.SPDF.config.security.mail; +package stirling.software.proprietary.security.service; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -14,6 +14,7 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.JavaMailSenderImpl; import stirling.software.common.model.ApplicationProperties; +import stirling.software.proprietary.security.configuration.MailConfig; class MailConfigTest { diff --git a/settings.gradle b/settings.gradle index 0dbeab6e7..e4e55768e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,4 +4,4 @@ plugins { } rootProject.name = 'Stirling-PDF' -include 'common' +include 'common', 'proprietary' diff --git a/src/main/java/stirling/software/SPDF/config/AppUpdateService.java b/src/main/java/stirling/software/SPDF/config/AppUpdateService.java index f89c9aed3..c4c528f77 100644 --- a/src/main/java/stirling/software/SPDF/config/AppUpdateService.java +++ b/src/main/java/stirling/software/SPDF/config/AppUpdateService.java @@ -5,7 +5,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; -import stirling.software.SPDF.config.interfaces.ShowAdminInterface; +import stirling.software.common.configuration.interfaces.ShowAdminInterface; import stirling.software.common.model.ApplicationProperties; @Configuration diff --git a/src/main/java/stirling/software/SPDF/config/interfaces/ShowAdminInterface.java b/src/main/java/stirling/software/SPDF/config/interfaces/ShowAdminInterface.java deleted file mode 100644 index 1bbebf5a9..000000000 --- a/src/main/java/stirling/software/SPDF/config/interfaces/ShowAdminInterface.java +++ /dev/null @@ -1,7 +0,0 @@ -package stirling.software.SPDF.config.interfaces; - -public interface ShowAdminInterface { - default boolean getShowUpdateOnlyAdmins() { - return true; - } -} diff --git a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java deleted file mode 100644 index f0829e23e..000000000 --- a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java +++ /dev/null @@ -1,319 +0,0 @@ -package stirling.software.SPDF.config.security; - -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; -import org.springframework.context.annotation.Lazy; -import org.springframework.security.authentication.ProviderManager; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; -import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider; -import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; -import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; -import org.springframework.security.web.csrf.CookieCsrfTokenRepository; -import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler; -import org.springframework.security.web.savedrequest.NullRequestCache; -import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; - -import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationFailureHandler; -import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationSuccessHandler; -import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService; -import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticationFailureHandler; -import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticationSuccessHandler; -import stirling.software.SPDF.config.security.saml2.CustomSaml2ResponseAuthenticationConverter; -import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; -import stirling.software.SPDF.model.User; -import stirling.software.SPDF.repository.JPATokenRepositoryImpl; -import stirling.software.SPDF.repository.PersistentLoginRepository; -import stirling.software.common.model.ApplicationProperties; - -@Configuration -@EnableWebSecurity -@EnableMethodSecurity -@Slf4j -@DependsOn("runningProOrHigher") -public class SecurityConfiguration { - - private final CustomUserDetailsService userDetailsService; - private final UserService userService; - private final boolean loginEnabledValue; - private final boolean runningProOrHigher; - - private final ApplicationProperties applicationProperties; - private final UserAuthenticationFilter userAuthenticationFilter; - private final LoginAttemptService loginAttemptService; - private final FirstLoginFilter firstLoginFilter; - private final SessionPersistentRegistry sessionRegistry; - private final PersistentLoginRepository persistentLoginRepository; - private final GrantedAuthoritiesMapper oAuth2userAuthoritiesMapper; - private final RelyingPartyRegistrationRepository saml2RelyingPartyRegistrations; - private final OpenSaml4AuthenticationRequestResolver saml2AuthenticationRequestResolver; - - public SecurityConfiguration( - PersistentLoginRepository persistentLoginRepository, - CustomUserDetailsService userDetailsService, - @Lazy UserService userService, - @Qualifier("loginEnabled") boolean loginEnabledValue, - @Qualifier("runningProOrHigher") boolean runningProOrHigher, - ApplicationProperties applicationProperties, - UserAuthenticationFilter userAuthenticationFilter, - LoginAttemptService loginAttemptService, - FirstLoginFilter firstLoginFilter, - SessionPersistentRegistry sessionRegistry, - @Autowired(required = false) GrantedAuthoritiesMapper oAuth2userAuthoritiesMapper, - @Autowired(required = false) - RelyingPartyRegistrationRepository saml2RelyingPartyRegistrations, - @Autowired(required = false) - OpenSaml4AuthenticationRequestResolver saml2AuthenticationRequestResolver) { - this.userDetailsService = userDetailsService; - this.userService = userService; - this.loginEnabledValue = loginEnabledValue; - this.runningProOrHigher = runningProOrHigher; - this.applicationProperties = applicationProperties; - this.userAuthenticationFilter = userAuthenticationFilter; - this.loginAttemptService = loginAttemptService; - this.firstLoginFilter = firstLoginFilter; - this.sessionRegistry = sessionRegistry; - this.persistentLoginRepository = persistentLoginRepository; - this.oAuth2userAuthoritiesMapper = oAuth2userAuthoritiesMapper; - this.saml2RelyingPartyRegistrations = saml2RelyingPartyRegistrations; - this.saml2AuthenticationRequestResolver = saml2AuthenticationRequestResolver; - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - if (applicationProperties.getSecurity().getCsrfDisabled() || !loginEnabledValue) { - http.csrf(csrf -> csrf.disable()); - } - - if (loginEnabledValue) { - http.addFilterBefore( - userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); - if (!applicationProperties.getSecurity().getCsrfDisabled()) { - CookieCsrfTokenRepository cookieRepo = - CookieCsrfTokenRepository.withHttpOnlyFalse(); - CsrfTokenRequestAttributeHandler requestHandler = - new CsrfTokenRequestAttributeHandler(); - requestHandler.setCsrfRequestAttributeName(null); - http.csrf( - csrf -> - csrf.ignoringRequestMatchers( - request -> { - String apiKey = request.getHeader("X-API-KEY"); - // If there's no API key, don't ignore CSRF - // (return false) - if (apiKey == null || apiKey.trim().isEmpty()) { - return false; - } - // Validate API key using existing UserService - try { - Optional user = - userService.getUserByApiKey(apiKey); - // If API key is valid, ignore CSRF (return - // true) - // If API key is invalid, don't ignore CSRF - // (return false) - return user.isPresent(); - } catch (Exception e) { - // If there's any error validating the API - // key, don't ignore CSRF - return false; - } - }) - .csrfTokenRepository(cookieRepo) - .csrfTokenRequestHandler(requestHandler)); - } - http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class); - http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class); - http.sessionManagement( - sessionManagement -> - sessionManagement - .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) - .maximumSessions(10) - .maxSessionsPreventsLogin(false) - .sessionRegistry(sessionRegistry) - .expiredUrl("/login?logout=true")); - http.authenticationProvider(daoAuthenticationProvider()); - http.requestCache(requestCache -> requestCache.requestCache(new NullRequestCache())); - http.logout( - logout -> - logout.logoutRequestMatcher( - PathPatternRequestMatcher.withDefaults() - .matcher("/logout")) - .logoutSuccessHandler( - new CustomLogoutSuccessHandler(applicationProperties)) - .clearAuthentication(true) - .invalidateHttpSession(true) - .deleteCookies("JSESSIONID", "remember-me")); - http.rememberMe( - rememberMeConfigurer -> // Use the configurator directly - rememberMeConfigurer - .tokenRepository(persistentTokenRepository()) - .tokenValiditySeconds( // 14 days - 14 * 24 * 60 * 60) - .userDetailsService( // Your existing UserDetailsService - userDetailsService) - .useSecureCookie( // Enable secure cookie - true) - .rememberMeParameter( // Form parameter name - "remember-me") - .rememberMeCookieName( // Cookie name - "remember-me") - .alwaysRemember(false)); - http.authorizeHttpRequests( - authz -> - authz.requestMatchers( - req -> { - String uri = req.getRequestURI(); - String contextPath = req.getContextPath(); - // Remove the context path from the URI - String trimmedUri = - uri.startsWith(contextPath) - ? uri.substring( - contextPath.length()) - : uri; - return trimmedUri.startsWith("/login") - || trimmedUri.startsWith("/oauth") - || trimmedUri.startsWith("/saml2") - || trimmedUri.endsWith(".svg") - || trimmedUri.startsWith("/register") - || trimmedUri.startsWith("/error") - || trimmedUri.startsWith("/images/") - || trimmedUri.startsWith("/public/") - || trimmedUri.startsWith("/css/") - || trimmedUri.startsWith("/fonts/") - || trimmedUri.startsWith("/js/") - || trimmedUri.startsWith( - "/api/v1/info/status"); - }) - .permitAll() - .anyRequest() - .authenticated()); - // Handle User/Password Logins - if (applicationProperties.getSecurity().isUserPass()) { - http.formLogin( - formLogin -> - formLogin - .loginPage("/login") - .successHandler( - new CustomAuthenticationSuccessHandler( - loginAttemptService, userService)) - .failureHandler( - new CustomAuthenticationFailureHandler( - loginAttemptService, userService)) - .defaultSuccessUrl("/") - .permitAll()); - } - // Handle OAUTH2 Logins - if (applicationProperties.getSecurity().isOauth2Active()) { - http.oauth2Login( - oauth2 -> - oauth2.loginPage("/oauth2") - . - /* - This Custom handler is used to check if the OAUTH2 user trying to log in, already exists in the database. - If user exists, login proceeds as usual. If user does not exist, then it is auto-created but only if 'OAUTH2AutoCreateUser' - is set as true, else login fails with an error message advising the same. - */ - successHandler( - new CustomOAuth2AuthenticationSuccessHandler( - loginAttemptService, - applicationProperties, - userService)) - .failureHandler( - new CustomOAuth2AuthenticationFailureHandler()) - . // Add existing Authorities from the database - userInfoEndpoint( - userInfoEndpoint -> - userInfoEndpoint - .oidcUserService( - new CustomOAuth2UserService( - applicationProperties, - userService, - loginAttemptService)) - .userAuthoritiesMapper( - oAuth2userAuthoritiesMapper)) - .permitAll()); - } - // Handle SAML - if (applicationProperties.getSecurity().isSaml2Active() && runningProOrHigher) { - // Configure the authentication provider - OpenSaml4AuthenticationProvider authenticationProvider = - new OpenSaml4AuthenticationProvider(); - authenticationProvider.setResponseAuthenticationConverter( - new CustomSaml2ResponseAuthenticationConverter(userService)); - http.authenticationProvider(authenticationProvider) - .saml2Login( - saml2 -> { - try { - saml2.loginPage("/saml2") - .relyingPartyRegistrationRepository( - saml2RelyingPartyRegistrations) - .authenticationManager( - new ProviderManager(authenticationProvider)) - .successHandler( - new CustomSaml2AuthenticationSuccessHandler( - loginAttemptService, - applicationProperties, - userService)) - .failureHandler( - new CustomSaml2AuthenticationFailureHandler()) - .authenticationRequestResolver( - saml2AuthenticationRequestResolver); - } catch (Exception e) { - log.error("Error configuring SAML 2 login", e); - throw new RuntimeException(e); - } - }); - } - } else { - log.debug("SAML 2 login is not enabled. Using default."); - http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll()); - } - return http.build(); - } - - public DaoAuthenticationProvider daoAuthenticationProvider() { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setUserDetailsService(userDetailsService); - provider.setPasswordEncoder(passwordEncoder()); - return provider; - } - - @Bean - public IPRateLimitingFilter rateLimitingFilter() { - // Example limit TODO add config level - int maxRequestsPerIp = 1000000; - return new IPRateLimitingFilter(maxRequestsPerIp, maxRequestsPerIp); - } - - @Bean - public PersistentTokenRepository persistentTokenRepository() { - return new JPATokenRepositoryImpl(persistentLoginRepository); - } - - @Bean - public boolean activeSecurity() { - return true; - } -} diff --git a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertOfficeController.java b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertOfficeController.java index 6716106d5..d81e3843f 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertOfficeController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertOfficeController.java @@ -23,8 +23,8 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -import stirling.software.SPDF.model.api.GeneralFile; import stirling.software.common.configuration.RuntimePathConfig; +import stirling.software.common.model.api.GeneralFile; import stirling.software.common.service.CustomPDFDocumentFactory; import stirling.software.common.util.ProcessExecutor; import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult; diff --git a/src/main/java/stirling/software/SPDF/controller/api/pipeline/ApiDocService.java b/src/main/java/stirling/software/SPDF/controller/api/pipeline/ApiDocService.java index 438ea980a..2e6e71b1f 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/pipeline/ApiDocService.java +++ b/src/main/java/stirling/software/SPDF/controller/api/pipeline/ApiDocService.java @@ -24,7 +24,7 @@ import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.SPDFApplication; import stirling.software.SPDF.model.ApiEndpoint; -import stirling.software.SPDF.model.Role; +import stirling.software.common.model.enumeration.Role; import stirling.software.common.service.UserServiceInterface; @Service diff --git a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java index 21be0861b..4e052b55e 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java +++ b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java @@ -35,7 +35,7 @@ import stirling.software.SPDF.SPDFApplication; import stirling.software.SPDF.model.PipelineConfig; import stirling.software.SPDF.model.PipelineOperation; import stirling.software.SPDF.model.PipelineResult; -import stirling.software.SPDF.model.Role; +import stirling.software.common.model.enumeration.Role; import stirling.software.common.service.UserServiceInterface; @Service diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java b/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java index bc0a4ff9d..47e45c595 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java @@ -4,9 +4,18 @@ import java.io.IOException; import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.pdmodel.*; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDDocumentCatalog; +import org.apache.pdfbox.pdmodel.PDDocumentInformation; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageTree; +import org.apache.pdfbox.pdmodel.PDResources; import org.apache.pdfbox.pdmodel.common.PDMetadata; -import org.apache.pdfbox.pdmodel.interactive.action.*; +import org.apache.pdfbox.pdmodel.interactive.action.PDAction; +import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript; +import org.apache.pdfbox.pdmodel.interactive.action.PDActionLaunch; +import org.apache.pdfbox.pdmodel.interactive.action.PDActionURI; +import org.apache.pdfbox.pdmodel.interactive.action.PDFormFieldAdditionalActions; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget; diff --git a/src/main/java/stirling/software/SPDF/model/AuthenticationType.java b/src/main/java/stirling/software/SPDF/model/AuthenticationType.java deleted file mode 100644 index 80419cdd2..000000000 --- a/src/main/java/stirling/software/SPDF/model/AuthenticationType.java +++ /dev/null @@ -1,6 +0,0 @@ -package stirling.software.SPDF.model; - -public enum AuthenticationType { - WEB, - SSO -} diff --git a/src/main/java/stirling/software/SPDF/model/PdfMetadata.java b/src/main/java/stirling/software/SPDF/model/PdfMetadata.java deleted file mode 100644 index 35054bc8c..000000000 --- a/src/main/java/stirling/software/SPDF/model/PdfMetadata.java +++ /dev/null @@ -1,19 +0,0 @@ -package stirling.software.SPDF.model; - -import java.util.Calendar; - -import lombok.Builder; -import lombok.Data; - -@Data -@Builder -public class PdfMetadata { - private String author; - private String producer; - private String title; - private String creator; - private String subject; - private String keywords; - private Calendar creationDate; - private Calendar modificationDate; -} diff --git a/src/main/java/stirling/software/SPDF/model/Role.java b/src/main/java/stirling/software/SPDF/model/Role.java deleted file mode 100644 index 7d45e3da3..000000000 --- a/src/main/java/stirling/software/SPDF/model/Role.java +++ /dev/null @@ -1,66 +0,0 @@ -package stirling.software.SPDF.model; - -import java.util.LinkedHashMap; -import java.util.Map; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public enum Role { - - // Unlimited access - ADMIN("ROLE_ADMIN", Integer.MAX_VALUE, Integer.MAX_VALUE, "adminUserSettings.admin"), - - // Unlimited access - USER("ROLE_USER", Integer.MAX_VALUE, Integer.MAX_VALUE, "adminUserSettings.user"), - - // 40 API calls Per Day, 40 web calls - LIMITED_API_USER("ROLE_LIMITED_API_USER", 40, 40, "adminUserSettings.apiUser"), - - // 20 API calls Per Day, 20 web calls - EXTRA_LIMITED_API_USER("ROLE_EXTRA_LIMITED_API_USER", 20, 20, "adminUserSettings.extraApiUser"), - - // 0 API calls per day and 20 web calls - WEB_ONLY_USER("ROLE_WEB_ONLY_USER", 0, 20, "adminUserSettings.webOnlyUser"), - - INTERNAL_API_USER( - "STIRLING-PDF-BACKEND-API-USER", - Integer.MAX_VALUE, - Integer.MAX_VALUE, - "adminUserSettings.internalApiUser"), - - DEMO_USER("ROLE_DEMO_USER", 100, 100, "adminUserSettings.demoUser"); - - private final String roleId; - private final int apiCallsPerDay; - private final int webCallsPerDay; - private final String roleName; - - public static String getRoleNameByRoleId(String roleId) { - // Using the fromString method to get the Role enum based on the roleId - Role role = fromString(roleId); - // Return the roleName of the found Role enum - return role.getRoleName(); - } - - // Method to retrieve all role IDs and role names - public static Map getAllRoleDetails() { - // Using LinkedHashMap to preserve order - Map roleDetails = new LinkedHashMap<>(); - for (Role role : Role.values()) { - roleDetails.put(role.getRoleId(), role.getRoleName()); - } - return roleDetails; - } - - public static Role fromString(String roleId) { - for (Role role : Role.values()) { - if (role.getRoleId().equalsIgnoreCase(roleId)) { - return role; - } - } - throw new IllegalArgumentException("No Role defined for id: " + roleId); - } -} From 6d8173b0218260b02da3a869efc667d8e7e2c753 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Tue, 27 May 2025 17:28:11 +0100 Subject: [PATCH 04/15] updating license --- .../gradle/wrapper/gradle-wrapper.properties | 6 ---- proprietary/LICENSE-proprietary | 33 ++++--------------- proprietary/build.gradle | 13 ++++---- .../gradle/wrapper/gradle-wrapper.properties | 6 ---- 4 files changed, 13 insertions(+), 45 deletions(-) delete mode 100644 common/gradle/wrapper/gradle-wrapper.properties delete mode 100644 proprietary/gradle/wrapper/gradle-wrapper.properties diff --git a/common/gradle/wrapper/gradle-wrapper.properties b/common/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index f7664bccf..000000000 --- a/common/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/proprietary/LICENSE-proprietary b/proprietary/LICENSE-proprietary index f723a2809..9f8fef545 100644 --- a/proprietary/LICENSE-proprietary +++ b/proprietary/LICENSE-proprietary @@ -4,33 +4,14 @@ Copyright (c) 2025-present Stirling Tools With regard to the Stirling PDF Software: -This software and associated documentation files (the "Software") may only be -used in production, if you (and any entity that you represent) have agreed to, -and are in compliance with, the Stirling PDF Terms of Service, available -at https://www.stirlingpdf.com/terms-and-conditions (the “EE Terms”), or other -agreement governing the use of the Software, as agreed by you and Stirling PDF, -and otherwise have a valid Stirling PDF Enterprise Edition subscription for the -correct number of user seats. Subject to the foregoing sentence, you are free to -modify this Software and publish patches to the Software. You agree that Stirling PDF -and/or its licensors (as applicable) retain all right, title and interest in and -to all such modifications and/or patches, and all such modifications and/or -patches may only be used, copied, modified, displayed, distributed, or otherwise -exploited with a valid Stirling PDF Enterprise Edition subscription for the correct -number of user seats. Notwithstanding the foregoing, you may copy and modify -the Software for development and testing purposes, without requiring a -subscription. You agree that Stirling PDF and/or its licensors (as applicable) retain -all right, title and interest in and to all such modifications. You are not -granted any other rights beyond what is expressly stated herein. Subject to the -foregoing, it is forbidden to copy, merge, publish, distribute, sublicense, -and/or sell the Software. +Trial and Minimal Use -This EE License applies only to the part of this Software that is not -distributed as part of MIT License. Any part of this Software -distributed as part of MIT License or is served client-side as an image, font, -cascading stylesheet (CSS), file which produces or is compiled, arranged, -augmented, or combined into client-side JavaScript, in whole or in part, is -copyrighted under the MIT Expat license. The full text of this EE License shall -be included in all copies or substantial portions of the Software. +You may use the Software without a subscription for purposes of trial, evaluation, or minimal use, including use by individuals, +organizations, or businesses, provided that: + * The usage is limited in scope (e.g. up to five (5) sessions or uses, or as otherwise defined within the Software); + * You do not modify, distribute, sublicense, or reverse-engineer the Software; + * Any continued use beyond the permitted trial or minimal use scope requires a valid Stirling PDF Enterprise Edition + subscription for the appropriate number of users. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/proprietary/build.gradle b/proprietary/build.gradle index 8f548a785..5c91d21ba 100644 --- a/proprietary/build.gradle +++ b/proprietary/build.gradle @@ -19,25 +19,24 @@ configurations.all { dependencyManagement { imports { - mavenBom 'org.springframework.boot:spring-boot-dependencies:3.4.5' + mavenBom 'org.springframework.boot:spring-boot-dependencies:3.5.0' } } dependencies { implementation project(':common') - implementation 'org.springframework:spring-jdbc:6.2.7' - implementation 'org.springframework:spring-webmvc:6.2.7' + implementation 'org.springframework:spring-jdbc' + implementation 'org.springframework:spring-webmvc' + implementation 'org.springframework.session:spring-session-core' + implementation "org.springframework.security:spring-security-core:$springSecuritySamlVersion" + implementation "org.springframework.security:spring-security-saml2-service-provider:$springSecuritySamlVersion" implementation 'org.springframework.boot:spring-boot-starter-jetty' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-mail' - implementation "org.springframework.security:spring-security-core:$springSecuritySamlVersion" - implementation "org.springframework.security:spring-security-saml2-service-provider:$springSecuritySamlVersion" - implementation 'org.springframework.session:spring-session-core:3.4.3' implementation 'io.swagger.core.v3:swagger-core-jakarta:2.2.30' - implementation 'com.bucket4j:bucket4j_jdk17-core:8.14.0' // https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17 diff --git a/proprietary/gradle/wrapper/gradle-wrapper.properties b/proprietary/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index f7664bccf..000000000 --- a/proprietary/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists From 2b9a3924d3aa58db0abcdc8da36527fcf4978d22 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Tue, 27 May 2025 19:55:15 +0100 Subject: [PATCH 05/15] added proprietary module to base packages for scanning clean up --- Dockerfile.fat | 2 + LICENSE | 2 +- build.gradle | 30 +++------ common/build.gradle | 26 ++++---- proprietary/LICENSE-proprietary | 66 +++++++++++++------ .../configuration/DatabaseConfig.java | 40 +++++------ .../configuration/SecurityConfiguration.java | 6 +- .../software/SPDF/SPDFApplication.java | 6 +- src/main/resources/settings.yml.template | 1 - 9 files changed, 101 insertions(+), 78 deletions(-) diff --git a/Dockerfile.fat b/Dockerfile.fat index 9029fc8eb..f442e60c8 100644 --- a/Dockerfile.fat +++ b/Dockerfile.fat @@ -5,6 +5,8 @@ COPY build.gradle . COPY settings.gradle . COPY gradlew . COPY gradle gradle/ +COPY common/build.gradle common/. +COPY proprietary/build.gradle proprietary/. RUN ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube || return 0 # Set the working directory diff --git a/LICENSE b/LICENSE index 0cd290e88..877663171 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Stirling Tools +Copyright (c) 2025 Stirling PDF Inc. Portions of this software are licensed as follows: diff --git a/build.gradle b/build.gradle index cf5a3b728..c6a2e74be 100644 --- a/build.gradle +++ b/build.gradle @@ -270,8 +270,6 @@ tasks.register('jpackageMacX64') { } } -//jpackage.finalizedBy(jpackageMacX64) - tasks.register('downloadTempJre') { group = 'distribution' description = 'Downloads and extracts a temporary JRE' @@ -421,20 +419,16 @@ dependencies { implementation("io.github.pixee:java-security-toolkit:1.2.1") // Exclude Tomcat and include Jetty - implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion") +// implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion") implementation "org.springframework.boot:spring-boot-starter-jetty:$springBootVersion" - - implementation "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion" +// implementation "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion" implementation 'com.posthog.java:posthog:1.2.0' implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1' - + implementation 'org.snakeyaml:snakeyaml-engine:2.9' if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") { implementation project(':proprietary') } - implementation 'org.snakeyaml:snakeyaml-engine:2.9' - - testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion" // Batik implementation "org.apache.xmlgraphics:batik-all:1.19" @@ -442,10 +436,12 @@ dependencies { // TwelveMonkeys runtimeOnly "com.twelvemonkeys.imageio:imageio-batik:$imageioVersion" runtimeOnly "com.twelvemonkeys.imageio:imageio-bmp:$imageioVersion" + runtimeOnly "com.twelvemonkeys.imageio:imageio-jpeg:$imageioVersion" + runtimeOnly "com.twelvemonkeys.imageio:imageio-tiff:$imageioVersion" + runtimeOnly "com.twelvemonkeys.imageio:imageio-webp:$imageioVersion" // runtimeOnly "com.twelvemonkeys.imageio:imageio-hdr:$imageioVersion" // runtimeOnly "com.twelvemonkeys.imageio:imageio-icns:$imageioVersion" // runtimeOnly "com.twelvemonkeys.imageio:imageio-iff:$imageioVersion" - runtimeOnly "com.twelvemonkeys.imageio:imageio-jpeg:$imageioVersion" // runtimeOnly "com.twelvemonkeys.imageio:imageio-pcx:$imageioVersion@ // runtimeOnly "com.twelvemonkeys.imageio:imageio-pict:$imageioVersion" // runtimeOnly "com.twelvemonkeys.imageio:imageio-pnm:$imageioVersion" @@ -453,24 +449,18 @@ dependencies { // runtimeOnly "com.twelvemonkeys.imageio:imageio-sgi:$imageioVersion" // runtimeOnly "com.twelvemonkeys.imageio:imageio-tga:$imageioVersion" // runtimeOnly "com.twelvemonkeys.imageio:imageio-thumbsdb:$imageioVersion" - runtimeOnly "com.twelvemonkeys.imageio:imageio-tiff:$imageioVersion" - runtimeOnly "com.twelvemonkeys.imageio:imageio-webp:$imageioVersion" // runtimeOnly "com.twelvemonkeys.imageio:imageio-xwd:$imageioVersion" // Image metadata extractor implementation "com.drewnoakes:metadata-extractor:2.19.0" - implementation "commons-io:commons-io:2.19.0" - implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.8" - //general PDF +// implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.8" + // General PDF // https://mvnrepository.com/artifact/com.opencsv/opencsv implementation ("com.opencsv:opencsv:5.11") - - implementation ("org.apache.pdfbox:pdfbox:$pdfboxVersion") +// implementation ("org.apache.pdfbox:pdfbox:$pdfboxVersion") implementation "org.apache.pdfbox:preflight:$pdfboxVersion" - - implementation ("org.apache.pdfbox:xmpbox:$pdfboxVersion") // https://mvnrepository.com/artifact/technology.tabula/tabula @@ -494,7 +484,6 @@ dependencies { // https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17 implementation "com.bucket4j:bucket4j_jdk17-core:8.14.0" implementation "com.fathzer:javaluator:3.0.6" - implementation 'com.vladsch.flexmark:flexmark-html2md-converter:0.64.8' developmentOnly("org.springframework.boot:spring-boot-devtools:$springBootVersion") @@ -504,6 +493,7 @@ dependencies { // Mockito (core) testImplementation 'org.mockito:mockito-core:5.18.0' testRuntimeOnly 'org.mockito:mockito-inline:5.2.0' + testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion" } tasks.withType(JavaCompile).configureEach { diff --git a/common/build.gradle b/common/build.gradle index 9b4c93e0d..b4c51c2f8 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -30,19 +30,19 @@ dependencyManagement { } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1' - implementation 'com.fathzer:javaluator:3.0.6' - implementation 'com.posthog.java:posthog:1.2.0' - implementation 'io.github.pixee:java-security-toolkit:1.2.1' - implementation 'org.apache.commons:commons-lang3:3.17.0' - implementation 'com.drewnoakes:metadata-extractor:2.19.0' // Image metadata extractor - implementation 'com.vladsch.flexmark:flexmark-html2md-converter:0.64.8' - implementation "org.apache.pdfbox:pdfbox:$pdfboxVersion" - implementation 'jakarta.servlet:jakarta.servlet-api:6.1.0' - implementation 'org.snakeyaml:snakeyaml-engine:2.9' - implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.8" + api 'org.springframework.boot:spring-boot-starter-web' + api 'org.springframework.boot:spring-boot-starter-thymeleaf' + api 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1' + api 'com.fathzer:javaluator:3.0.6' + api 'com.posthog.java:posthog:1.2.0' + api 'io.github.pixee:java-security-toolkit:1.2.1' + api 'org.apache.commons:commons-lang3:3.17.0' + api 'com.drewnoakes:metadata-extractor:2.19.0' // Image metadata extractor + api 'com.vladsch.flexmark:flexmark-html2md-converter:0.64.8' + api "org.apache.pdfbox:pdfbox:$pdfboxVersion" + api 'jakarta.servlet:jakarta.servlet-api:6.1.0' + api 'org.snakeyaml:snakeyaml-engine:2.9' + api "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.8" compileOnly "org.projectlombok:lombok:$lombokVersion" annotationProcessor "org.projectlombok:lombok:$lombokVersion" diff --git a/proprietary/LICENSE-proprietary b/proprietary/LICENSE-proprietary index 9f8fef545..df9b7b974 100644 --- a/proprietary/LICENSE-proprietary +++ b/proprietary/LICENSE-proprietary @@ -1,26 +1,54 @@ -Stirling PDF Enterprise Edition (EE) license (the “EE License”) +Stirling PDF User License -Copyright (c) 2025-present Stirling Tools +Copyright (c) 2025 Stirling PDF Inc. -With regard to the Stirling PDF Software: +License Scope & Usage Rights + +Production use of the Stirling PDF Software is only permitted with a valid Stirling PDF User License. + +For purposes of this license, “the Software” refers to the Stirling PDF application and any associated documentation files +provided by Stirling PDF Inc. You or your organization may not use the Software in production, at scale, or for business-critical +processes unless you have agreed to, and remain in compliance with, the Stirling PDF Subscription Terms of Service +(https://www.stirlingpdf.com/terms) or another valid agreement with Stirling PDF, and hold an active User License subscription +covering the appropriate number of licensed users. Trial and Minimal Use -You may use the Software without a subscription for purposes of trial, evaluation, or minimal use, including use by individuals, -organizations, or businesses, provided that: - * The usage is limited in scope (e.g. up to five (5) sessions or uses, or as otherwise defined within the Software); - * You do not modify, distribute, sublicense, or reverse-engineer the Software; - * Any continued use beyond the permitted trial or minimal use scope requires a valid Stirling PDF Enterprise Edition - subscription for the appropriate number of users. +You may use the Software without a paid subscription for the sole purposes of internal trial, evaluation, or minimal use, +provided that: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +* Use is limited to no more than five (5) named users or sessions; +* Use is strictly non-production, for internal testing or evaluation only; +* You do not copy, distribute, sublicense, reverse-engineer, or use the Software in client-facing or commercial contexts. -For all third party components incorporated into the Stirling PDF Software, those -components are licensed under the original license provided by the owner of the -applicable component. +Continued use beyond this scope requires a valid Stirling PDF User License. + +Modifications and Derivative Works + +You may modify the Software only for development or internal testing purposes. Any such modifications or derivative works: + +* May not be deployed in production environments without a valid User License; +* May not be distributed or sublicensed; +* Remain the intellectual property of Stirling PDF and/or its licensors; +* May only be used, copied, or exploited in accordance with the terms of a valid Stirling PDF User License subscription. + +Prohibited Actions + +Unless explicitly permitted by a paid license or separate agreement, you may not: + +* Use the Software in production environments; +* Copy, merge, distribute, sublicense, or sell the Software; +* Remove or alter any licensing or copyright notices; +* Circumvent access restrictions or licensing requirements. + +Third-Party Components + +The Stirling PDF Software may include components subject to separate open source licenses. Such components remain governed by +their original license terms as provided by their respective owners. + +Disclaimer + +THE SOFTWARE IS PROVIDED “AS IS,” WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java index 8d686e4d7..5507580a4 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java @@ -4,6 +4,7 @@ import javax.sql.DataSource; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.jdbc.DatabaseDriver; @@ -54,14 +55,25 @@ public class DatabaseConfig { public DataSource dataSource() throws UnsupportedProviderException { DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); - if (!runningProOrHigher) { + if (!runningProOrHigher || !datasource.isEnableCustomDatabase()) { return useDefaultDataSource(dataSourceBuilder); } - if (!datasource.isEnableCustomDatabase()) { - return useDefaultDataSource(dataSourceBuilder); - } + return useCustomDataSource(dataSourceBuilder); + } + private DataSource useDefaultDataSource(DataSourceBuilder dataSourceBuilder) { + log.info("Using default H2 database"); + + dataSourceBuilder.url(DATASOURCE_DEFAULT_URL) + .driverClassName(DatabaseDriver.H2.getDriverClassName()) + .username(DEFAULT_USERNAME); + + return dataSourceBuilder.build(); + } + + @ConditionalOnBooleanProperty(name = "premium.enabled") + private DataSource useCustomDataSource(DataSourceBuilder dataSourceBuilder) throws UnsupportedProviderException { log.info("Using custom database configuration"); if (!datasource.getCustomDatabaseUrl().isBlank()) { @@ -73,11 +85,11 @@ public class DatabaseConfig { } else { dataSourceBuilder.driverClassName(getDriverClassName(datasource.getType())); dataSourceBuilder.url( - generateCustomDataSourceUrl( - datasource.getType(), - datasource.getHostName(), - datasource.getPort(), - datasource.getName())); + generateCustomDataSourceUrl( + datasource.getType(), + datasource.getHostName(), + datasource.getPort(), + datasource.getName())); } dataSourceBuilder.username(datasource.getUsername()); dataSourceBuilder.password(datasource.getPassword()); @@ -85,16 +97,6 @@ public class DatabaseConfig { return dataSourceBuilder.build(); } - private DataSource useDefaultDataSource(DataSourceBuilder dataSourceBuilder) { - log.info("Using default H2 database"); - - dataSourceBuilder.url(DATASOURCE_DEFAULT_URL) - .driverClassName(DatabaseDriver.H2.getDriverClassName()) - .username(DEFAULT_USERNAME); - - return dataSourceBuilder.build(); - } - /** * Generate the URL the DataSource will use to connect to the database * diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java index c31d42dde..cec19214a 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java @@ -6,7 +6,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.Lazy; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; @@ -26,7 +25,7 @@ import org.springframework.security.web.authentication.rememberme.PersistentToke import org.springframework.security.web.csrf.CookieCsrfTokenRepository; import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler; import org.springframework.security.web.savedrequest.NullRequestCache; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import stirling.software.common.configuration.AppConfig; import stirling.software.common.model.ApplicationProperties; import stirling.software.proprietary.security.CustomAuthenticationFailureHandler; @@ -53,7 +52,6 @@ import stirling.software.proprietary.security.session.SessionPersistentRegistry; @Configuration @EnableWebSecurity @EnableMethodSecurity -@DependsOn("runningProOrHigher") public class SecurityConfiguration { private final CustomUserDetailsService userDetailsService; @@ -167,7 +165,7 @@ public class SecurityConfiguration { http.requestCache(requestCache -> requestCache.requestCache(new NullRequestCache())); http.logout( logout -> - logout.logoutRequestMatcher(new AntPathRequestMatcher("/logout")) + logout.logoutRequestMatcher(PathPatternRequestMatcher.withDefaults().matcher("/logout")) .logoutSuccessHandler( new CustomLogoutSuccessHandler(applicationProperties, appConfig)) .clearAuthentication(true) diff --git a/src/main/java/stirling/software/SPDF/SPDFApplication.java b/src/main/java/stirling/software/SPDF/SPDFApplication.java index b3f6dd078..91a5354e4 100644 --- a/src/main/java/stirling/software/SPDF/SPDFApplication.java +++ b/src/main/java/stirling/software/SPDF/SPDFApplication.java @@ -35,7 +35,11 @@ import stirling.software.common.util.UrlUtils; @Slf4j @EnableScheduling @SpringBootApplication( - scanBasePackages = {"stirling.software.common", "stirling.software.SPDF"}, + scanBasePackages = { + "stirling.software.common", + "stirling.software.SPDF", + "stirling.software.proprietary.security" + }, exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index 2228b73a7..b22e2ab66 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -64,7 +64,6 @@ premium: key: 00000000-0000-0000-0000-000000000000 enabled: true # Enable license key checks for pro/enterprise features proFeatures: - customDatabase: false # Enable database features todo: use only for custom DB SSOAutoLogin: false CustomMetadata: autoUpdateMetadata: false From 149fe8755d303e3fa1202e95d598f4144be1163b Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Wed, 28 May 2025 16:34:59 +0100 Subject: [PATCH 06/15] DOCKER_ENABLE_SECURITY > ADDITIONAL_FEATURES_OFF --- .../workflows/PR-Demo-Comment-with-react.yml | 9 +- .github/workflows/build.yml | 2 + .github/workflows/multiOSReleases.yml | 7 + .github/workflows/push-docker.yml | 1 + .github/workflows/releaseArtifacts.yml | 6 + .github/workflows/sonarqube.yml | 1 + .github/workflows/testdriver.yml | 2 + DeveloperGuide.md | 5 +- Dockerfile | 1 + Dockerfile.fat | 4 +- Dockerfile.ultra-lite | 1 + build.gradle | 6 +- common/gradlew | 251 ------------------ common/gradlew.bat | 94 ------- ...-compose-latest-fat-endpoints-disabled.yml | 1 + ...r-compose-latest-fat-security-postgres.yml | 1 + .../docker-compose-latest-fat-security.yml | 1 + ...ocker-compose-latest-security-with-sso.yml | 1 + .../docker-compose-latest-security.yml | 1 + ...ker-compose-latest-ultra-lite-security.yml | 1 + .../docker-compose-latest-ultra-lite.yml | 1 + exampleYmlFiles/docker-compose-latest.yml | 1 + exampleYmlFiles/test_cicd.yml | 1 + proprietary/gradlew | 251 ------------------ proprietary/gradlew.bat | 94 ------- .../security/oauth2/OAuth2Configuration.java | 5 +- .../security/saml2/SAML2Configuration.java | 3 +- scripts/download-security-jar.sh | 4 +- testing/test.sh | 58 ++-- 29 files changed, 82 insertions(+), 732 deletions(-) delete mode 100755 common/gradlew delete mode 100644 common/gradlew.bat delete mode 100755 proprietary/gradlew delete mode 100644 proprietary/gradlew.bat diff --git a/.github/workflows/PR-Demo-Comment-with-react.yml b/.github/workflows/PR-Demo-Comment-with-react.yml index 67ed61ef1..406568cff 100644 --- a/.github/workflows/PR-Demo-Comment-with-react.yml +++ b/.github/workflows/PR-Demo-Comment-with-react.yml @@ -84,7 +84,7 @@ jobs: core.setOutput('repository', repository); core.setOutput('ref', pr.head.ref); - + - name: Check for security/login flag id: check-security-flag env: @@ -157,8 +157,10 @@ jobs: run: | if [ "${{ needs.check-comment.outputs.enable_security }}" == "true" ]; then export DOCKER_ENABLE_SECURITY=true + export ADDITIONAL_FEATURES_OFF=false else export DOCKER_ENABLE_SECURITY=false + export ADDITIONAL_FEATURES_OFF=true fi ./gradlew clean build env: @@ -223,7 +225,8 @@ jobs: - /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/config:/configs:rw - /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "${DOCKER_SECURITY}" + DOCKER_ENABLE_SECURITY: "${DOCKER_SECURITY}" # todo: change DOCKER_SECURITY? + ADDITIONAL_FEATURES_OFF: "${DOCKER_SECURITY}" SECURITY_ENABLELOGIN: "${LOGIN_SECURITY}" SYSTEM_DEFAULTLOCALE: en-GB UI_APPNAME: "Stirling-PDF PR#${{ needs.check-comment.outputs.pr_number }}" @@ -250,7 +253,7 @@ jobs: docker-compose pull docker-compose up -d ENDSSH - + # Set output for use in PR comment echo "security_status=${SECURITY_STATUS}" >> $GITHUB_ENV diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 322d52af1..198a8d411 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,11 +41,13 @@ jobs: run: ./gradlew clean build env: DOCKER_ENABLE_SECURITY: false + ADDITIONAL_FEATURES_OFF: true - name: Build with Gradle and with spring security run: ./gradlew clean build env: DOCKER_ENABLE_SECURITY: true + ADDITIONAL_FEATURES_OFF: false - name: Upload Test Reports if: always() diff --git a/.github/workflows/multiOSReleases.yml b/.github/workflows/multiOSReleases.yml index dd8f54a9b..8e0ef3837 100644 --- a/.github/workflows/multiOSReleases.yml +++ b/.github/workflows/multiOSReleases.yml @@ -49,11 +49,16 @@ jobs: strategy: matrix: enable_security: [true, false] + disable_security: [true, false] include: - enable_security: true file_suffix: "-with-login" - enable_security: false file_suffix: "" + - disable_security: true + file_suffix: "" + - disable_security: false + file_suffix: "-with-login" steps: - name: Harden Runner uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 @@ -76,6 +81,7 @@ jobs: run: ./gradlew clean createExe env: DOCKER_ENABLE_SECURITY: ${{ matrix.enable_security }} + ADDITIONAL_FEATURES_OFF: ${{ matrix.disable_security }} STIRLING_PDF_DESKTOP_UI: false - name: Rename binaries @@ -172,6 +178,7 @@ jobs: run: ./gradlew build jpackage -x test --info env: DOCKER_ENABLE_SECURITY: false + ADDITIONAL_FEATURES_OFF: true STIRLING_PDF_DESKTOP_UI: true BROWSER_OPEN: true diff --git a/.github/workflows/push-docker.yml b/.github/workflows/push-docker.yml index 7fa1b9afb..7e9f483f0 100644 --- a/.github/workflows/push-docker.yml +++ b/.github/workflows/push-docker.yml @@ -38,6 +38,7 @@ jobs: run: ./gradlew clean build env: DOCKER_ENABLE_SECURITY: false + ADDITIONAL_FEATURES_OFF: true STIRLING_PDF_DESKTOP_UI: false - name: Install cosign diff --git a/.github/workflows/releaseArtifacts.yml b/.github/workflows/releaseArtifacts.yml index 71be7b03a..476ae8a9c 100644 --- a/.github/workflows/releaseArtifacts.yml +++ b/.github/workflows/releaseArtifacts.yml @@ -14,11 +14,16 @@ jobs: strategy: matrix: enable_security: [true, false] + disable_security: [true, false] include: - enable_security: true file_suffix: "-with-login" - enable_security: false file_suffix: "" + - disable_security: true + file_suffix: "" + - disable_security: false + file_suffix: "-with-login" outputs: version: ${{ steps.versionNumber.outputs.versionNumber }} steps: @@ -43,6 +48,7 @@ jobs: run: ./gradlew clean createExe env: DOCKER_ENABLE_SECURITY: ${{ matrix.enable_security }} + ADDITIONAL_FEATURES_OFF: ${{ matrix.disable_security }} STIRLING_PDF_DESKTOP_UI: false - name: Get version number diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml index f9ab27ecc..4c12b819a 100644 --- a/.github/workflows/sonarqube.yml +++ b/.github/workflows/sonarqube.yml @@ -34,6 +34,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} DOCKER_ENABLE_SECURITY: true + ADDITIONAL_FEATURES_OFF: false STIRLING_PDF_DESKTOP_UI: true run: | ./gradlew clean build sonar \ diff --git a/.github/workflows/testdriver.yml b/.github/workflows/testdriver.yml index 44c2fbe11..a71293e3e 100644 --- a/.github/workflows/testdriver.yml +++ b/.github/workflows/testdriver.yml @@ -29,6 +29,7 @@ jobs: run: ./gradlew clean build env: DOCKER_ENABLE_SECURITY: false + ADDITIONAL_FEATURES_OFF: true - name: Set up Docker Buildx uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 @@ -77,6 +78,7 @@ jobs: - /stirling/test-${{ github.sha }}/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "false" + ADDITIONAL_FEATURES_OFF: "true" SECURITY_ENABLELOGIN: "false" SYSTEM_DEFAULTLOCALE: en-GB UI_APPNAME: "Stirling-PDF Test" diff --git a/DeveloperGuide.md b/DeveloperGuide.md index 32d480f5c..675e5b4db 100644 --- a/DeveloperGuide.md +++ b/DeveloperGuide.md @@ -55,7 +55,7 @@ Stirling-PDF uses Lombok to reduce boilerplate code. Some IDEs, like Eclipse, do Visit the [Lombok website](https://projectlombok.org/setup/) for installation instructions specific to your IDE. 5. Add environment variable -For local testing, you should generally be testing the full 'Security' version of Stirling-PDF. To do this, you must add the environment flag DOCKER_ENABLE_SECURITY=true to your system and/or IDE build/run step. +For local testing, you should generally be testing the full 'Security' version of Stirling-PDF. To do this, you must add the environment flag DOCKER_ENABLE_SECURITY=true or ADDITIONAL_FEATURES_OFF=false to your system and/or IDE build/run step. ## 4. Project Structure @@ -142,6 +142,7 @@ services: - /stirling/latest/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "true" + ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" PUID: 1002 PGID: 1002 @@ -171,6 +172,7 @@ Stirling-PDF uses different Docker images for various configurations. The build ```bash export DOCKER_ENABLE_SECURITY=false # or true for security-enabled builds + export ADDITIONAL_FEATURES_OFF=true # or false for security-enabled builds ``` 2. Build the project with Gradle: @@ -197,6 +199,7 @@ Stirling-PDF uses different Docker images for various configurations. The build ```bash export DOCKER_ENABLE_SECURITY=true + export ADDITIONAL_FEATURES_OFF=false docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest-fat -f ./Dockerfile.fat . ``` diff --git a/Dockerfile b/Dockerfile index f078e78ac..bf302116b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,7 @@ LABEL org.opencontainers.image.keywords="PDF, manipulation, merge, split, conver # Set Environment Variables ENV DOCKER_ENABLE_SECURITY=false \ + ADDITIONAL_FEATURES_OFF=true \ VERSION_TAG=$VERSION_TAG \ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ JAVA_CUSTOM_OPTS="" \ diff --git a/Dockerfile.fat b/Dockerfile.fat index f442e60c8..203af02da 100644 --- a/Dockerfile.fat +++ b/Dockerfile.fat @@ -15,8 +15,9 @@ WORKDIR /app # Copy the entire project to the working directory COPY . . -# Build the application with DOCKER_ENABLE_SECURITY=false +# Build the application with DOCKER_ENABLE_SECURITY=true/ADDITIONAL_FEATURES_OFF=false RUN DOCKER_ENABLE_SECURITY=true \ + ADDITIONAL_FEATURES_OFF=false \ STIRLING_PDF_DESKTOP_UI=false \ ./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube @@ -33,6 +34,7 @@ ARG VERSION_TAG # Set Environment Variables ENV DOCKER_ENABLE_SECURITY=false \ + ADDITIONAL_FEATURES_OFF=true \ VERSION_TAG=$VERSION_TAG \ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ JAVA_CUSTOM_OPTS="" \ diff --git a/Dockerfile.ultra-lite b/Dockerfile.ultra-lite index ec0ab55aa..a30c45d48 100644 --- a/Dockerfile.ultra-lite +++ b/Dockerfile.ultra-lite @@ -5,6 +5,7 @@ ARG VERSION_TAG # Set Environment Variables ENV DOCKER_ENABLE_SECURITY=false \ + ADDITIONAL_FEATURES_OFF=true \ HOME=/home/stirlingpdfuser \ VERSION_TAG=$VERSION_TAG \ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ diff --git a/build.gradle b/build.gradle index c6a2e74be..832a0f4a5 100644 --- a/build.gradle +++ b/build.gradle @@ -51,7 +51,7 @@ licenseReport { sourceSets { main { java { - if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") { + if (System.getenv("DOCKER_ENABLE_SECURITY") == "false" || System.getenv("ADDITIONAL_FEATURES_OFF") == "true") { exclude "stirling/software/proprietary/security/**" } @@ -64,7 +64,7 @@ sourceSets { test { java { - if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") { + if (System.getenv("DOCKER_ENABLE_SECURITY") == "false" || System.getenv("ADDITIONAL_FEATURES_OFF") == "true") { exclude "stirling/software/proprietary/security/**" } @@ -426,7 +426,7 @@ dependencies { implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1' implementation 'org.snakeyaml:snakeyaml-engine:2.9' - if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") { + if (System.getenv("DOCKER_ENABLE_SECURITY") != "false" || System.getenv("ADDITIONAL_FEATURES_OFF") == "false") { implementation project(':proprietary') } diff --git a/common/gradlew b/common/gradlew deleted file mode 100755 index 23d15a936..000000000 --- a/common/gradlew +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH="\\\"\\\"" - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/common/gradlew.bat b/common/gradlew.bat deleted file mode 100644 index db3a6ac20..000000000 --- a/common/gradlew.bat +++ /dev/null @@ -1,94 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH= - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml b/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml index f36cd5bc7..63b0a7467 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml @@ -21,6 +21,7 @@ services: - ../testing/allEndpointsRemovedSettings.yml:/configs/settings.yml:rw environment: DOCKER_ENABLE_SECURITY: "true" + ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "false" PUID: 1002 PGID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml b/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml index c04da1912..318065e05 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml @@ -21,6 +21,7 @@ services: - ./stirling/latest/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "true" + ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "false" PUID: 1002 PGID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-fat-security.yml b/exampleYmlFiles/docker-compose-latest-fat-security.yml index d9e4fa5a9..8d9ebeff4 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-security.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-security.yml @@ -19,6 +19,7 @@ services: - ./stirling/latest/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "true" + ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "false" PUID: 1002 PGID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml b/exampleYmlFiles/docker-compose-latest-security-with-sso.yml index 1514dd7d8..36cbfe868 100644 --- a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml +++ b/exampleYmlFiles/docker-compose-latest-security-with-sso.yml @@ -19,6 +19,7 @@ services: - /stirling/latest/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "true" + ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" SECURITY_OAUTH2_ENABLED: "true" SECURITY_OAUTH2_AUTOCREATEUSER: "true" # This is set to true to allow auto-creation of non-existing users in Stirling-PDF diff --git a/exampleYmlFiles/docker-compose-latest-security.yml b/exampleYmlFiles/docker-compose-latest-security.yml index ccd3a41c6..d6d90bf0a 100644 --- a/exampleYmlFiles/docker-compose-latest-security.yml +++ b/exampleYmlFiles/docker-compose-latest-security.yml @@ -19,6 +19,7 @@ services: - ./stirling/latest/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "true" + ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" PUID: 1002 PGID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml b/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml index c59713b71..b3cb57cd1 100644 --- a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml +++ b/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml @@ -19,6 +19,7 @@ services: - /stirling/latest/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "true" + ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" SYSTEM_DEFAULTLOCALE: en-US UI_APPNAME: Stirling-PDF-Lite diff --git a/exampleYmlFiles/docker-compose-latest-ultra-lite.yml b/exampleYmlFiles/docker-compose-latest-ultra-lite.yml index 6148f7251..f6c1b703a 100644 --- a/exampleYmlFiles/docker-compose-latest-ultra-lite.yml +++ b/exampleYmlFiles/docker-compose-latest-ultra-lite.yml @@ -18,6 +18,7 @@ services: - /stirling/latest/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "false" + ADDITIONAL_FEATURES_OFF: "true" SECURITY_ENABLELOGIN: "false" SYSTEM_DEFAULTLOCALE: en-US UI_APPNAME: Stirling-PDF-Ultra-lite diff --git a/exampleYmlFiles/docker-compose-latest.yml b/exampleYmlFiles/docker-compose-latest.yml index 51266ee8b..3a296b84a 100644 --- a/exampleYmlFiles/docker-compose-latest.yml +++ b/exampleYmlFiles/docker-compose-latest.yml @@ -19,6 +19,7 @@ services: - /stirling/latest/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "false" + ADDITIONAL_FEATURES_OFF: "true" SECURITY_ENABLELOGIN: "false" LANGS: "en_GB,en_US,ar_AR,de_DE,fr_FR,es_ES,zh_CN,zh_TW,ca_CA,it_IT,sv_SE,pl_PL,ro_RO,ko_KR,pt_BR,ru_RU,el_GR,hi_IN,hu_HU,tr_TR,id_ID" SYSTEM_DEFAULTLOCALE: en-US diff --git a/exampleYmlFiles/test_cicd.yml b/exampleYmlFiles/test_cicd.yml index eebb50f2a..f92c80d8f 100644 --- a/exampleYmlFiles/test_cicd.yml +++ b/exampleYmlFiles/test_cicd.yml @@ -19,6 +19,7 @@ services: - /stirling/latest/logs:/logs:rw environment: DOCKER_ENABLE_SECURITY: "true" + ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" PUID: 1002 PGID: 1002 diff --git a/proprietary/gradlew b/proprietary/gradlew deleted file mode 100755 index 23d15a936..000000000 --- a/proprietary/gradlew +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH="\\\"\\\"" - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/proprietary/gradlew.bat b/proprietary/gradlew.bat deleted file mode 100644 index db3a6ac20..000000000 --- a/proprietary/gradlew.bat +++ /dev/null @@ -1,94 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH= - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java index a0f11c5b2..cb2771cc0 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -36,8 +37,7 @@ import static stirling.software.common.util.ValidationUtils.isStringEmpty; @Slf4j @Configuration -@ConditionalOnProperty(value = "security.oauth2.enabled", havingValue = "true") -@ConditionalOnExpression("${docker.enable.security:true}") // todo: change this +@ConditionalOnBooleanProperty("security.oauth2.enabled") public class OAuth2Configuration { public static final String REDIRECT_URI_PATH = "{baseUrl}/login/oauth2/code/"; @@ -52,7 +52,6 @@ public class OAuth2Configuration { } @Bean - @ConditionalOnProperty(value = "security.oauth2.enabled", havingValue = "true") public ClientRegistrationRepository clientRegistrationRepository() throws NoProviderFoundException { List registrations = new ArrayList<>(); diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java index 8482b8753..836419ea0 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java @@ -7,6 +7,7 @@ import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.opensaml.saml.saml2.core.AuthnRequest; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -25,8 +26,8 @@ import stirling.software.common.model.ApplicationProperties.Security.SAML2; @Configuration @Slf4j -@ConditionalOnProperty(value = "security.saml2.enabled", havingValue = "true") @RequiredArgsConstructor +@ConditionalOnBooleanProperty("security.saml2.enabled") public class SAML2Configuration { private final ApplicationProperties applicationProperties; diff --git a/scripts/download-security-jar.sh b/scripts/download-security-jar.sh index df03bf1d0..8216179fa 100644 --- a/scripts/download-security-jar.sh +++ b/scripts/download-security-jar.sh @@ -1,6 +1,6 @@ -echo "Running Stirling PDF with DOCKER_ENABLE_SECURITY=${DOCKER_ENABLE_SECURITY} and VERSION_TAG=${VERSION_TAG}" +echo "Running Stirling PDF with ADDITIONAL_FEATURES_OFF=${ADDITIONAL_FEATURES_OFF} and VERSION_TAG=${VERSION_TAG}" # Check for DOCKER_ENABLE_SECURITY and download the appropriate JAR if required -if [ "$DOCKER_ENABLE_SECURITY" = "true" ] && [ "$VERSION_TAG" != "alpha" ]; then +if [ "$DOCKER_ENABLE_SECURITY" = "true" ] || [ "$ADDITIONAL_FEATURES_OFF" = "false" ] && [ "$VERSION_TAG" != "alpha" ]; then if [ ! -f app-security.jar ]; then echo "Trying to download from: https://files.stirlingpdf.com/v$VERSION_TAG/Stirling-PDF-with-login.jar" curl -L -o app-security.jar https://files.stirlingpdf.com/v$VERSION_TAG/Stirling-PDF-with-login.jar diff --git a/testing/test.sh b/testing/test.sh index 5c4455dc2..f1169ec17 100644 --- a/testing/test.sh +++ b/testing/test.sh @@ -43,7 +43,7 @@ check_health() { capture_file_list() { local container_name=$1 local output_file=$2 - + echo "Capturing file list from $container_name..." # Get all files in one command, output directly from Docker to avoid path issues # Skip proc, sys, dev, and the specified LibreOffice config directory @@ -60,12 +60,12 @@ capture_file_list() { -not -path '*/tmp/lu*' \ -not -path '*/tmp/tmp*' \ 2>/dev/null | xargs -I{} sh -c 'stat -c \"%n %s %Y\" \"{}\" 2>/dev/null || true' | sort" > "$output_file" - + # Check if the output file has content if [ ! -s "$output_file" ]; then echo "WARNING: Failed to capture file list or container returned empty list" echo "Trying alternative approach..." - + # Alternative simpler approach - just get paths as a fallback docker exec $container_name sh -c "find / -type f \ -not -path '*/proc/*' \ @@ -79,14 +79,14 @@ capture_file_list() { -not -path '*/tmp/lu*' \ -not -path '*/tmp/tmp*' \ 2>/dev/null | sort" > "$output_file" - + if [ ! -s "$output_file" ]; then echo "ERROR: All attempts to capture file list failed" # Create a dummy entry to prevent diff errors echo "NO_FILES_FOUND 0 0" > "$output_file" fi fi - + echo "File list captured to $output_file" } @@ -96,24 +96,24 @@ compare_file_lists() { local after_file=$2 local diff_file=$3 local container_name=$4 # Added container_name parameter - + echo "Comparing file lists..." - + # Check if files exist and have content if [ ! -s "$before_file" ] || [ ! -s "$after_file" ]; then echo "WARNING: One or both file lists are empty." - + if [ ! -s "$before_file" ]; then echo "Before file is empty: $before_file" fi - + if [ ! -s "$after_file" ]; then echo "After file is empty: $after_file" fi - + # Create empty diff file > "$diff_file" - + # Check if we at least have the after file to look for temp files if [ -s "$after_file" ]; then echo "Checking for temp files in the after snapshot..." @@ -128,23 +128,23 @@ compare_file_lists() { echo "No temporary files found in the after snapshot." fi fi - + return 0 fi - + # Both files exist and have content, proceed with diff diff "$before_file" "$after_file" > "$diff_file" - + if [ -s "$diff_file" ]; then echo "Detected changes in files:" cat "$diff_file" - + # Extract only added files (lines starting with ">") grep "^>" "$diff_file" > "${diff_file}.added" || true if [ -s "${diff_file}.added" ]; then echo "New files created during test:" cat "${diff_file}.added" | sed 's/^> //' - + # Check for tmp files grep -i "tmp\|temp" "${diff_file}.added" > "${diff_file}.tmp" || true if [ -s "${diff_file}.tmp" ]; then @@ -155,7 +155,7 @@ compare_file_lists() { return 1 fi fi - + # Extract only removed files (lines starting with "<") grep "^<" "$diff_file" > "${diff_file}.removed" || true if [ -s "${diff_file}.removed" ]; then @@ -165,7 +165,7 @@ compare_file_lists() { else echo "No file changes detected during test." fi - + return 0 } @@ -215,6 +215,7 @@ main() { export DOCKER_CLI_EXPERIMENTAL=enabled export COMPOSE_DOCKER_CLI_BUILD=0 export DOCKER_ENABLE_SECURITY=false + export ADDITIONAL_FEATURES_OFF=true # Run the gradlew build command and check if it fails if ! ./gradlew clean build; then echo "Gradle build failed with security disabled, exiting script." @@ -243,6 +244,7 @@ main() { # docker-compose -f "./exampleYmlFiles/docker-compose-latest.yml" down export DOCKER_ENABLE_SECURITY=true + export ADDITIONAL_FEATURES_OFF=false # Run the gradlew build command and check if it fails if ! ./gradlew clean build; then echo "Gradle build failed with security enabled, exiting script." @@ -282,27 +284,27 @@ main() { # Create directory for file snapshots if it doesn't exist SNAPSHOT_DIR="$PROJECT_ROOT/testing/file_snapshots" mkdir -p "$SNAPSHOT_DIR" - + # Capture file list before running behave tests BEFORE_FILE="$SNAPSHOT_DIR/files_before_behave.txt" AFTER_FILE="$SNAPSHOT_DIR/files_after_behave.txt" DIFF_FILE="$SNAPSHOT_DIR/files_diff.txt" - + # Define container name variable for consistency CONTAINER_NAME="Stirling-PDF-Security-Fat-with-login" - + capture_file_list "$CONTAINER_NAME" "$BEFORE_FILE" - + cd "testing/cucumber" if python -m behave; then # Wait 10 seconds before capturing the file list after tests echo "Waiting 5 seconds for any file operations to complete..." sleep 5 - + # Capture file list after running behave tests cd "$PROJECT_ROOT" capture_file_list "$CONTAINER_NAME" "$AFTER_FILE" - + # Compare file lists if compare_file_lists "$BEFORE_FILE" "$AFTER_FILE" "$DIFF_FILE" "$CONTAINER_NAME"; then echo "No unexpected temporary files found." @@ -311,19 +313,19 @@ main() { echo "WARNING: Unexpected temporary files detected after behave tests!" failed_tests+=("Stirling-PDF-Regression-Temp-Files") fi - + passed_tests+=("Stirling-PDF-Regression") else failed_tests+=("Stirling-PDF-Regression") echo "Printing docker logs of failed regression" docker logs "$CONTAINER_NAME" echo "Printed docker logs of failed regression" - + # Still capture file list after failure for analysis # Wait 10 seconds before capturing the file list echo "Waiting 5 seconds before capturing file list..." sleep 10 - + cd "$PROJECT_ROOT" capture_file_list "$CONTAINER_NAME" "$AFTER_FILE" compare_file_lists "$BEFORE_FILE" "$AFTER_FILE" "$DIFF_FILE" "$CONTAINER_NAME" @@ -372,4 +374,4 @@ main() { fi } -main \ No newline at end of file +main From 275039015df18092378d2fd35d5ea114ed1a990f Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Fri, 30 May 2025 18:09:02 +0100 Subject: [PATCH 07/15] updating LICENSE-proprietary --- proprietary/LICENSE-proprietary | 7 ++----- .../software/SPDF/EE/KeygenLicenseVerifier.java | 10 +++++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/proprietary/LICENSE-proprietary b/proprietary/LICENSE-proprietary index df9b7b974..d26855680 100644 --- a/proprietary/LICENSE-proprietary +++ b/proprietary/LICENSE-proprietary @@ -14,11 +14,8 @@ covering the appropriate number of licensed users. Trial and Minimal Use -You may use the Software without a paid subscription for the sole purposes of internal trial, evaluation, or minimal use, -provided that: - -* Use is limited to no more than five (5) named users or sessions; -* Use is strictly non-production, for internal testing or evaluation only; +You may use the Software without a paid subscription for the sole purposes of internal trial, evaluation, or minimal use, provided that: +* Use is limited to the capabilities and restrictions defined by the Software itself; * You do not copy, distribute, sublicense, reverse-engineer, or use the Software in client-facing or commercial contexts. Continued use beyond this scope requires a valid Stirling PDF User License. diff --git a/src/main/java/stirling/software/SPDF/EE/KeygenLicenseVerifier.java b/src/main/java/stirling/software/SPDF/EE/KeygenLicenseVerifier.java index c760a83c9..e92e048e9 100644 --- a/src/main/java/stirling/software/SPDF/EE/KeygenLicenseVerifier.java +++ b/src/main/java/stirling/software/SPDF/EE/KeygenLicenseVerifier.java @@ -520,7 +520,7 @@ public class KeygenLicenseVerifier { HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - log.info("ValidateLicenseResponse body: {}", response.body()); + log.debug("ValidateLicenseResponse body: {}", response.body()); JsonNode jsonResponse = objectMapper.readTree(response.body()); if (response.statusCode() == 200) { JsonNode metaNode = jsonResponse.path("meta"); @@ -529,9 +529,9 @@ public class KeygenLicenseVerifier { String detail = metaNode.path("detail").asText(); String code = metaNode.path("code").asText(); - log.info("License validity: " + isValid); - log.info("Validation detail: " + detail); - log.info("Validation code: " + code); + log.info("License validity: {}", isValid); + log.info("Validation detail: {}", detail); + log.info("Validation code: {}", code); // Check if the license itself has floating attribute JsonNode licenseAttrs = jsonResponse.path("data").path("attributes"); @@ -595,7 +595,7 @@ public class KeygenLicenseVerifier { .path("isEnterprise") .asBoolean(false); - log.info(applicationProperties.toString()); + log.debug(applicationProperties.toString()); } else { log.error("Error validating license. Status code: {}", response.statusCode()); From 392a10a8c1ce093a1b65478cfad65ad71686d57c Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Mon, 2 Jun 2025 14:39:55 +0100 Subject: [PATCH 08/15] added back activeSecurity bean --- .../software/common/configuration/AppConfig.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/stirling/software/common/configuration/AppConfig.java b/common/src/main/java/stirling/software/common/configuration/AppConfig.java index 732a3b174..f6b8b2d45 100644 --- a/common/src/main/java/stirling/software/common/configuration/AppConfig.java +++ b/common/src/main/java/stirling/software/common/configuration/AppConfig.java @@ -10,6 +10,7 @@ import java.util.Properties; import java.util.function.Predicate; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -146,8 +147,16 @@ public class AppConfig { } } - @ConditionalOnMissingClass("stirling.software.SPDF.config.security.SecurityConfiguration") @Bean(name = "activeSecurity") + @ConditionalOnClass( + name = "stirling.software.proprietary.security.configuration.SecurityConfiguration") + public boolean activeSecurity() { + return true; + } + + @Bean(name = "missingActiveSecurity") + @ConditionalOnMissingClass( + "stirling.software.proprietary.security.configuration.SecurityConfiguration") public boolean missingActiveSecurity() { return false; } From 5a50947e5eadbfe671f2683d1a4562634754d580 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Mon, 2 Jun 2025 15:04:27 +0100 Subject: [PATCH 09/15] updated build.gradle --- .vscode/settings.json | 3 +++ build.gradle | 1 + proprietary/build.gradle | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index e45bc4dd9..f759730f2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -50,8 +50,10 @@ ".vscode/", "bin/", "common/bin/", + "proprietary/bin/", "build/", "common/build/", + "proprietary/build/", "configs/", "customFiles/", "docs/", @@ -66,6 +68,7 @@ ".gitattributes", ".gitignore", "common/.gitignore", + "proprietary/.gitignore", ".pre-commit-config.yaml", ], // Enables signature help in Java. diff --git a/build.gradle b/build.gradle index 832a0f4a5..87c603617 100644 --- a/build.gradle +++ b/build.gradle @@ -354,6 +354,7 @@ spotless { java { target sourceSets.main.allJava target project(':common').sourceSets.main.allJava + target project(':proprietary').sourceSets.main.allJava googleJavaFormat("1.27.0").aosp().reorderImports(false) diff --git a/proprietary/build.gradle b/proprietary/build.gradle index 5c91d21ba..331476f57 100644 --- a/proprietary/build.gradle +++ b/proprietary/build.gradle @@ -26,17 +26,17 @@ dependencyManagement { dependencies { implementation project(':common') - implementation 'org.springframework:spring-jdbc' - implementation 'org.springframework:spring-webmvc' - implementation 'org.springframework.session:spring-session-core' - implementation "org.springframework.security:spring-security-core:$springSecuritySamlVersion" - implementation "org.springframework.security:spring-security-saml2-service-provider:$springSecuritySamlVersion" - implementation 'org.springframework.boot:spring-boot-starter-jetty' - implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - implementation 'org.springframework.boot:spring-boot-starter-mail' - implementation 'io.swagger.core.v3:swagger-core-jakarta:2.2.30' + api 'org.springframework:spring-jdbc' + api 'org.springframework:spring-webmvc' + api 'org.springframework.session:spring-session-core' + api "org.springframework.security:spring-security-core:$springSecuritySamlVersion" + api "org.springframework.security:spring-security-saml2-service-provider:$springSecuritySamlVersion" + api 'org.springframework.boot:spring-boot-starter-jetty' + api 'org.springframework.boot:spring-boot-starter-security' + api 'org.springframework.boot:spring-boot-starter-data-jpa' + api 'org.springframework.boot:spring-boot-starter-oauth2-client' + api 'org.springframework.boot:spring-boot-starter-mail' + api 'io.swagger.core.v3:swagger-core-jakarta:2.2.30' implementation 'com.bucket4j:bucket4j_jdk17-core:8.14.0' // https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17 @@ -44,7 +44,7 @@ dependencies { implementation 'io.github.pixee:java-security-toolkit:1.2.1' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.3.RELEASE' - implementation 'io.micrometer:micrometer-registry-prometheus' + api 'io.micrometer:micrometer-registry-prometheus' implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5' runtimeOnly 'com.h2database:h2:2.3.232' // Don't upgrade h2database runtimeOnly 'org.postgresql:postgresql:42.7.5' From 41cd7d8f47172d9924c9a746a8df95780710877c Mon Sep 17 00:00:00 2001 From: DarioGii Date: Mon, 2 Jun 2025 22:45:59 +0100 Subject: [PATCH 10/15] removing DOCKER_ENABLE_SECURITY flag --- .../workflows/PR-Demo-Comment-with-react.yml | 3 - .github/workflows/build.yml | 2 - .github/workflows/multiOSReleases.yml | 2 - .github/workflows/push-docker.yml | 1 - .github/workflows/releaseArtifacts.yml | 1 - .github/workflows/sonarqube.yml | 1 - .github/workflows/testdriver.yml | 2 - DeveloperGuide.md | 5 +- Dockerfile | 3 +- Dockerfile.fat | 8 +- Dockerfile.ultra-lite | 3 +- build.gradle | 20 +- ...-compose-latest-fat-endpoints-disabled.yml | 1 - ...r-compose-latest-fat-security-postgres.yml | 1 - .../docker-compose-latest-fat-security.yml | 1 - ...ocker-compose-latest-security-with-sso.yml | 1 - .../docker-compose-latest-security.yml | 1 - ...ker-compose-latest-ultra-lite-security.yml | 1 - .../docker-compose-latest-ultra-lite.yml | 1 - exampleYmlFiles/docker-compose-latest.yml | 1 - exampleYmlFiles/test_cicd.yml | 1 - .../CustomAuthenticationFailureHandler.java | 12 +- .../CustomAuthenticationSuccessHandler.java | 12 +- .../security/CustomLogoutSuccessHandler.java | 20 +- .../security/InitialSecuritySetup.java | 10 +- .../security/RateLimitResetScheduler.java | 4 +- .../configuration/DatabaseConfig.java | 27 +- .../security/configuration/MailConfig.java | 1 + .../configuration/SecurityConfiguration.java | 330 +++++++++--------- .../controller/api/DatabaseController.java | 1 + .../controller/api/UserController.java | 6 +- .../controller/web/AccountWebController.java | 2 +- .../security/database/ScheduledTasks.java | 5 +- .../repository/AuthorityRepository.java | 1 + .../repository/JPATokenRepositoryImpl.java | 1 + .../repository/PersistentLoginRepository.java | 1 + .../repository/SessionRepository.java | 5 +- .../database/repository/UserRepository.java | 1 + .../security/filter/FirstLoginFilter.java | 22 +- .../security/filter/IPRateLimitingFilter.java | 9 +- .../filter/UserAuthenticationFilter.java | 14 +- .../filter/UserBasedRateLimitingFilter.java | 20 +- .../proprietary/security/model/User.java | 1 + .../proprietary/security/model/api/Email.java | 1 + ...tomOAuth2AuthenticationFailureHandler.java | 11 +- ...tomOAuth2AuthenticationSuccessHandler.java | 14 +- .../security/oauth2/OAuth2Configuration.java | 15 +- .../security/saml2/CertificateUtils.java | 1 + .../CustomSaml2AuthenticatedPrincipal.java | 1 + ...stomSaml2AuthenticationFailureHandler.java | 9 +- ...stomSaml2AuthenticationSuccessHandler.java | 16 +- ...mSaml2ResponseAuthenticationConverter.java | 7 +- .../security/saml2/SAML2Configuration.java | 10 +- .../service/AppUpdateAuthService.java | 5 +- .../service/CustomOAuth2UserService.java | 5 +- .../service/CustomUserDetailsService.java | 5 +- .../security/service/DatabaseService.java | 28 +- .../security/service/LoginAttemptService.java | 8 +- .../security/service/UserService.java | 16 +- .../session/CustomHttpSessionListener.java | 6 +- .../session/SessionPersistentRegistry.java | 8 +- .../session/SessionRegistryConfig.java | 4 +- .../security/session/SessionScheduled.java | 4 +- scripts/download-security-jar.sh | 4 +- testing/test.sh | 2 - 65 files changed, 415 insertions(+), 330 deletions(-) diff --git a/.github/workflows/PR-Demo-Comment-with-react.yml b/.github/workflows/PR-Demo-Comment-with-react.yml index 406568cff..786316365 100644 --- a/.github/workflows/PR-Demo-Comment-with-react.yml +++ b/.github/workflows/PR-Demo-Comment-with-react.yml @@ -156,10 +156,8 @@ jobs: - name: Run Gradle Command run: | if [ "${{ needs.check-comment.outputs.enable_security }}" == "true" ]; then - export DOCKER_ENABLE_SECURITY=true export ADDITIONAL_FEATURES_OFF=false else - export DOCKER_ENABLE_SECURITY=false export ADDITIONAL_FEATURES_OFF=true fi ./gradlew clean build @@ -225,7 +223,6 @@ jobs: - /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/config:/configs:rw - /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "${DOCKER_SECURITY}" # todo: change DOCKER_SECURITY? ADDITIONAL_FEATURES_OFF: "${DOCKER_SECURITY}" SECURITY_ENABLELOGIN: "${LOGIN_SECURITY}" SYSTEM_DEFAULTLOCALE: en-GB diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 198a8d411..797a1bca0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,13 +40,11 @@ jobs: - name: Build with Gradle and no spring security run: ./gradlew clean build env: - DOCKER_ENABLE_SECURITY: false ADDITIONAL_FEATURES_OFF: true - name: Build with Gradle and with spring security run: ./gradlew clean build env: - DOCKER_ENABLE_SECURITY: true ADDITIONAL_FEATURES_OFF: false - name: Upload Test Reports diff --git a/.github/workflows/multiOSReleases.yml b/.github/workflows/multiOSReleases.yml index 8e0ef3837..d10d8e8b6 100644 --- a/.github/workflows/multiOSReleases.yml +++ b/.github/workflows/multiOSReleases.yml @@ -80,7 +80,6 @@ jobs: - name: Generate jar (With Security=${{ matrix.enable_security }}) run: ./gradlew clean createExe env: - DOCKER_ENABLE_SECURITY: ${{ matrix.enable_security }} ADDITIONAL_FEATURES_OFF: ${{ matrix.disable_security }} STIRLING_PDF_DESKTOP_UI: false @@ -177,7 +176,6 @@ jobs: - name: Build Installer run: ./gradlew build jpackage -x test --info env: - DOCKER_ENABLE_SECURITY: false ADDITIONAL_FEATURES_OFF: true STIRLING_PDF_DESKTOP_UI: true BROWSER_OPEN: true diff --git a/.github/workflows/push-docker.yml b/.github/workflows/push-docker.yml index 7e9f483f0..210007c72 100644 --- a/.github/workflows/push-docker.yml +++ b/.github/workflows/push-docker.yml @@ -37,7 +37,6 @@ jobs: - name: Run Gradle Command run: ./gradlew clean build env: - DOCKER_ENABLE_SECURITY: false ADDITIONAL_FEATURES_OFF: true STIRLING_PDF_DESKTOP_UI: false diff --git a/.github/workflows/releaseArtifacts.yml b/.github/workflows/releaseArtifacts.yml index 476ae8a9c..09ad89312 100644 --- a/.github/workflows/releaseArtifacts.yml +++ b/.github/workflows/releaseArtifacts.yml @@ -47,7 +47,6 @@ jobs: - name: Generate jar (With Security=${{ matrix.enable_security }}) run: ./gradlew clean createExe env: - DOCKER_ENABLE_SECURITY: ${{ matrix.enable_security }} ADDITIONAL_FEATURES_OFF: ${{ matrix.disable_security }} STIRLING_PDF_DESKTOP_UI: false diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml index 4c12b819a..5509d74bc 100644 --- a/.github/workflows/sonarqube.yml +++ b/.github/workflows/sonarqube.yml @@ -33,7 +33,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - DOCKER_ENABLE_SECURITY: true ADDITIONAL_FEATURES_OFF: false STIRLING_PDF_DESKTOP_UI: true run: | diff --git a/.github/workflows/testdriver.yml b/.github/workflows/testdriver.yml index a71293e3e..27a8255a4 100644 --- a/.github/workflows/testdriver.yml +++ b/.github/workflows/testdriver.yml @@ -28,7 +28,6 @@ jobs: - name: Build with Gradle run: ./gradlew clean build env: - DOCKER_ENABLE_SECURITY: false ADDITIONAL_FEATURES_OFF: true - name: Set up Docker Buildx @@ -77,7 +76,6 @@ jobs: - /stirling/test-${{ github.sha }}/config:/configs:rw - /stirling/test-${{ github.sha }}/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "false" ADDITIONAL_FEATURES_OFF: "true" SECURITY_ENABLELOGIN: "false" SYSTEM_DEFAULTLOCALE: en-GB diff --git a/DeveloperGuide.md b/DeveloperGuide.md index 675e5b4db..cb4c4827a 100644 --- a/DeveloperGuide.md +++ b/DeveloperGuide.md @@ -55,7 +55,7 @@ Stirling-PDF uses Lombok to reduce boilerplate code. Some IDEs, like Eclipse, do Visit the [Lombok website](https://projectlombok.org/setup/) for installation instructions specific to your IDE. 5. Add environment variable -For local testing, you should generally be testing the full 'Security' version of Stirling-PDF. To do this, you must add the environment flag DOCKER_ENABLE_SECURITY=true or ADDITIONAL_FEATURES_OFF=false to your system and/or IDE build/run step. +For local testing, you should generally be testing the full 'Security' version of Stirling-PDF. To do this, you must add the environment flag ADDITIONAL_FEATURES_OFF=false to your system and/or IDE build/run step. ## 4. Project Structure @@ -141,7 +141,6 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "true" ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" PUID: 1002 @@ -171,7 +170,6 @@ Stirling-PDF uses different Docker images for various configurations. The build 1. Set the security environment variable: ```bash - export DOCKER_ENABLE_SECURITY=false # or true for security-enabled builds export ADDITIONAL_FEATURES_OFF=true # or false for security-enabled builds ``` @@ -198,7 +196,6 @@ Stirling-PDF uses different Docker images for various configurations. The build For the fat version (with security enabled): ```bash - export DOCKER_ENABLE_SECURITY=true export ADDITIONAL_FEATURES_OFF=false docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest-fat -f ./Dockerfile.fat . ``` diff --git a/Dockerfile b/Dockerfile index bf302116b..ad8f7c590 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,8 +23,7 @@ LABEL org.opencontainers.image.version="${VERSION_TAG}" LABEL org.opencontainers.image.keywords="PDF, manipulation, merge, split, convert, OCR, watermark" # Set Environment Variables -ENV DOCKER_ENABLE_SECURITY=false \ - ADDITIONAL_FEATURES_OFF=true \ +ENV ADDITIONAL_FEATURES_OFF=true \ VERSION_TAG=$VERSION_TAG \ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ JAVA_CUSTOM_OPTS="" \ diff --git a/Dockerfile.fat b/Dockerfile.fat index 203af02da..e742dd43b 100644 --- a/Dockerfile.fat +++ b/Dockerfile.fat @@ -15,9 +15,8 @@ WORKDIR /app # Copy the entire project to the working directory COPY . . -# Build the application with DOCKER_ENABLE_SECURITY=true/ADDITIONAL_FEATURES_OFF=false -RUN DOCKER_ENABLE_SECURITY=true \ - ADDITIONAL_FEATURES_OFF=false \ +# Build the application with ADDITIONAL_FEATURES_OFF=false +RUN ADDITIONAL_FEATURES_OFF=false \ STIRLING_PDF_DESKTOP_UI=false \ ./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube @@ -33,8 +32,7 @@ COPY --from=build /app/build/libs/*.jar app.jar ARG VERSION_TAG # Set Environment Variables -ENV DOCKER_ENABLE_SECURITY=false \ - ADDITIONAL_FEATURES_OFF=true \ +ENV ADDITIONAL_FEATURES_OFF=true \ VERSION_TAG=$VERSION_TAG \ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ JAVA_CUSTOM_OPTS="" \ diff --git a/Dockerfile.ultra-lite b/Dockerfile.ultra-lite index a30c45d48..3b54091b1 100644 --- a/Dockerfile.ultra-lite +++ b/Dockerfile.ultra-lite @@ -4,8 +4,7 @@ FROM alpine:3.22.0@sha256:8a1f59ffb675680d47db6337b49d22281a139e9d709335b492be02 ARG VERSION_TAG # Set Environment Variables -ENV DOCKER_ENABLE_SECURITY=false \ - ADDITIONAL_FEATURES_OFF=true \ +ENV ADDITIONAL_FEATURES_OFF=true \ HOME=/home/stirlingpdfuser \ VERSION_TAG=$VERSION_TAG \ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ diff --git a/build.gradle b/build.gradle index 87c603617..987b4b14f 100644 --- a/build.gradle +++ b/build.gradle @@ -51,12 +51,14 @@ licenseReport { sourceSets { main { java { - if (System.getenv("DOCKER_ENABLE_SECURITY") == "false" || System.getenv("ADDITIONAL_FEATURES_OFF") == "true") { - exclude "stirling/software/proprietary/security/**" + if (System.getenv('DOCKER_ENABLE_SECURITY') == 'false' || System.getenv('ADDITIONAL_FEATURES_OFF') == 'false' + || (project.hasProperty('ADDITIONAL_FEATURES_OFF') + && System.getProperty('ADDITIONAL_FEATURES_OFF'))) { + exclude 'stirling/software/proprietary/security/**' } - if (System.getenv("STIRLING_PDF_DESKTOP_UI") == "false") { - exclude "stirling/software/SPDF/UI/impl/**" + if (System.getenv('STIRLING_PDF_DESKTOP_UI') == 'false') { + exclude 'stirling/software/SPDF/UI/impl/**' } } @@ -64,12 +66,14 @@ sourceSets { test { java { - if (System.getenv("DOCKER_ENABLE_SECURITY") == "false" || System.getenv("ADDITIONAL_FEATURES_OFF") == "true") { - exclude "stirling/software/proprietary/security/**" + if (System.getenv('DOCKER_ENABLE_SECURITY') == 'false' || System.getenv('ADDITIONAL_FEATURES_OFF') == 'false' + || (project.hasProperty('ADDITIONAL_FEATURES_OFF') + && System.getProperty('ADDITIONAL_FEATURES_OFF'))) { + exclude 'stirling/software/proprietary/security/**' } - if (System.getenv("STIRLING_PDF_DESKTOP_UI") == "false") { - exclude "stirling/software/SPDF/UI/impl/**" + if (System.getenv('STIRLING_PDF_DESKTOP_UI') == 'false') { + exclude 'stirling/software/SPDF/UI/impl/**' } } } diff --git a/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml b/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml index 63b0a7467..4f3b25948 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml @@ -20,7 +20,6 @@ services: - ./stirling/latest/logs:/logs:rw - ../testing/allEndpointsRemovedSettings.yml:/configs/settings.yml:rw environment: - DOCKER_ENABLE_SECURITY: "true" ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "false" PUID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml b/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml index 318065e05..f38ed84e2 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml @@ -20,7 +20,6 @@ services: - ./stirling/latest/config:/configs:rw - ./stirling/latest/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "true" ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "false" PUID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-fat-security.yml b/exampleYmlFiles/docker-compose-latest-fat-security.yml index 8d9ebeff4..88441ee9a 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-security.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-security.yml @@ -18,7 +18,6 @@ services: - ./stirling/latest/config:/configs:rw - ./stirling/latest/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "true" ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "false" PUID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml b/exampleYmlFiles/docker-compose-latest-security-with-sso.yml index 36cbfe868..947ddc447 100644 --- a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml +++ b/exampleYmlFiles/docker-compose-latest-security-with-sso.yml @@ -18,7 +18,6 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "true" ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" SECURITY_OAUTH2_ENABLED: "true" diff --git a/exampleYmlFiles/docker-compose-latest-security.yml b/exampleYmlFiles/docker-compose-latest-security.yml index d6d90bf0a..fa8d76888 100644 --- a/exampleYmlFiles/docker-compose-latest-security.yml +++ b/exampleYmlFiles/docker-compose-latest-security.yml @@ -18,7 +18,6 @@ services: - ./stirling/latest/config:/configs:rw - ./stirling/latest/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "true" ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" PUID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml b/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml index b3cb57cd1..434bbcd61 100644 --- a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml +++ b/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml @@ -18,7 +18,6 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "true" ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" SYSTEM_DEFAULTLOCALE: en-US diff --git a/exampleYmlFiles/docker-compose-latest-ultra-lite.yml b/exampleYmlFiles/docker-compose-latest-ultra-lite.yml index f6c1b703a..484acf269 100644 --- a/exampleYmlFiles/docker-compose-latest-ultra-lite.yml +++ b/exampleYmlFiles/docker-compose-latest-ultra-lite.yml @@ -17,7 +17,6 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "false" ADDITIONAL_FEATURES_OFF: "true" SECURITY_ENABLELOGIN: "false" SYSTEM_DEFAULTLOCALE: en-US diff --git a/exampleYmlFiles/docker-compose-latest.yml b/exampleYmlFiles/docker-compose-latest.yml index 3a296b84a..46cfe3553 100644 --- a/exampleYmlFiles/docker-compose-latest.yml +++ b/exampleYmlFiles/docker-compose-latest.yml @@ -18,7 +18,6 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "false" ADDITIONAL_FEATURES_OFF: "true" SECURITY_ENABLELOGIN: "false" LANGS: "en_GB,en_US,ar_AR,de_DE,fr_FR,es_ES,zh_CN,zh_TW,ca_CA,it_IT,sv_SE,pl_PL,ro_RO,ko_KR,pt_BR,ru_RU,el_GR,hi_IN,hu_HU,tr_TR,id_ID" diff --git a/exampleYmlFiles/test_cicd.yml b/exampleYmlFiles/test_cicd.yml index f92c80d8f..c76471bd8 100644 --- a/exampleYmlFiles/test_cicd.yml +++ b/exampleYmlFiles/test_cicd.yml @@ -18,7 +18,6 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - DOCKER_ENABLE_SECURITY: "true" ADDITIONAL_FEATURES_OFF: "false" SECURITY_ENABLELOGIN: "true" PUID: 1002 diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationFailureHandler.java index ee726b9fb..47ad7671c 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationFailureHandler.java @@ -1,11 +1,8 @@ package stirling.software.proprietary.security; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Optional; -import lombok.extern.slf4j.Slf4j; + import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.DisabledException; import org.springframework.security.authentication.InternalAuthenticationServiceException; @@ -13,6 +10,13 @@ import org.springframework.security.authentication.LockedException; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UsernameNotFoundException; 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; + import stirling.software.proprietary.security.model.User; import stirling.software.proprietary.security.service.LoginAttemptService; import stirling.software.proprietary.security.service.UserService; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationSuccessHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationSuccessHandler.java index b9379ec74..8b6ea1dec 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationSuccessHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/CustomAuthenticationSuccessHandler.java @@ -1,14 +1,18 @@ package stirling.software.proprietary.security; +import java.io.IOException; + +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; +import org.springframework.security.web.savedrequest.SavedRequest; + import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; -import java.io.IOException; + import lombok.extern.slf4j.Slf4j; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import org.springframework.security.web.savedrequest.SavedRequest; + import stirling.software.common.util.RequestUriUtils; import stirling.software.proprietary.security.service.LoginAttemptService; import stirling.software.proprietary.security.service.UserService; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/CustomLogoutSuccessHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/CustomLogoutSuccessHandler.java index 244e16da0..44046eb71 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/CustomLogoutSuccessHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/CustomLogoutSuccessHandler.java @@ -1,22 +1,27 @@ package stirling.software.proprietary.security; -import com.coveo.saml.SamlClient; -import com.coveo.saml.SamlException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; + import org.springframework.core.io.Resource; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler; + +import com.coveo.saml.SamlClient; +import com.coveo.saml.SamlException; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.configuration.AppConfig; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; @@ -171,8 +176,7 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { private SamlClient getSamlClient( String registrationId, SAML2 samlConf, List certificates) throws SamlException { - String serverUrl = - appConfig.getBaseUrl() + ":" + appConfig.getServerPort(); + String serverUrl = appConfig.getBaseUrl() + ":" + appConfig.getServerPort(); String relyingPartyIdentifier = serverUrl + "/saml2/service-provider-metadata/" + registrationId; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/InitialSecuritySetup.java b/proprietary/src/main/java/stirling/software/proprietary/security/InitialSecuritySetup.java index 1353f2151..6568ac3b0 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/InitialSecuritySetup.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/InitialSecuritySetup.java @@ -1,14 +1,18 @@ package stirling.software.proprietary.security; -import jakarta.annotation.PostConstruct; import java.sql.SQLException; import java.util.UUID; + +import org.springframework.stereotype.Component; + +import jakarta.annotation.PostConstruct; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; + import stirling.software.common.model.ApplicationProperties; -import stirling.software.common.model.exception.UnsupportedProviderException; import stirling.software.common.model.enumeration.Role; +import stirling.software.common.model.exception.UnsupportedProviderException; import stirling.software.proprietary.security.service.DatabaseServiceInterface; import stirling.software.proprietary.security.service.UserService; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/RateLimitResetScheduler.java b/proprietary/src/main/java/stirling/software/proprietary/security/RateLimitResetScheduler.java index 4faeb9041..25b3c5096 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/RateLimitResetScheduler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/RateLimitResetScheduler.java @@ -1,8 +1,10 @@ package stirling.software.proprietary.security; -import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; + import stirling.software.proprietary.security.filter.IPRateLimitingFilter; @Component diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java index 5507580a4..2feab9a46 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/DatabaseConfig.java @@ -1,8 +1,7 @@ package stirling.software.proprietary.security.configuration; import javax.sql.DataSource; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; + import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.domain.EntityScan; @@ -11,6 +10,10 @@ import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.configuration.InstallationPathConfig; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.exception.UnsupportedProviderException; @@ -65,15 +68,17 @@ public class DatabaseConfig { private DataSource useDefaultDataSource(DataSourceBuilder dataSourceBuilder) { log.info("Using default H2 database"); - dataSourceBuilder.url(DATASOURCE_DEFAULT_URL) - .driverClassName(DatabaseDriver.H2.getDriverClassName()) - .username(DEFAULT_USERNAME); + dataSourceBuilder + .url(DATASOURCE_DEFAULT_URL) + .driverClassName(DatabaseDriver.H2.getDriverClassName()) + .username(DEFAULT_USERNAME); return dataSourceBuilder.build(); } @ConditionalOnBooleanProperty(name = "premium.enabled") - private DataSource useCustomDataSource(DataSourceBuilder dataSourceBuilder) throws UnsupportedProviderException { + private DataSource useCustomDataSource(DataSourceBuilder dataSourceBuilder) + throws UnsupportedProviderException { log.info("Using custom database configuration"); if (!datasource.getCustomDatabaseUrl().isBlank()) { @@ -85,11 +90,11 @@ public class DatabaseConfig { } else { dataSourceBuilder.driverClassName(getDriverClassName(datasource.getType())); dataSourceBuilder.url( - generateCustomDataSourceUrl( - datasource.getType(), - datasource.getHostName(), - datasource.getPort(), - datasource.getName())); + generateCustomDataSourceUrl( + datasource.getType(), + datasource.getHostName(), + datasource.getPort(), + datasource.getName())); } dataSourceBuilder.username(datasource.getUsername()); dataSourceBuilder.password(datasource.getPassword()); diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java index 82d794d6e..c9b6e9d77 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java @@ -10,6 +10,7 @@ import org.springframework.mail.javamail.JavaMailSenderImpl; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; + import stirling.software.common.model.ApplicationProperties; /** diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java index cec19214a..b49e19c08 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java @@ -1,7 +1,7 @@ package stirling.software.proprietary.security.configuration; import java.util.Optional; -import lombok.extern.slf4j.Slf4j; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; @@ -26,6 +26,9 @@ import org.springframework.security.web.csrf.CookieCsrfTokenRepository; import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler; import org.springframework.security.web.savedrequest.NullRequestCache; import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; + +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.configuration.AppConfig; import stirling.software.common.model.ApplicationProperties; import stirling.software.proprietary.security.CustomAuthenticationFailureHandler; @@ -71,22 +74,22 @@ public class SecurityConfiguration { private final OpenSaml4AuthenticationRequestResolver saml2AuthenticationRequestResolver; public SecurityConfiguration( - PersistentLoginRepository persistentLoginRepository, - CustomUserDetailsService userDetailsService, - @Lazy UserService userService, - @Qualifier("loginEnabled") boolean loginEnabledValue, - @Qualifier("runningProOrHigher") boolean runningProOrHigher, - AppConfig appConfig, - ApplicationProperties applicationProperties, - UserAuthenticationFilter userAuthenticationFilter, - LoginAttemptService loginAttemptService, - FirstLoginFilter firstLoginFilter, - SessionPersistentRegistry sessionRegistry, - @Autowired(required = false) GrantedAuthoritiesMapper oAuth2userAuthoritiesMapper, - @Autowired(required = false) - RelyingPartyRegistrationRepository saml2RelyingPartyRegistrations, - @Autowired(required = false) - OpenSaml4AuthenticationRequestResolver saml2AuthenticationRequestResolver) { + PersistentLoginRepository persistentLoginRepository, + CustomUserDetailsService userDetailsService, + @Lazy UserService userService, + @Qualifier("loginEnabled") boolean loginEnabledValue, + @Qualifier("runningProOrHigher") boolean runningProOrHigher, + AppConfig appConfig, + ApplicationProperties applicationProperties, + UserAuthenticationFilter userAuthenticationFilter, + LoginAttemptService loginAttemptService, + FirstLoginFilter firstLoginFilter, + SessionPersistentRegistry sessionRegistry, + @Autowired(required = false) GrantedAuthoritiesMapper oAuth2userAuthoritiesMapper, + @Autowired(required = false) + RelyingPartyRegistrationRepository saml2RelyingPartyRegistrations, + @Autowired(required = false) + OpenSaml4AuthenticationRequestResolver saml2AuthenticationRequestResolver) { this.userDetailsService = userDetailsService; this.userService = userService; this.loginEnabledValue = loginEnabledValue; @@ -116,180 +119,183 @@ public class SecurityConfiguration { if (loginEnabledValue) { http.addFilterBefore( - userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); if (!applicationProperties.getSecurity().getCsrfDisabled()) { CookieCsrfTokenRepository cookieRepo = - CookieCsrfTokenRepository.withHttpOnlyFalse(); + CookieCsrfTokenRepository.withHttpOnlyFalse(); CsrfTokenRequestAttributeHandler requestHandler = - new CsrfTokenRequestAttributeHandler(); + new CsrfTokenRequestAttributeHandler(); requestHandler.setCsrfRequestAttributeName(null); http.csrf( - csrf -> - csrf.ignoringRequestMatchers( - request -> { - String apiKey = request.getHeader("X-API-KEY"); - // If there's no API key, don't ignore CSRF - // (return false) - if (apiKey == null || apiKey.trim().isEmpty()) { - return false; - } - // Validate API key using existing UserService - try { - Optional user = - userService.getUserByApiKey(apiKey); - // If API key is valid, ignore CSRF (return - // true) - // If API key is invalid, don't ignore CSRF - // (return false) - return user.isPresent(); - } catch (Exception e) { - // If there's any error validating the API - // key, don't ignore CSRF - return false; - } - }) - .csrfTokenRepository(cookieRepo) - .csrfTokenRequestHandler(requestHandler)); + csrf -> + csrf.ignoringRequestMatchers( + request -> { + String apiKey = request.getHeader("X-API-KEY"); + // If there's no API key, don't ignore CSRF + // (return false) + if (apiKey == null || apiKey.trim().isEmpty()) { + return false; + } + // Validate API key using existing UserService + try { + Optional user = + userService.getUserByApiKey(apiKey); + // If API key is valid, ignore CSRF (return + // true) + // If API key is invalid, don't ignore CSRF + // (return false) + return user.isPresent(); + } catch (Exception e) { + // If there's any error validating the API + // key, don't ignore CSRF + return false; + } + }) + .csrfTokenRepository(cookieRepo) + .csrfTokenRequestHandler(requestHandler)); } http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class); http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class); http.sessionManagement( - sessionManagement -> - sessionManagement - .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) - .maximumSessions(10) - .maxSessionsPreventsLogin(false) - .sessionRegistry(sessionRegistry) - .expiredUrl("/login?logout=true")); + sessionManagement -> + sessionManagement + .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) + .maximumSessions(10) + .maxSessionsPreventsLogin(false) + .sessionRegistry(sessionRegistry) + .expiredUrl("/login?logout=true")); http.authenticationProvider(daoAuthenticationProvider()); http.requestCache(requestCache -> requestCache.requestCache(new NullRequestCache())); http.logout( - logout -> - logout.logoutRequestMatcher(PathPatternRequestMatcher.withDefaults().matcher("/logout")) - .logoutSuccessHandler( - new CustomLogoutSuccessHandler(applicationProperties, appConfig)) - .clearAuthentication(true) - .invalidateHttpSession(true) - .deleteCookies("JSESSIONID", "remember-me")); + logout -> + logout.logoutRequestMatcher( + PathPatternRequestMatcher.withDefaults() + .matcher("/logout")) + .logoutSuccessHandler( + new CustomLogoutSuccessHandler( + applicationProperties, appConfig)) + .clearAuthentication(true) + .invalidateHttpSession(true) + .deleteCookies("JSESSIONID", "remember-me")); http.rememberMe( - rememberMeConfigurer -> // Use the configurator directly + rememberMeConfigurer -> // Use the configurator directly rememberMeConfigurer - .tokenRepository(persistentTokenRepository()) - .tokenValiditySeconds( // 14 days - 14 * 24 * 60 * 60) - .userDetailsService( // Your existing UserDetailsService - userDetailsService) - .useSecureCookie( // Enable secure cookie - true) - .rememberMeParameter( // Form parameter name - "remember-me") - .rememberMeCookieName( // Cookie name - "remember-me") - .alwaysRemember(false)); + .tokenRepository(persistentTokenRepository()) + .tokenValiditySeconds( // 14 days + 14 * 24 * 60 * 60) + .userDetailsService( // Your existing UserDetailsService + userDetailsService) + .useSecureCookie( // Enable secure cookie + true) + .rememberMeParameter( // Form parameter name + "remember-me") + .rememberMeCookieName( // Cookie name + "remember-me") + .alwaysRemember(false)); http.authorizeHttpRequests( - authz -> - authz.requestMatchers( - req -> { - String uri = req.getRequestURI(); - String contextPath = req.getContextPath(); - // Remove the context path from the URI - String trimmedUri = - uri.startsWith(contextPath) - ? uri.substring( - contextPath.length()) - : uri; - return trimmedUri.startsWith("/login") - || trimmedUri.startsWith("/oauth") - || trimmedUri.startsWith("/saml2") - || trimmedUri.endsWith(".svg") - || trimmedUri.startsWith("/register") - || trimmedUri.startsWith("/error") - || trimmedUri.startsWith("/images/") - || trimmedUri.startsWith("/public/") - || trimmedUri.startsWith("/css/") - || trimmedUri.startsWith("/fonts/") - || trimmedUri.startsWith("/js/") - || trimmedUri.startsWith( - "/api/v1/info/status"); - }) - .permitAll() - .anyRequest() - .authenticated()); + authz -> + authz.requestMatchers( + req -> { + String uri = req.getRequestURI(); + String contextPath = req.getContextPath(); + // Remove the context path from the URI + String trimmedUri = + uri.startsWith(contextPath) + ? uri.substring( + contextPath.length()) + : uri; + return trimmedUri.startsWith("/login") + || trimmedUri.startsWith("/oauth") + || trimmedUri.startsWith("/saml2") + || trimmedUri.endsWith(".svg") + || trimmedUri.startsWith("/register") + || trimmedUri.startsWith("/error") + || trimmedUri.startsWith("/images/") + || trimmedUri.startsWith("/public/") + || trimmedUri.startsWith("/css/") + || trimmedUri.startsWith("/fonts/") + || trimmedUri.startsWith("/js/") + || trimmedUri.startsWith( + "/api/v1/info/status"); + }) + .permitAll() + .anyRequest() + .authenticated()); // Handle User/Password Logins if (applicationProperties.getSecurity().isUserPass()) { http.formLogin( - formLogin -> - formLogin - .loginPage("/login") - .successHandler( - new CustomAuthenticationSuccessHandler( - loginAttemptService, userService)) - .failureHandler( - new CustomAuthenticationFailureHandler( - loginAttemptService, userService)) - .defaultSuccessUrl("/") - .permitAll()); + formLogin -> + formLogin + .loginPage("/login") + .successHandler( + new CustomAuthenticationSuccessHandler( + loginAttemptService, userService)) + .failureHandler( + new CustomAuthenticationFailureHandler( + loginAttemptService, userService)) + .defaultSuccessUrl("/") + .permitAll()); } // Handle OAUTH2 Logins if (applicationProperties.getSecurity().isOauth2Active()) { http.oauth2Login( - oauth2 -> - oauth2.loginPage("/oauth2") - /* - This Custom handler is used to check if the OAUTH2 user trying to log in, already exists in the database. - If user exists, login proceeds as usual. If user does not exist, then it is auto-created but only if 'OAUTH2AutoCreateUser' - is set as true, else login fails with an error message advising the same. - */ - .successHandler( - new CustomOAuth2AuthenticationSuccessHandler( - loginAttemptService, - applicationProperties, - userService)) - .failureHandler( - new CustomOAuth2AuthenticationFailureHandler()) - . // Add existing Authorities from the database - userInfoEndpoint( - userInfoEndpoint -> - userInfoEndpoint - .oidcUserService( - new CustomOAuth2UserService( - applicationProperties, - userService, - loginAttemptService)) - .userAuthoritiesMapper( - oAuth2userAuthoritiesMapper)) - .permitAll()); + oauth2 -> + oauth2.loginPage("/oauth2") + /* + This Custom handler is used to check if the OAUTH2 user trying to log in, already exists in the database. + If user exists, login proceeds as usual. If user does not exist, then it is auto-created but only if 'OAUTH2AutoCreateUser' + is set as true, else login fails with an error message advising the same. + */ + .successHandler( + new CustomOAuth2AuthenticationSuccessHandler( + loginAttemptService, + applicationProperties, + userService)) + .failureHandler( + new CustomOAuth2AuthenticationFailureHandler()) + . // Add existing Authorities from the database + userInfoEndpoint( + userInfoEndpoint -> + userInfoEndpoint + .oidcUserService( + new CustomOAuth2UserService( + applicationProperties, + userService, + loginAttemptService)) + .userAuthoritiesMapper( + oAuth2userAuthoritiesMapper)) + .permitAll()); } // Handle SAML if (applicationProperties.getSecurity().isSaml2Active() && runningProOrHigher) { // Configure the authentication provider OpenSaml4AuthenticationProvider authenticationProvider = - new OpenSaml4AuthenticationProvider(); + new OpenSaml4AuthenticationProvider(); authenticationProvider.setResponseAuthenticationConverter( - new CustomSaml2ResponseAuthenticationConverter(userService)); + new CustomSaml2ResponseAuthenticationConverter(userService)); http.authenticationProvider(authenticationProvider) - .saml2Login( - saml2 -> { - try { - saml2.loginPage("/saml2") - .relyingPartyRegistrationRepository( - saml2RelyingPartyRegistrations) - .authenticationManager( - new ProviderManager(authenticationProvider)) - .successHandler( - new CustomSaml2AuthenticationSuccessHandler( - loginAttemptService, - applicationProperties, - userService)) - .failureHandler( - new CustomSaml2AuthenticationFailureHandler()) - .authenticationRequestResolver( - saml2AuthenticationRequestResolver); - } catch (Exception e) { - log.error("Error configuring SAML 2 login", e); - throw new RuntimeException(e); - } - }); + .saml2Login( + saml2 -> { + try { + saml2.loginPage("/saml2") + .relyingPartyRegistrationRepository( + saml2RelyingPartyRegistrations) + .authenticationManager( + new ProviderManager(authenticationProvider)) + .successHandler( + new CustomSaml2AuthenticationSuccessHandler( + loginAttemptService, + applicationProperties, + userService)) + .failureHandler( + new CustomSaml2AuthenticationFailureHandler()) + .authenticationRequestResolver( + saml2AuthenticationRequestResolver); + } catch (Exception e) { + log.error("Error configuring SAML 2 login", e); + throw new RuntimeException(e); + } + }); } } else { log.debug("Login is not enabled."); diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/DatabaseController.java b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/DatabaseController.java index bbc84821f..dec64c46f 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/DatabaseController.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/DatabaseController.java @@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; + import stirling.software.proprietary.security.database.H2SQLCondition; import stirling.software.proprietary.security.service.DatabaseService; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/UserController.java b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/UserController.java index dec5905ba..e1abb6989 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/UserController.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/UserController.java @@ -29,11 +29,11 @@ import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import stirling.software.proprietary.security.model.AuthenticationType; -import stirling.software.common.model.enumeration.Role; -import stirling.software.proprietary.security.model.User; import stirling.software.common.model.ApplicationProperties; +import stirling.software.common.model.enumeration.Role; import stirling.software.common.model.exception.UnsupportedProviderException; +import stirling.software.proprietary.security.model.AuthenticationType; +import stirling.software.proprietary.security.model.User; import stirling.software.proprietary.security.model.api.user.UsernameAndPass; import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; import stirling.software.proprietary.security.service.UserService; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/AccountWebController.java b/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/AccountWebController.java index 311f81a4f..bdf1df32e 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/AccountWebController.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/AccountWebController.java @@ -29,12 +29,12 @@ import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; -import stirling.software.common.model.enumeration.Role; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2.Client; import stirling.software.common.model.ApplicationProperties.Security.SAML2; +import stirling.software.common.model.enumeration.Role; import stirling.software.common.model.oauth2.GitHubProvider; import stirling.software.common.model.oauth2.GoogleProvider; import stirling.software.common.model.oauth2.KeycloakProvider; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/database/ScheduledTasks.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/ScheduledTasks.java index 835dc1917..6821414aa 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/database/ScheduledTasks.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/ScheduledTasks.java @@ -1,10 +1,13 @@ package stirling.software.proprietary.security.database; import java.sql.SQLException; -import lombok.RequiredArgsConstructor; + import org.springframework.context.annotation.Conditional; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; + import stirling.software.common.model.exception.UnsupportedProviderException; import stirling.software.proprietary.security.service.DatabaseServiceInterface; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/AuthorityRepository.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/AuthorityRepository.java index a7773d859..e8d74ec01 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/AuthorityRepository.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/AuthorityRepository.java @@ -4,6 +4,7 @@ import java.util.Set; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; + import stirling.software.proprietary.security.model.Authority; @Repository diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/JPATokenRepositoryImpl.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/JPATokenRepositoryImpl.java index b98a8094f..ec7a0078b 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/JPATokenRepositoryImpl.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/JPATokenRepositoryImpl.java @@ -5,6 +5,7 @@ import java.util.Date; import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.transaction.annotation.Transactional; + import stirling.software.proprietary.security.model.PersistentLogin; public class JPATokenRepositoryImpl implements PersistentTokenRepository { diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/PersistentLoginRepository.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/PersistentLoginRepository.java index a9ddf8a37..2ab956676 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/PersistentLoginRepository.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/PersistentLoginRepository.java @@ -2,6 +2,7 @@ package stirling.software.proprietary.security.database.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; + import stirling.software.proprietary.security.model.PersistentLogin; @Repository diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/SessionRepository.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/SessionRepository.java index b7a7d7a84..78206b259 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/SessionRepository.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/SessionRepository.java @@ -1,13 +1,16 @@ package stirling.software.proprietary.security.database.repository; -import jakarta.transaction.Transactional; import java.util.Date; import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; + +import jakarta.transaction.Transactional; + import stirling.software.proprietary.security.model.SessionEntity; @Repository diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/UserRepository.java b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/UserRepository.java index dcf84ee19..2a8d42096 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/UserRepository.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/database/repository/UserRepository.java @@ -7,6 +7,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; + import stirling.software.proprietary.security.model.User; @Repository diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/filter/FirstLoginFilter.java b/proprietary/src/main/java/stirling/software/proprietary/security/filter/FirstLoginFilter.java index a96e6e769..3bae72195 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/filter/FirstLoginFilter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/filter/FirstLoginFilter.java @@ -1,20 +1,24 @@ package stirling.software.proprietary.security.filter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Optional; + +import org.springframework.context.annotation.Lazy; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Optional; + import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Lazy; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; + import stirling.software.common.util.RequestUriUtils; import stirling.software.proprietary.security.model.User; import stirling.software.proprietary.security.service.UserService; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/filter/IPRateLimitingFilter.java b/proprietary/src/main/java/stirling/software/proprietary/security/filter/IPRateLimitingFilter.java index ebc0f949e..028768c08 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/filter/IPRateLimitingFilter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/filter/IPRateLimitingFilter.java @@ -1,15 +1,18 @@ package stirling.software.proprietary.security.filter; +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import jakarta.servlet.http.HttpServletRequest; -import java.io.IOException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; + import lombok.RequiredArgsConstructor; + import stirling.software.common.util.RequestUriUtils; @RequiredArgsConstructor diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserAuthenticationFilter.java b/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserAuthenticationFilter.java index de97ec785..e9addd239 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserAuthenticationFilter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserAuthenticationFilter.java @@ -1,13 +1,9 @@ package stirling.software.proprietary.security.filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; import java.util.Optional; -import lombok.extern.slf4j.Slf4j; + import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpStatus; @@ -20,6 +16,14 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.ApplicationProperties.Security.SAML2; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserBasedRateLimitingFilter.java b/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserBasedRateLimitingFilter.java index 31db979b0..4d1d7bbed 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserBasedRateLimitingFilter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/filter/UserBasedRateLimitingFilter.java @@ -1,17 +1,10 @@ package stirling.software.proprietary.security.filter; -import io.github.bucket4j.Bandwidth; -import io.github.bucket4j.Bucket; -import io.github.bucket4j.ConsumptionProbe; -import io.github.pixee.security.Newlines; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.Duration; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; + import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; @@ -20,6 +13,17 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; + +import io.github.bucket4j.Bandwidth; +import io.github.bucket4j.Bucket; +import io.github.bucket4j.ConsumptionProbe; +import io.github.pixee.security.Newlines; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + import stirling.software.common.model.enumeration.Role; @Component diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java index 6dc32a85d..b364f3738 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java @@ -14,6 +14,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; + import stirling.software.common.model.enumeration.Role; @Entity diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/api/Email.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/Email.java index 8fe3cebe6..4e9421aba 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/model/api/Email.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/api/Email.java @@ -7,6 +7,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; + import stirling.software.common.model.api.GeneralFile; @Data diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java index 92b053b8a..7175a5b5d 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java @@ -1,10 +1,7 @@ package stirling.software.proprietary.security.oauth2; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import lombok.extern.slf4j.Slf4j; + import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.DisabledException; import org.springframework.security.authentication.LockedException; @@ -13,6 +10,12 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2Error; 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; + @Slf4j public class CustomOAuth2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java index 1c4d04e55..71bd42a85 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationSuccessHandler.java @@ -1,18 +1,22 @@ package stirling.software.proprietary.security.oauth2; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.sql.SQLException; -import lombok.RequiredArgsConstructor; + import org.springframework.security.authentication.LockedException; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.savedrequest.SavedRequest; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + +import lombok.RequiredArgsConstructor; + import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.exception.UnsupportedProviderException; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java index cb2771cc0..6516cc7d7 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java @@ -1,13 +1,16 @@ package stirling.software.proprietary.security.oauth2; +import static org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE; +import static stirling.software.common.util.ProviderUtils.validateProvider; +import static stirling.software.common.util.ValidationUtils.isStringEmpty; + import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; -import lombok.extern.slf4j.Slf4j; + import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -20,20 +23,20 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio import org.springframework.security.oauth2.client.registration.ClientRegistrations; import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; + +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2.Client; import stirling.software.common.model.enumeration.UsernameAttribute; -import stirling.software.proprietary.security.model.exception.NoProviderFoundException; import stirling.software.common.model.oauth2.GitHubProvider; import stirling.software.common.model.oauth2.GoogleProvider; import stirling.software.common.model.oauth2.KeycloakProvider; import stirling.software.common.model.oauth2.Provider; import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.model.exception.NoProviderFoundException; import stirling.software.proprietary.security.service.UserService; -import static org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE; -import static stirling.software.common.util.ProviderUtils.validateProvider; -import static stirling.software.common.util.ValidationUtils.isStringEmpty; @Slf4j @Configuration diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java index c2957e241..fff03fd4f 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java @@ -6,6 +6,7 @@ import java.nio.charset.StandardCharsets; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; + import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java index 055ac8f4e..a39a39092 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java @@ -3,6 +3,7 @@ package stirling.software.proprietary.security.saml2; import java.io.Serializable; import java.util.List; import java.util.Map; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java index a7e663aac..7bf0c3a3b 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java @@ -1,9 +1,7 @@ package stirling.software.proprietary.security.saml2; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import lombok.extern.slf4j.Slf4j; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.authentication.ProviderNotFoundException; import org.springframework.security.core.AuthenticationException; @@ -11,6 +9,11 @@ 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.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import lombok.extern.slf4j.Slf4j; + @Slf4j @ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true") public class CustomSaml2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationSuccessHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationSuccessHandler.java index 47391e4d0..2170a9632 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationSuccessHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationSuccessHandler.java @@ -1,17 +1,21 @@ package stirling.software.proprietary.security.saml2; +import java.io.IOException; +import java.sql.SQLException; + +import org.springframework.security.authentication.LockedException; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; +import org.springframework.security.web.savedrequest.SavedRequest; + import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; -import java.io.IOException; -import java.sql.SQLException; + import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.security.authentication.LockedException; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import org.springframework.security.web.savedrequest.SavedRequest; + import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.SAML2; import stirling.software.common.model.exception.UnsupportedProviderException; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2ResponseAuthenticationConverter.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2ResponseAuthenticationConverter.java index d1c24b420..e8326c1e3 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2ResponseAuthenticationConverter.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2ResponseAuthenticationConverter.java @@ -5,8 +5,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; + import org.opensaml.core.xml.XMLObject; import org.opensaml.saml.saml2.core.Assertion; import org.opensaml.saml.saml2.core.Attribute; @@ -17,6 +16,10 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.ResponseToken; import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + import stirling.software.proprietary.security.model.User; import stirling.software.proprietary.security.service.UserService; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java index 836419ea0..233bcaadd 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java @@ -1,11 +1,9 @@ package stirling.software.proprietary.security.saml2; -import jakarta.servlet.http.HttpServletRequest; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.UUID; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; + import org.opensaml.saml.saml2.core.AuthnRequest; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -21,6 +19,12 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository; import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; + +import jakarta.servlet.http.HttpServletRequest; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.SAML2; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/service/AppUpdateAuthService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/AppUpdateAuthService.java index 5687a3b92..19e300585 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/service/AppUpdateAuthService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/AppUpdateAuthService.java @@ -1,10 +1,13 @@ package stirling.software.proprietary.security.service; import java.util.Optional; -import lombok.RequiredArgsConstructor; + import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; + import stirling.software.common.configuration.interfaces.ShowAdminInterface; import stirling.software.common.model.ApplicationProperties; import stirling.software.proprietary.security.database.repository.UserRepository; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomOAuth2UserService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomOAuth2UserService.java index b889a06e5..0b286e894 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomOAuth2UserService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomOAuth2UserService.java @@ -1,7 +1,7 @@ package stirling.software.proprietary.security.service; import java.util.Optional; -import lombok.extern.slf4j.Slf4j; + import org.springframework.security.authentication.LockedException; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; @@ -10,6 +10,9 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.security.oauth2.core.oidc.user.OidcUser; + +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; import stirling.software.common.model.enumeration.UsernameAttribute; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java index 014666971..6ece48a4e 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java @@ -2,7 +2,7 @@ package stirling.software.proprietary.security.service; import java.util.Collection; import java.util.Set; -import lombok.RequiredArgsConstructor; + import org.springframework.security.authentication.LockedException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -10,6 +10,9 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; + import stirling.software.proprietary.security.database.repository.UserRepository; import stirling.software.proprietary.security.model.Authority; import stirling.software.proprietary.security.model.User; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseService.java index 37de87cf4..6474ae7ea 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/DatabaseService.java @@ -18,11 +18,15 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; + import javax.sql.DataSource; -import lombok.extern.slf4j.Slf4j; + import org.springframework.jdbc.datasource.init.CannotReadScriptException; import org.springframework.jdbc.datasource.init.ScriptException; import org.springframework.stereotype.Service; + +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.configuration.InstallationPathConfig; import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.FileInfo; @@ -235,27 +239,27 @@ public class DatabaseService implements DatabaseServiceInterface { private boolean isH2Database() { boolean isTypeH2 = - datasourceProps.getType().equalsIgnoreCase(ApplicationProperties.Driver.H2.name()); + datasourceProps.getType().equalsIgnoreCase(ApplicationProperties.Driver.H2.name()); boolean isDBUrlH2 = - datasourceProps.getCustomDatabaseUrl().contains("h2") - || datasourceProps.getCustomDatabaseUrl().contains("H2"); + datasourceProps.getCustomDatabaseUrl().contains("h2") + || datasourceProps.getCustomDatabaseUrl().contains("H2"); boolean isCustomDatabase = datasourceProps.isEnableCustomDatabase(); if (isCustomDatabase) { if (isTypeH2 && !isDBUrlH2) { log.warn( - "Datasource type is H2, but the URL does not contain 'h2'. " - + "Please check your configuration."); + "Datasource type is H2, but the URL does not contain 'h2'. " + + "Please check your configuration."); throw new IllegalStateException( - "Datasource type is H2, but the URL does not contain 'h2'. Please check" - + " your configuration."); + "Datasource type is H2, but the URL does not contain 'h2'. Please check" + + " your configuration."); } else if (!isTypeH2 && isDBUrlH2) { log.warn( - "Datasource URL contains 'h2', but the type is not H2. " - + "Please check your configuration."); + "Datasource URL contains 'h2', but the type is not H2. " + + "Please check your configuration."); throw new IllegalStateException( - "Datasource URL contains 'h2', but the type is not H2. Please check your" - + " configuration."); + "Datasource URL contains 'h2', but the type is not H2. Please check your" + + " configuration."); } } boolean isH2 = isTypeH2 && isDBUrlH2; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/service/LoginAttemptService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/LoginAttemptService.java index 852fc8ab9..ecc04bac5 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/service/LoginAttemptService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/LoginAttemptService.java @@ -1,11 +1,15 @@ package stirling.software.proprietary.security.service; -import jakarta.annotation.PostConstruct; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; + +import org.springframework.stereotype.Service; + +import jakarta.annotation.PostConstruct; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; + import stirling.software.common.model.ApplicationProperties; import stirling.software.proprietary.security.model.AttemptCounter; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/service/UserService.java b/proprietary/src/main/java/stirling/software/proprietary/security/service/UserService.java index 7bf3e2643..0823f748b 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/service/UserService.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/service/UserService.java @@ -1,6 +1,5 @@ package stirling.software.proprietary.security.service; -import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; @@ -9,8 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; + import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -25,10 +23,14 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.model.ApplicationProperties; +import stirling.software.common.model.enumeration.Role; import stirling.software.common.model.exception.UnsupportedProviderException; import stirling.software.common.service.UserServiceInterface; -import stirling.software.common.model.enumeration.Role; import stirling.software.proprietary.security.database.repository.AuthorityRepository; import stirling.software.proprietary.security.database.repository.UserRepository; import stirling.software.proprietary.security.model.AuthenticationType; @@ -84,7 +86,7 @@ public class UserService implements UserServiceInterface { public Authentication getAuthentication(String apiKey) { Optional user = getUserByApiKey(apiKey); - if (!user.isPresent()) { + if (user.isEmpty()) { throw new UsernameNotFoundException("API key is not valid"); } // Convert the user into an Authentication object @@ -301,9 +303,7 @@ public class UserService implements UserServiceInterface { } public void changeUsername(User user, String newUsername) - throws IllegalArgumentException, - SQLException, - UnsupportedProviderException { + throws IllegalArgumentException, SQLException, UnsupportedProviderException { if (!isUsernameValid(newUsername)) { throw new IllegalArgumentException(getInvalidUsernameMessage()); } diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/session/CustomHttpSessionListener.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/CustomHttpSessionListener.java index 7ed0f6506..b69dfaefb 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/session/CustomHttpSessionListener.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/CustomHttpSessionListener.java @@ -1,15 +1,17 @@ package stirling.software.proprietary.security.session; +import org.springframework.stereotype.Component; + import jakarta.servlet.http.HttpSessionEvent; import jakarta.servlet.http.HttpSessionListener; + import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; @Component @Slf4j public class CustomHttpSessionListener implements HttpSessionListener { - private SessionPersistentRegistry sessionPersistentRegistry; + private final SessionPersistentRegistry sessionPersistentRegistry; public CustomHttpSessionListener(SessionPersistentRegistry sessionPersistentRegistry) { super(); diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionPersistentRegistry.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionPersistentRegistry.java index 5d482e94d..8931866ad 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionPersistentRegistry.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionPersistentRegistry.java @@ -1,6 +1,5 @@ package stirling.software.proprietary.security.session; -import jakarta.transaction.Transactional; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; @@ -8,13 +7,18 @@ import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Optional; -import lombok.RequiredArgsConstructor; + import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.session.SessionInformation; import org.springframework.security.core.session.SessionRegistry; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Component; + +import jakarta.transaction.Transactional; + +import lombok.RequiredArgsConstructor; + import stirling.software.proprietary.security.database.repository.SessionRepository; import stirling.software.proprietary.security.model.SessionEntity; import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java index 75afbea9b..eccd7332e 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java @@ -3,6 +3,7 @@ package stirling.software.proprietary.security.session; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.session.SessionRegistryImpl; + import stirling.software.proprietary.security.database.repository.SessionRepository; @Configuration @@ -14,7 +15,8 @@ public class SessionRegistryConfig { } @Bean - public SessionPersistentRegistry sessionPersistentRegistry(SessionRepository sessionRepository) { + public SessionPersistentRegistry sessionPersistentRegistry( + SessionRepository sessionRepository) { return new SessionPersistentRegistry(sessionRepository); } } diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java index 83403f9f7..1f491bf4d 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java @@ -4,11 +4,13 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.List; -import lombok.RequiredArgsConstructor; + import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.core.session.SessionInformation; import org.springframework.stereotype.Component; +import lombok.RequiredArgsConstructor; + @Component @RequiredArgsConstructor public class SessionScheduled { diff --git a/scripts/download-security-jar.sh b/scripts/download-security-jar.sh index 8216179fa..bee188d97 100644 --- a/scripts/download-security-jar.sh +++ b/scripts/download-security-jar.sh @@ -1,6 +1,6 @@ echo "Running Stirling PDF with ADDITIONAL_FEATURES_OFF=${ADDITIONAL_FEATURES_OFF} and VERSION_TAG=${VERSION_TAG}" -# Check for DOCKER_ENABLE_SECURITY and download the appropriate JAR if required -if [ "$DOCKER_ENABLE_SECURITY" = "true" ] || [ "$ADDITIONAL_FEATURES_OFF" = "false" ] && [ "$VERSION_TAG" != "alpha" ]; then +# Check for $ADDITIONAL_FEATURES_OFF and download the appropriate JAR if required +if [ "$ADDITIONAL_FEATURES_OFF" = "false" ] && [ "$VERSION_TAG" != "alpha" ]; then if [ ! -f app-security.jar ]; then echo "Trying to download from: https://files.stirlingpdf.com/v$VERSION_TAG/Stirling-PDF-with-login.jar" curl -L -o app-security.jar https://files.stirlingpdf.com/v$VERSION_TAG/Stirling-PDF-with-login.jar diff --git a/testing/test.sh b/testing/test.sh index f1169ec17..0891c6bbd 100644 --- a/testing/test.sh +++ b/testing/test.sh @@ -214,7 +214,6 @@ main() { export DOCKER_CLI_EXPERIMENTAL=enabled export COMPOSE_DOCKER_CLI_BUILD=0 - export DOCKER_ENABLE_SECURITY=false export ADDITIONAL_FEATURES_OFF=true # Run the gradlew build command and check if it fails if ! ./gradlew clean build; then @@ -243,7 +242,6 @@ main() { # run_tests "Stirling-PDF" "./exampleYmlFiles/docker-compose-latest.yml" # docker-compose -f "./exampleYmlFiles/docker-compose-latest.yml" down - export DOCKER_ENABLE_SECURITY=true export ADDITIONAL_FEATURES_OFF=false # Run the gradlew build command and check if it fails if ! ./gradlew clean build; then From febe67eac8af66cc9a7001fe28d5ccac611913f4 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Fri, 9 May 2025 16:48:48 +0100 Subject: [PATCH 11/15] moving security package and relevant files over to proprietary --- LICENSE | 7 + .../gradle/wrapper/gradle-wrapper.properties | 6 + common/gradlew | 251 ++++++++++++++++++ common/gradlew.bat | 94 +++++++ .../gradle/wrapper/gradle-wrapper.properties | 6 + proprietary/gradlew | 251 ++++++++++++++++++ proprietary/gradlew.bat | 94 +++++++ .../security/configuration/MailConfig.java | 1 - .../proprietary/security/model/User.java | 1 + ...tomOAuth2AuthenticationFailureHandler.java | 11 +- .../security/saml2/CertificateUtils.java | 1 - .../CustomSaml2AuthenticatedPrincipal.java | 1 - ...stomSaml2AuthenticationFailureHandler.java | 9 +- .../security/saml2/SAML2Configuration.java | 10 +- .../session/SessionRegistryConfig.java | 4 +- .../security/session/SessionScheduled.java | 4 +- 16 files changed, 723 insertions(+), 28 deletions(-) create mode 100644 common/gradle/wrapper/gradle-wrapper.properties create mode 100755 common/gradlew create mode 100644 common/gradlew.bat create mode 100644 proprietary/gradle/wrapper/gradle-wrapper.properties create mode 100755 proprietary/gradlew create mode 100644 proprietary/gradlew.bat diff --git a/LICENSE b/LICENSE index 877663171..62cd6e5cc 100644 --- a/LICENSE +++ b/LICENSE @@ -9,6 +9,13 @@ if that directory exists, is licensed under the license defined in "proprietary/ * Content outside of the above mentioned directories or restrictions above is available under the MIT License as defined below. +Portions of this software are licensed as follows: + +* All content that resides under the "proprietary/" directory of this repository, +if that directory exists, is licensed under the license defined in "proprietary/LICENSE". +* Content outside of the above mentioned directories or restrictions above is +available under the MIT License as defined below. + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff --git a/common/gradle/wrapper/gradle-wrapper.properties b/common/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..f7664bccf --- /dev/null +++ b/common/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/common/gradlew b/common/gradlew new file mode 100755 index 000000000..23d15a936 --- /dev/null +++ b/common/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/common/gradlew.bat b/common/gradlew.bat new file mode 100644 index 000000000..db3a6ac20 --- /dev/null +++ b/common/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/proprietary/gradle/wrapper/gradle-wrapper.properties b/proprietary/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..f7664bccf --- /dev/null +++ b/proprietary/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/proprietary/gradlew b/proprietary/gradlew new file mode 100755 index 000000000..23d15a936 --- /dev/null +++ b/proprietary/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/proprietary/gradlew.bat b/proprietary/gradlew.bat new file mode 100644 index 000000000..db3a6ac20 --- /dev/null +++ b/proprietary/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java index c9b6e9d77..82d794d6e 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java @@ -10,7 +10,6 @@ import org.springframework.mail.javamail.JavaMailSenderImpl; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; - import stirling.software.common.model.ApplicationProperties; /** diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java index b364f3738..0fd356da2 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java @@ -14,6 +14,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; +import stirling.software.common.model.enumeration.Role; import stirling.software.common.model.enumeration.Role; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java index 7175a5b5d..92b053b8a 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java @@ -1,7 +1,10 @@ package stirling.software.proprietary.security.oauth2; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; - +import lombok.extern.slf4j.Slf4j; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.DisabledException; import org.springframework.security.authentication.LockedException; @@ -10,12 +13,6 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2Error; 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; - @Slf4j public class CustomOAuth2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java index fff03fd4f..c2957e241 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java @@ -6,7 +6,6 @@ import java.nio.charset.StandardCharsets; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; - import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java index a39a39092..055ac8f4e 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java @@ -3,7 +3,6 @@ package stirling.software.proprietary.security.saml2; import java.io.Serializable; import java.util.List; import java.util.Map; - import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java index 7bf0c3a3b..a7e663aac 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java @@ -1,7 +1,9 @@ package stirling.software.proprietary.security.saml2; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; - +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.authentication.ProviderNotFoundException; import org.springframework.security.core.AuthenticationException; @@ -9,11 +11,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.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import lombok.extern.slf4j.Slf4j; - @Slf4j @ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true") public class CustomSaml2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java index 233bcaadd..836419ea0 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java @@ -1,9 +1,11 @@ package stirling.software.proprietary.security.saml2; +import jakarta.servlet.http.HttpServletRequest; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.UUID; - +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.opensaml.saml.saml2.core.AuthnRequest; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -19,12 +21,6 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository; import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; - -import jakarta.servlet.http.HttpServletRequest; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.SAML2; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java index eccd7332e..6c1d334f5 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java @@ -3,6 +3,7 @@ package stirling.software.proprietary.security.session; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.session.SessionRegistryImpl; +import stirling.software.proprietary.security.database.repository.SessionRepository; import stirling.software.proprietary.security.database.repository.SessionRepository; @@ -15,8 +16,7 @@ public class SessionRegistryConfig { } @Bean - public SessionPersistentRegistry sessionPersistentRegistry( - SessionRepository sessionRepository) { + public SessionPersistentRegistry sessionPersistentRegistry(SessionRepository sessionRepository) { return new SessionPersistentRegistry(sessionRepository); } } diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java index 1f491bf4d..83403f9f7 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java @@ -4,13 +4,11 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.List; - +import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.core.session.SessionInformation; import org.springframework.stereotype.Component; -import lombok.RequiredArgsConstructor; - @Component @RequiredArgsConstructor public class SessionScheduled { From a0cb56ab0c9d9ebb3da400b48129b81ef6a1a14f Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Tue, 3 Jun 2025 17:15:50 +0100 Subject: [PATCH 12/15] correcting security logic This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made: - Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`. - Ensured consistency and synchronization across all supported language files. - Highlighted any missing or incomplete translations. - Generated the translation progress table in `README.md`. - Added a summary of the current translation status for all supported languages. - Included up-to-date statistics on translation coverage. - Keeps translation files aligned with the latest reference updates. - Ensures the documentation reflects the current translation progress. --- Auto-generated by [create-pull-request][1]. [1]: https://github.com/peter-evans/create-pull-request Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com> Update messages_de_DE.properties (#3618) Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --- - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] My changes generate no new warnings - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Fix error display for Split by Chapter (#3621) - throw `IllegalArgumentException` when bookmark level is invalid or when a PDF has no outline - rely on global error handling so frontend shows the message - `./gradlew build` ------ https://chatgpt.com/codex/tasks/task_b_683dc51dd31083288be3f9892889fa59 :globe_with_meridians: Sync Translations + Update README Progress Table (#3638) This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made: - Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`. - Ensured consistency and synchronization across all supported language files. - Highlighted any missing or incomplete translations. - Generated the translation progress table in `README.md`. - Added a summary of the current translation status for all supported languages. - Included up-to-date statistics on translation coverage. - Keeps translation files aligned with the latest reference updates. - Ensures the documentation reflects the current translation progress. --- Auto-generated by [create-pull-request][1]. [1]: https://github.com/peter-evans/create-pull-request Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com> GetInfo summary #2388 (#3585) Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --- - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. Co-authored-by: a :globe_with_meridians: Sync Translations + Update README Progress Table (#3639) This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made: - Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`. - Ensured consistency and synchronization across all supported language files. - Highlighted any missing or incomplete translations. - Generated the translation progress table in `README.md`. - Added a summary of the current translation status for all supported languages. - Included up-to-date statistics on translation coverage. - Keeps translation files aligned with the latest reference updates. - Ensures the documentation reflects the current translation progress. --- Auto-generated by [create-pull-request][1]. [1]: https://github.com/peter-evans/create-pull-request --------- Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com> clean up :globe_with_meridians: Sync Translations + Update README Progress Table (#3639) This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made: - Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`. - Ensured consistency and synchronization across all supported language files. - Highlighted any missing or incomplete translations. - Generated the translation progress table in `README.md`. - Added a summary of the current translation status for all supported languages. - Included up-to-date statistics on translation coverage. - Keeps translation files aligned with the latest reference updates. - Ensures the documentation reflects the current translation progress. --- Auto-generated by [create-pull-request][1]. [1]: https://github.com/peter-evans/create-pull-request --------- Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com> ADDITIONAL_FEATURES_OFF > ADDITIONAL_FEATURES renamed flag renamed flag in workflows --- .../workflows/PR-Demo-Comment-with-react.yml | 16 +- .github/workflows/build.yml | 4 +- .github/workflows/multiOSReleases.yml | 21 +- .github/workflows/push-docker.yml | 2 +- .github/workflows/releaseArtifacts.yml | 25 +- .github/workflows/sonarqube.yml | 2 +- .github/workflows/testdriver.yml | 4 +- DeveloperGuide.md | 8 +- Dockerfile | 2 +- Dockerfile.fat | 6 +- Dockerfile.ultra-lite | 2 +- build.gradle | 22 +- .../gradle/wrapper/gradle-wrapper.properties | 6 - common/gradlew | 251 ------------------ common/gradlew.bat | 94 ------- .../common/configuration/AppConfig.java | 12 +- ...-compose-latest-fat-endpoints-disabled.yml | 2 +- ...r-compose-latest-fat-security-postgres.yml | 2 +- .../docker-compose-latest-fat-security.yml | 2 +- ...ocker-compose-latest-security-with-sso.yml | 2 +- .../docker-compose-latest-security.yml | 2 +- ...ker-compose-latest-ultra-lite-security.yml | 2 +- .../docker-compose-latest-ultra-lite.yml | 2 +- exampleYmlFiles/docker-compose-latest.yml | 2 +- exampleYmlFiles/test_cicd.yml | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 6 - proprietary/gradlew | 251 ------------------ proprietary/gradlew.bat | 94 ------- .../security/configuration/MailConfig.java | 1 + .../proprietary/security/model/User.java | 1 - ...tomOAuth2AuthenticationFailureHandler.java | 11 +- .../security/saml2/CertificateUtils.java | 1 + .../CustomSaml2AuthenticatedPrincipal.java | 1 + ...stomSaml2AuthenticationFailureHandler.java | 9 +- .../security/saml2/SAML2Configuration.java | 10 +- .../session/SessionRegistryConfig.java | 4 +- .../security/session/SessionScheduled.java | 4 +- scripts/download-security-jar.sh | 6 +- testing/test.sh | 4 +- 39 files changed, 103 insertions(+), 795 deletions(-) delete mode 100644 common/gradle/wrapper/gradle-wrapper.properties delete mode 100755 common/gradlew delete mode 100644 common/gradlew.bat delete mode 100644 proprietary/gradle/wrapper/gradle-wrapper.properties delete mode 100755 proprietary/gradlew delete mode 100644 proprietary/gradlew.bat diff --git a/.github/workflows/PR-Demo-Comment-with-react.yml b/.github/workflows/PR-Demo-Comment-with-react.yml index 786316365..e9dcc3d8b 100644 --- a/.github/workflows/PR-Demo-Comment-with-react.yml +++ b/.github/workflows/PR-Demo-Comment-with-react.yml @@ -37,7 +37,7 @@ jobs: pr_repository: ${{ steps.get-pr-info.outputs.repository }} pr_ref: ${{ steps.get-pr-info.outputs.ref }} comment_id: ${{ github.event.comment.id }} - enable_security: ${{ steps.check-security-flag.outputs.enable_security }} + disable_security: ${{ steps.check-security-flag.outputs.disable_security }} steps: - name: Harden Runner @@ -92,10 +92,10 @@ jobs: run: | if [[ "$COMMENT_BODY" == *"security"* ]] || [[ "$COMMENT_BODY" == *"login"* ]]; then echo "Security flags detected in comment" - echo "enable_security=true" >> $GITHUB_OUTPUT + echo "disable_security=false" >> $GITHUB_OUTPUT else echo "No security flags detected in comment" - echo "enable_security=false" >> $GITHUB_OUTPUT + echo "disable_security=true" >> $GITHUB_OUTPUT fi - name: Add 'in_progress' reaction to comment @@ -155,10 +155,10 @@ jobs: - name: Run Gradle Command run: | - if [ "${{ needs.check-comment.outputs.enable_security }}" == "true" ]; then - export ADDITIONAL_FEATURES_OFF=false + if [ "${{ needs.check-comment.outputs.disable_security }}" == "true" ]; then + export DISABLE_ADDITIONAL_FEATURES=true else - export ADDITIONAL_FEATURES_OFF=true + export DISABLE_ADDITIONAL_FEATURES=false fi ./gradlew clean build env: @@ -199,7 +199,7 @@ jobs: id: deploy run: | # Set security settings based on flags - if [ "${{ needs.check-comment.outputs.enable_security }}" == "true" ]; then + if [ "${{ needs.check-comment.outputs.disable_security }}" == "false" ]; then DOCKER_SECURITY="true" LOGIN_SECURITY="true" SECURITY_STATUS="🔒 Security Enabled" @@ -223,7 +223,7 @@ jobs: - /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/config:/configs:rw - /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "${DOCKER_SECURITY}" + DISABLE_ADDITIONAL_FEATURES: "${DOCKER_SECURITY}" SECURITY_ENABLELOGIN: "${LOGIN_SECURITY}" SYSTEM_DEFAULTLOCALE: en-GB UI_APPNAME: "Stirling-PDF PR#${{ needs.check-comment.outputs.pr_number }}" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 797a1bca0..7274c568b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,12 +40,12 @@ jobs: - name: Build with Gradle and no spring security run: ./gradlew clean build env: - ADDITIONAL_FEATURES_OFF: true + DISABLE_ADDITIONAL_FEATURES: true - name: Build with Gradle and with spring security run: ./gradlew clean build env: - ADDITIONAL_FEATURES_OFF: false + DISABLE_ADDITIONAL_FEATURES: false - name: Upload Test Reports if: always() diff --git a/.github/workflows/multiOSReleases.yml b/.github/workflows/multiOSReleases.yml index d10d8e8b6..c934b7129 100644 --- a/.github/workflows/multiOSReleases.yml +++ b/.github/workflows/multiOSReleases.yml @@ -48,17 +48,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - enable_security: [true, false] disable_security: [true, false] include: - - enable_security: true - file_suffix: "-with-login" - - enable_security: false - file_suffix: "" - - disable_security: true - file_suffix: "" - disable_security: false file_suffix: "-with-login" + - disable_security: true + file_suffix: "" steps: - name: Harden Runner uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 @@ -77,10 +72,10 @@ jobs: with: gradle-version: 8.14 - - name: Generate jar (With Security=${{ matrix.enable_security }}) + - name: Generate jar (Disable Security=${{ matrix.disable_security }}) run: ./gradlew clean createExe env: - ADDITIONAL_FEATURES_OFF: ${{ matrix.disable_security }} + DISABLE_ADDITIONAL_FEATURES: ${{ matrix.disable_security }} STIRLING_PDF_DESKTOP_UI: false - name: Rename binaries @@ -103,11 +98,11 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - enable_security: [true, false] + disable_security: [true, false] include: - - enable_security: true + - disable_security: false file_suffix: "with-login-" - - enable_security: false + - disable_security: true file_suffix: "" steps: - name: Harden Runner @@ -176,7 +171,7 @@ jobs: - name: Build Installer run: ./gradlew build jpackage -x test --info env: - ADDITIONAL_FEATURES_OFF: true + DISABLE_ADDITIONAL_FEATURES: true STIRLING_PDF_DESKTOP_UI: true BROWSER_OPEN: true diff --git a/.github/workflows/push-docker.yml b/.github/workflows/push-docker.yml index 210007c72..03ea3464d 100644 --- a/.github/workflows/push-docker.yml +++ b/.github/workflows/push-docker.yml @@ -37,7 +37,7 @@ jobs: - name: Run Gradle Command run: ./gradlew clean build env: - ADDITIONAL_FEATURES_OFF: true + DISABLE_ADDITIONAL_FEATURES: true STIRLING_PDF_DESKTOP_UI: false - name: Install cosign diff --git a/.github/workflows/releaseArtifacts.yml b/.github/workflows/releaseArtifacts.yml index 09ad89312..5434eec96 100644 --- a/.github/workflows/releaseArtifacts.yml +++ b/.github/workflows/releaseArtifacts.yml @@ -13,17 +13,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - enable_security: [true, false] disable_security: [true, false] include: - - enable_security: true - file_suffix: "-with-login" - - enable_security: false - file_suffix: "" - - disable_security: true - file_suffix: "" - disable_security: false file_suffix: "-with-login" + - disable_security: true + file_suffix: "" outputs: version: ${{ steps.versionNumber.outputs.versionNumber }} steps: @@ -44,10 +39,10 @@ jobs: with: gradle-version: 8.14 - - name: Generate jar (With Security=${{ matrix.enable_security }}) + - name: Generate jar (Disable Security=${{ matrix.disable_security }}) run: ./gradlew clean createExe env: - ADDITIONAL_FEATURES_OFF: ${{ matrix.disable_security }} + DISABLE_ADDITIONAL_FEATURES: ${{ matrix.disable_security }} STIRLING_PDF_DESKTOP_UI: false - name: Get version number @@ -80,11 +75,11 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - enable_security: [true, false] + disable_security: [true, false] include: - - enable_security: true + - disable_security: false file_suffix: "-with-login" - - enable_security: false + - disable_security: true file_suffix: "" steps: - name: Harden Runner @@ -158,11 +153,11 @@ jobs: contents: write strategy: matrix: - enable_security: [true, false] + disable_security: [true, false] include: - - enable_security: true + - disable_security: false file_suffix: "-with-login" - - enable_security: false + - disable_security: true file_suffix: "" steps: - name: Harden Runner diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml index 5509d74bc..16d004dd9 100644 --- a/.github/workflows/sonarqube.yml +++ b/.github/workflows/sonarqube.yml @@ -33,7 +33,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - ADDITIONAL_FEATURES_OFF: false + DISABLE_ADDITIONAL_FEATURES: false STIRLING_PDF_DESKTOP_UI: true run: | ./gradlew clean build sonar \ diff --git a/.github/workflows/testdriver.yml b/.github/workflows/testdriver.yml index 27a8255a4..e4ef4138f 100644 --- a/.github/workflows/testdriver.yml +++ b/.github/workflows/testdriver.yml @@ -28,7 +28,7 @@ jobs: - name: Build with Gradle run: ./gradlew clean build env: - ADDITIONAL_FEATURES_OFF: true + DISABLE_ADDITIONAL_FEATURES: true - name: Set up Docker Buildx uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 @@ -76,7 +76,7 @@ jobs: - /stirling/test-${{ github.sha }}/config:/configs:rw - /stirling/test-${{ github.sha }}/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "true" + DISABLE_ADDITIONAL_FEATURES: "true" SECURITY_ENABLELOGIN: "false" SYSTEM_DEFAULTLOCALE: en-GB UI_APPNAME: "Stirling-PDF Test" diff --git a/DeveloperGuide.md b/DeveloperGuide.md index cb4c4827a..f9b8833b8 100644 --- a/DeveloperGuide.md +++ b/DeveloperGuide.md @@ -55,7 +55,7 @@ Stirling-PDF uses Lombok to reduce boilerplate code. Some IDEs, like Eclipse, do Visit the [Lombok website](https://projectlombok.org/setup/) for installation instructions specific to your IDE. 5. Add environment variable -For local testing, you should generally be testing the full 'Security' version of Stirling-PDF. To do this, you must add the environment flag ADDITIONAL_FEATURES_OFF=false to your system and/or IDE build/run step. +For local testing, you should generally be testing the full 'Security' version of Stirling-PDF. To do this, you must add the environment flag DISABLE_ADDITIONAL_FEATURES=false to your system and/or IDE build/run step. ## 4. Project Structure @@ -141,7 +141,7 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "false" + DISABLE_ADDITIONAL_FEATURES: "false" SECURITY_ENABLELOGIN: "true" PUID: 1002 PGID: 1002 @@ -170,7 +170,7 @@ Stirling-PDF uses different Docker images for various configurations. The build 1. Set the security environment variable: ```bash - export ADDITIONAL_FEATURES_OFF=true # or false for security-enabled builds + export DISABLE_ADDITIONAL_FEATURES=true # or false for security-enabled builds ``` 2. Build the project with Gradle: @@ -196,7 +196,7 @@ Stirling-PDF uses different Docker images for various configurations. The build For the fat version (with security enabled): ```bash - export ADDITIONAL_FEATURES_OFF=false + export DISABLE_ADDITIONAL_FEATURES=false docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest-fat -f ./Dockerfile.fat . ``` diff --git a/Dockerfile b/Dockerfile index ad8f7c590..bef88cd98 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ LABEL org.opencontainers.image.version="${VERSION_TAG}" LABEL org.opencontainers.image.keywords="PDF, manipulation, merge, split, convert, OCR, watermark" # Set Environment Variables -ENV ADDITIONAL_FEATURES_OFF=true \ +ENV DISABLE_ADDITIONAL_FEATURES=true \ VERSION_TAG=$VERSION_TAG \ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ JAVA_CUSTOM_OPTS="" \ diff --git a/Dockerfile.fat b/Dockerfile.fat index e742dd43b..20ce8030f 100644 --- a/Dockerfile.fat +++ b/Dockerfile.fat @@ -15,8 +15,8 @@ WORKDIR /app # Copy the entire project to the working directory COPY . . -# Build the application with ADDITIONAL_FEATURES_OFF=false -RUN ADDITIONAL_FEATURES_OFF=false \ +# Build the application with DISABLE_ADDITIONAL_FEATURES=false +RUN DISABLE_ADDITIONAL_FEATURES=false \ STIRLING_PDF_DESKTOP_UI=false \ ./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube @@ -32,7 +32,7 @@ COPY --from=build /app/build/libs/*.jar app.jar ARG VERSION_TAG # Set Environment Variables -ENV ADDITIONAL_FEATURES_OFF=true \ +ENV DISABLE_ADDITIONAL_FEATURES=true \ VERSION_TAG=$VERSION_TAG \ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ JAVA_CUSTOM_OPTS="" \ diff --git a/Dockerfile.ultra-lite b/Dockerfile.ultra-lite index 3b54091b1..6da0990f9 100644 --- a/Dockerfile.ultra-lite +++ b/Dockerfile.ultra-lite @@ -4,7 +4,7 @@ FROM alpine:3.22.0@sha256:8a1f59ffb675680d47db6337b49d22281a139e9d709335b492be02 ARG VERSION_TAG # Set Environment Variables -ENV ADDITIONAL_FEATURES_OFF=true \ +ENV DISABLE_ADDITIONAL_FEATURES=true \ HOME=/home/stirlingpdfuser \ VERSION_TAG=$VERSION_TAG \ JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ diff --git a/build.gradle b/build.gradle index 987b4b14f..7cdc6683b 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { id "com.diffplug.spotless" version "7.0.4" id "com.github.jk1.dependency-license-report" version "2.9" //id "nebula.lint" version "19.0.3" - id("org.panteleyev.jpackageplugin") version "1.6.1" + id "org.panteleyev.jpackageplugin" version "1.6.1" id "org.sonarqube" version "6.2.0.5505" } @@ -51,9 +51,9 @@ licenseReport { sourceSets { main { java { - if (System.getenv('DOCKER_ENABLE_SECURITY') == 'false' || System.getenv('ADDITIONAL_FEATURES_OFF') == 'false' - || (project.hasProperty('ADDITIONAL_FEATURES_OFF') - && System.getProperty('ADDITIONAL_FEATURES_OFF'))) { + if (System.getenv('DOCKER_ENABLE_SECURITY') == 'false' || System.getenv('DISABLE_ADDITIONAL_FEATURES') == 'true' + || (project.hasProperty('DISABLE_ADDITIONAL_FEATURES') + && System.getProperty('DISABLE_ADDITIONAL_FEATURES') == 'true')) { exclude 'stirling/software/proprietary/security/**' } @@ -66,9 +66,9 @@ sourceSets { test { java { - if (System.getenv('DOCKER_ENABLE_SECURITY') == 'false' || System.getenv('ADDITIONAL_FEATURES_OFF') == 'false' - || (project.hasProperty('ADDITIONAL_FEATURES_OFF') - && System.getProperty('ADDITIONAL_FEATURES_OFF'))) { + if (System.getenv('DOCKER_ENABLE_SECURITY') == 'false' || System.getenv('DISABLE_ADDITIONAL_FEATURES') == 'true' + || (project.hasProperty('DISABLE_ADDITIONAL_FEATURES') + && System.getProperty('DISABLE_ADDITIONAL_FEATURES') == 'true')) { exclude 'stirling/software/proprietary/security/**' } @@ -285,18 +285,18 @@ tasks.register('downloadTempJre') { def jreArchive = new File(tmpDir, 'jre.tar.gz') def jreDir = new File(tmpDir, 'jre') - println "🔽 Downloading JRE to $jreArchive..." + println "Downloading JRE to $jreArchive..." jreArchive.withOutputStream { out -> new URI(jreUrl).toURL().withInputStream { from -> out << from } } - println "📦 Extracting JRE to $jreDir..." + println "Extracting JRE to $jreDir..." jreDir.mkdirs() providers.exec { commandLine 'tar', '-xzf', jreArchive.absolutePath, '-C', jreDir.absolutePath, '--strip-components=1' }.result.get() - println "✅ JRE ready at: $jreDir" + println "JRE ready at: $jreDir" ext.tempJrePath = jreDir.absolutePath project.ext.tempJrePath = jreDir.absolutePath } catch (Exception e) { @@ -431,7 +431,7 @@ dependencies { implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1' implementation 'org.snakeyaml:snakeyaml-engine:2.9' - if (System.getenv("DOCKER_ENABLE_SECURITY") != "false" || System.getenv("ADDITIONAL_FEATURES_OFF") == "false") { + if (System.getenv("DOCKER_ENABLE_SECURITY") != "false" && System.getenv("DISABLE_ADDITIONAL_FEATURES") != "true") { implementation project(':proprietary') } diff --git a/common/gradle/wrapper/gradle-wrapper.properties b/common/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index f7664bccf..000000000 --- a/common/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/common/gradlew b/common/gradlew deleted file mode 100755 index 23d15a936..000000000 --- a/common/gradlew +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH="\\\"\\\"" - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/common/gradlew.bat b/common/gradlew.bat deleted file mode 100644 index db3a6ac20..000000000 --- a/common/gradlew.bat +++ /dev/null @@ -1,94 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH= - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/common/src/main/java/stirling/software/common/configuration/AppConfig.java b/common/src/main/java/stirling/software/common/configuration/AppConfig.java index f6b8b2d45..6c243eb59 100644 --- a/common/src/main/java/stirling/software/common/configuration/AppConfig.java +++ b/common/src/main/java/stirling/software/common/configuration/AppConfig.java @@ -148,10 +148,16 @@ public class AppConfig { } @Bean(name = "activeSecurity") - @ConditionalOnClass( - name = "stirling.software.proprietary.security.configuration.SecurityConfiguration") public boolean activeSecurity() { - return true; + String additionalFeaturesOff = env.getProperty("DISABLE_ADDITIONAL_FEATURES"); + + if (additionalFeaturesOff != null) { + // DISABLE_ADDITIONAL_FEATURES=true means security OFF, so return false + // DISABLE_ADDITIONAL_FEATURES=false means security ON, so return true + return !Boolean.parseBoolean(additionalFeaturesOff); + } + + return env.getProperty("DOCKER_ENABLE_SECURITY", Boolean.class, true); } @Bean(name = "missingActiveSecurity") diff --git a/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml b/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml index 4f3b25948..827de1e19 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml @@ -20,7 +20,7 @@ services: - ./stirling/latest/logs:/logs:rw - ../testing/allEndpointsRemovedSettings.yml:/configs/settings.yml:rw environment: - ADDITIONAL_FEATURES_OFF: "false" + DISABLE_ADDITIONAL_FEATURES: "false" SECURITY_ENABLELOGIN: "false" PUID: 1002 PGID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml b/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml index f38ed84e2..bbf8a2115 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml @@ -20,7 +20,7 @@ services: - ./stirling/latest/config:/configs:rw - ./stirling/latest/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "false" + DISABLE_ADDITIONAL_FEATURES: "false" SECURITY_ENABLELOGIN: "false" PUID: 1002 PGID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-fat-security.yml b/exampleYmlFiles/docker-compose-latest-fat-security.yml index 88441ee9a..5b07420ff 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-security.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-security.yml @@ -18,7 +18,7 @@ services: - ./stirling/latest/config:/configs:rw - ./stirling/latest/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "false" + DISABLE_ADDITIONAL_FEATURES: "false" SECURITY_ENABLELOGIN: "false" PUID: 1002 PGID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml b/exampleYmlFiles/docker-compose-latest-security-with-sso.yml index 947ddc447..89d0fc94e 100644 --- a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml +++ b/exampleYmlFiles/docker-compose-latest-security-with-sso.yml @@ -18,7 +18,7 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "false" + DISABLE_ADDITIONAL_FEATURES: "false" SECURITY_ENABLELOGIN: "true" SECURITY_OAUTH2_ENABLED: "true" SECURITY_OAUTH2_AUTOCREATEUSER: "true" # This is set to true to allow auto-creation of non-existing users in Stirling-PDF diff --git a/exampleYmlFiles/docker-compose-latest-security.yml b/exampleYmlFiles/docker-compose-latest-security.yml index fa8d76888..c6589ab9c 100644 --- a/exampleYmlFiles/docker-compose-latest-security.yml +++ b/exampleYmlFiles/docker-compose-latest-security.yml @@ -18,7 +18,7 @@ services: - ./stirling/latest/config:/configs:rw - ./stirling/latest/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "false" + DISABLE_ADDITIONAL_FEATURES: "false" SECURITY_ENABLELOGIN: "true" PUID: 1002 PGID: 1002 diff --git a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml b/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml index 434bbcd61..c927ab706 100644 --- a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml +++ b/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml @@ -18,7 +18,7 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "false" + DISABLE_ADDITIONAL_FEATURES: "false" SECURITY_ENABLELOGIN: "true" SYSTEM_DEFAULTLOCALE: en-US UI_APPNAME: Stirling-PDF-Lite diff --git a/exampleYmlFiles/docker-compose-latest-ultra-lite.yml b/exampleYmlFiles/docker-compose-latest-ultra-lite.yml index 484acf269..d3e1b9759 100644 --- a/exampleYmlFiles/docker-compose-latest-ultra-lite.yml +++ b/exampleYmlFiles/docker-compose-latest-ultra-lite.yml @@ -17,7 +17,7 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "true" + DISABLE_ADDITIONAL_FEATURES: "true" SECURITY_ENABLELOGIN: "false" SYSTEM_DEFAULTLOCALE: en-US UI_APPNAME: Stirling-PDF-Ultra-lite diff --git a/exampleYmlFiles/docker-compose-latest.yml b/exampleYmlFiles/docker-compose-latest.yml index 46cfe3553..d8b1aee74 100644 --- a/exampleYmlFiles/docker-compose-latest.yml +++ b/exampleYmlFiles/docker-compose-latest.yml @@ -18,7 +18,7 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "true" + DISABLE_ADDITIONAL_FEATURES: "true" SECURITY_ENABLELOGIN: "false" LANGS: "en_GB,en_US,ar_AR,de_DE,fr_FR,es_ES,zh_CN,zh_TW,ca_CA,it_IT,sv_SE,pl_PL,ro_RO,ko_KR,pt_BR,ru_RU,el_GR,hi_IN,hu_HU,tr_TR,id_ID" SYSTEM_DEFAULTLOCALE: en-US diff --git a/exampleYmlFiles/test_cicd.yml b/exampleYmlFiles/test_cicd.yml index c76471bd8..749e863a3 100644 --- a/exampleYmlFiles/test_cicd.yml +++ b/exampleYmlFiles/test_cicd.yml @@ -18,7 +18,7 @@ services: - /stirling/latest/config:/configs:rw - /stirling/latest/logs:/logs:rw environment: - ADDITIONAL_FEATURES_OFF: "false" + DISABLE_ADDITIONAL_FEATURES: "false" SECURITY_ENABLELOGIN: "true" PUID: 1002 PGID: 1002 diff --git a/proprietary/gradle/wrapper/gradle-wrapper.properties b/proprietary/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index f7664bccf..000000000 --- a/proprietary/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/proprietary/gradlew b/proprietary/gradlew deleted file mode 100755 index 23d15a936..000000000 --- a/proprietary/gradlew +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH="\\\"\\\"" - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/proprietary/gradlew.bat b/proprietary/gradlew.bat deleted file mode 100644 index db3a6ac20..000000000 --- a/proprietary/gradlew.bat +++ /dev/null @@ -1,94 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH= - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java index 82d794d6e..c9b6e9d77 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/configuration/MailConfig.java @@ -10,6 +10,7 @@ import org.springframework.mail.javamail.JavaMailSenderImpl; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; + import stirling.software.common.model.ApplicationProperties; /** diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java b/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java index 0fd356da2..b364f3738 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/model/User.java @@ -14,7 +14,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; -import stirling.software.common.model.enumeration.Role; import stirling.software.common.model.enumeration.Role; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java index 92b053b8a..7175a5b5d 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java @@ -1,10 +1,7 @@ package stirling.software.proprietary.security.oauth2; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import lombok.extern.slf4j.Slf4j; + import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.DisabledException; import org.springframework.security.authentication.LockedException; @@ -13,6 +10,12 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2Error; 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; + @Slf4j public class CustomOAuth2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java index c2957e241..fff03fd4f 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CertificateUtils.java @@ -6,6 +6,7 @@ import java.nio.charset.StandardCharsets; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; + import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java index 055ac8f4e..a39a39092 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticatedPrincipal.java @@ -3,6 +3,7 @@ package stirling.software.proprietary.security.saml2; import java.io.Serializable; import java.util.List; import java.util.Map; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java index a7e663aac..7bf0c3a3b 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/CustomSaml2AuthenticationFailureHandler.java @@ -1,9 +1,7 @@ package stirling.software.proprietary.security.saml2; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import lombok.extern.slf4j.Slf4j; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.security.authentication.ProviderNotFoundException; import org.springframework.security.core.AuthenticationException; @@ -11,6 +9,11 @@ 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.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import lombok.extern.slf4j.Slf4j; + @Slf4j @ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true") public class CustomSaml2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java index 836419ea0..233bcaadd 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/saml2/SAML2Configuration.java @@ -1,11 +1,9 @@ package stirling.software.proprietary.security.saml2; -import jakarta.servlet.http.HttpServletRequest; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.UUID; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; + import org.opensaml.saml.saml2.core.AuthnRequest; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -21,6 +19,12 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository; import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; + +import jakarta.servlet.http.HttpServletRequest; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties.Security.SAML2; diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java index 6c1d334f5..eccd7332e 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionRegistryConfig.java @@ -3,7 +3,6 @@ package stirling.software.proprietary.security.session; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.session.SessionRegistryImpl; -import stirling.software.proprietary.security.database.repository.SessionRepository; import stirling.software.proprietary.security.database.repository.SessionRepository; @@ -16,7 +15,8 @@ public class SessionRegistryConfig { } @Bean - public SessionPersistentRegistry sessionPersistentRegistry(SessionRepository sessionRepository) { + public SessionPersistentRegistry sessionPersistentRegistry( + SessionRepository sessionRepository) { return new SessionPersistentRegistry(sessionRepository); } } diff --git a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java index 83403f9f7..1f491bf4d 100644 --- a/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java +++ b/proprietary/src/main/java/stirling/software/proprietary/security/session/SessionScheduled.java @@ -4,11 +4,13 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.List; -import lombok.RequiredArgsConstructor; + import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.core.session.SessionInformation; import org.springframework.stereotype.Component; +import lombok.RequiredArgsConstructor; + @Component @RequiredArgsConstructor public class SessionScheduled { diff --git a/scripts/download-security-jar.sh b/scripts/download-security-jar.sh index bee188d97..d49cf3605 100644 --- a/scripts/download-security-jar.sh +++ b/scripts/download-security-jar.sh @@ -1,6 +1,6 @@ -echo "Running Stirling PDF with ADDITIONAL_FEATURES_OFF=${ADDITIONAL_FEATURES_OFF} and VERSION_TAG=${VERSION_TAG}" -# Check for $ADDITIONAL_FEATURES_OFF and download the appropriate JAR if required -if [ "$ADDITIONAL_FEATURES_OFF" = "false" ] && [ "$VERSION_TAG" != "alpha" ]; then +echo "Running Stirling PDF with DISABLE_ADDITIONAL_FEATURES=${DISABLE_ADDITIONAL_FEATURES} and VERSION_TAG=${VERSION_TAG}" +# Check for $DISABLE_ADDITIONAL_FEATURES and download the appropriate JAR if required +if [ "$DISABLE_ADDITIONAL_FEATURES" = "false" ] && [ "$VERSION_TAG" != "alpha" ]; then if [ ! -f app-security.jar ]; then echo "Trying to download from: https://files.stirlingpdf.com/v$VERSION_TAG/Stirling-PDF-with-login.jar" curl -L -o app-security.jar https://files.stirlingpdf.com/v$VERSION_TAG/Stirling-PDF-with-login.jar diff --git a/testing/test.sh b/testing/test.sh index 0891c6bbd..51f63b453 100644 --- a/testing/test.sh +++ b/testing/test.sh @@ -214,7 +214,7 @@ main() { export DOCKER_CLI_EXPERIMENTAL=enabled export COMPOSE_DOCKER_CLI_BUILD=0 - export ADDITIONAL_FEATURES_OFF=true + export DISABLE_ADDITIONAL_FEATURES=true # Run the gradlew build command and check if it fails if ! ./gradlew clean build; then echo "Gradle build failed with security disabled, exiting script." @@ -242,7 +242,7 @@ main() { # run_tests "Stirling-PDF" "./exampleYmlFiles/docker-compose-latest.yml" # docker-compose -f "./exampleYmlFiles/docker-compose-latest.yml" down - export ADDITIONAL_FEATURES_OFF=false + export DISABLE_ADDITIONAL_FEATURES=false # Run the gradlew build command and check if it fails if ! ./gradlew clean build; then echo "Gradle build failed with security enabled, exiting script." From 2df70daf169169cef8162f48993f60ab73d5cce3 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Wed, 4 Jun 2025 16:31:40 +0100 Subject: [PATCH 13/15] updated jpackage --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 7cdc6683b..3d003bb85 100644 --- a/build.gradle +++ b/build.gradle @@ -110,6 +110,7 @@ jpackage { javaOptions = [ "-DBROWSER_OPEN=true", "-DSTIRLING_PDF_DESKTOP_UI=true", + "-DDISABLE_ADDITIONAL_FEATURES=false", "-Djava.awt.headless=false", "-Dapple.awt.UIElement=true", "--add-opens=java.base/java.lang=ALL-UNNAMED", @@ -246,6 +247,7 @@ tasks.register('jpackageMacX64') { // Java options '--java-options', '-DBROWSER_OPEN=true', '--java-options', '-DSTIRLING_PDF_DESKTOP_UI=true', + '--java-options', '-DDISABLE_ADDITIONAL_FEATURES=false', '--java-options', '-Djava.awt.headless=false', '--java-options', '-Dapple.awt.UIElement=true', '--java-options', '--add-opens=java.base/java.lang=ALL-UNNAMED', From 6cef1fac5f30fddd11211dc6f041a88f88139c9e Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Wed, 4 Jun 2025 17:18:41 +0100 Subject: [PATCH 14/15] renamed proprietary/LICENSE and fixed main LICENSE --- LICENSE | 7 ------- proprietary/{LICENSE-proprietary => LICENSE} | 0 2 files changed, 7 deletions(-) rename proprietary/{LICENSE-proprietary => LICENSE} (100%) diff --git a/LICENSE b/LICENSE index 62cd6e5cc..877663171 100644 --- a/LICENSE +++ b/LICENSE @@ -9,13 +9,6 @@ if that directory exists, is licensed under the license defined in "proprietary/ * Content outside of the above mentioned directories or restrictions above is available under the MIT License as defined below. -Portions of this software are licensed as follows: - -* All content that resides under the "proprietary/" directory of this repository, -if that directory exists, is licensed under the license defined in "proprietary/LICENSE". -* Content outside of the above mentioned directories or restrictions above is -available under the MIT License as defined below. - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff --git a/proprietary/LICENSE-proprietary b/proprietary/LICENSE similarity index 100% rename from proprietary/LICENSE-proprietary rename to proprietary/LICENSE From 0006a77b5da1276217bfc9bcc5d36dc1d85fce07 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Thu, 5 Jun 2025 10:35:52 +0100 Subject: [PATCH 15/15] updated comments in DeveloperGuide.md --- DeveloperGuide.md | 12 ++++++------ build.gradle | 4 +++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/DeveloperGuide.md b/DeveloperGuide.md index f9b8833b8..d484838e0 100644 --- a/DeveloperGuide.md +++ b/DeveloperGuide.md @@ -55,7 +55,7 @@ Stirling-PDF uses Lombok to reduce boilerplate code. Some IDEs, like Eclipse, do Visit the [Lombok website](https://projectlombok.org/setup/) for installation instructions specific to your IDE. 5. Add environment variable -For local testing, you should generally be testing the full 'Security' version of Stirling-PDF. To do this, you must add the environment flag DISABLE_ADDITIONAL_FEATURES=false to your system and/or IDE build/run step. +For local testing, you should generally be testing the full 'Security' version of Stirling PDF. To do this, you must add the environment flag DISABLE_ADDITIONAL_FEATURES=false to your system and/or IDE build/run step. ## 4. Project Structure @@ -114,9 +114,9 @@ Stirling-PDF offers several Docker versions: Stirling-PDF provides several example Docker Compose files in the `exampleYmlFiles` directory, such as: -- `docker-compose-latest.yml`: Latest version without security features -- `docker-compose-latest-security.yml`: Latest version with security features enabled -- `docker-compose-latest-fat-security.yml`: Fat version with security features enabled +- `docker-compose-latest.yml`: Latest version without login and security features +- `docker-compose-latest-security.yml`: Latest version with login and security features enabled +- `docker-compose-latest-fat-security.yml`: Fat version with login and security features enabled These files provide pre-configured setups for different scenarios. For example, here's a snippet from `docker-compose-latest-security.yml`: @@ -170,7 +170,7 @@ Stirling-PDF uses different Docker images for various configurations. The build 1. Set the security environment variable: ```bash - export DISABLE_ADDITIONAL_FEATURES=true # or false for security-enabled builds + export DISABLE_ADDITIONAL_FEATURES=true # or false for to enable login and security features for builds ``` 2. Build the project with Gradle: @@ -193,7 +193,7 @@ Stirling-PDF uses different Docker images for various configurations. The build docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest-ultra-lite -f ./Dockerfile.ultra-lite . ``` - For the fat version (with security enabled): + For the fat version (with login and security features enabled): ```bash export DISABLE_ADDITIONAL_FEATURES=false diff --git a/build.gradle b/build.gradle index 3d003bb85..6ca36d727 100644 --- a/build.gradle +++ b/build.gradle @@ -433,7 +433,9 @@ dependencies { implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1' implementation 'org.snakeyaml:snakeyaml-engine:2.9' - if (System.getenv("DOCKER_ENABLE_SECURITY") != "false" && System.getenv("DISABLE_ADDITIONAL_FEATURES") != "true") { + if (System.getenv("DOCKER_ENABLE_SECURITY") != "false" || System.getenv('DISABLE_ADDITIONAL_FEATURES') != 'true' + || (project.hasProperty('DISABLE_ADDITIONAL_FEATURES') + && System.getProperty('DISABLE_ADDITIONAL_FEATURES') != 'true')) { implementation project(':proprietary') }