diff --git a/.gitattributes b/.gitattributes index c498408ab..f72c204bd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,10 +1,10 @@ * text=auto eol=lf # Ignore all JavaScript files in a directory -src/main/resources/static/pdfjs/* linguist-vendored -src/main/resources/static/pdfjs/** linguist-vendored -src/main/resources/static/pdfjs-legacy/* linguist-vendored -src/main/resources/static/pdfjs-legacy/** linguist-vendored -src/main/resources/static/css/bootstrap-icons.css linguist-vendored -src/main/resources/static/css/bootstrap.min.css linguist-vendored -src/main/resources/static/css/fonts/* linguist-vendored +stirling-pdf/src/main/resources/static/pdfjs/* linguist-vendored +stirling-pdf/src/main/resources/static/pdfjs/** linguist-vendored +stirling-pdf/src/main/resources/static/pdfjs-legacy/* linguist-vendored +stirling-pdf/src/main/resources/static/pdfjs-legacy/** linguist-vendored +stirling-pdf/src/main/resources/static/css/bootstrap-icons.css linguist-vendored +stirling-pdf/src/main/resources/static/css/bootstrap.min.css linguist-vendored +stirling-pdf/src/main/resources/static/css/fonts/* linguist-vendored diff --git a/.github/labeler-config.yml b/.github/labeler-config.yml index bb52c7b85..d1a340065 100644 --- a/.github/labeler-config.yml +++ b/.github/labeler-config.yml @@ -1,60 +1,45 @@ Translation: - changed-files: - - any-glob-to-any-file: 'src/main/resources/messages_*_*.properties' + - any-glob-to-any-file: 'stirling-pdf/src/main/resources/messages_*_*.properties' - any-glob-to-any-file: 'scripts/ignore_translation.toml' - - any-glob-to-any-file: 'src/main/resources/templates/fragments/languages.html' + - any-glob-to-any-file: 'stirling-pdf/src/main/resources/templates/fragments/languages.html' Front End: - changed-files: - - any-glob-to-any-file: 'src/main/resources/templates/**/*' - - any-glob-to-any-file: 'src/main/resources/static/**/*' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/**' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/UI/**/*' + - any-glob-to-any-file: 'stirling-pdf/src/main/resources/templates/**/*' + - any-glob-to-any-file: 'stirling-pdf/src/main/resources/static/**/*' + - any-glob-to-any-file: 'stirling-pdf/src/main/java/stirling/software/SPDF/controller/web/**' + - any-glob-to-any-file: 'stirling-pdf/src/main/java/stirling/software/SPDF/UI/**/*' Java: - changed-files: - - any-glob-to-any-file: 'src/main/java/**/*.java' + - any-glob-to-any-file: 'common/src/main/java/**/*.java' + - any-glob-to-any-file: 'proprietary/src/main/java/**/*.java' + - any-glob-to-any-file: 'stirling-pdf/src/main/java/**/*.java' Back End: - changed-files: - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/**/*' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/**/*' - - any-glob-to-any-file: 'src/main/resources/settings.yml.template' - - any-glob-to-any-file: 'src/main/resources/application.properties' - - any-glob-to-any-file: 'src/main/resources/banner.txt' + - any-glob-to-any-file: 'stirling-pdf/src/main/java/stirling/software/SPDF/config/**/*' + - any-glob-to-any-file: 'stirling-pdf/src/main/java/stirling/software/SPDF/controller/**/*' + - any-glob-to-any-file: 'stirling-pdf/src/main/resources/settings.yml.template' + - any-glob-to-any-file: 'stirling-pdf/src/main/resources/application.properties' + - any-glob-to-any-file: 'stirling-pdf/src/main/resources/banner.txt' - any-glob-to-any-file: 'scripts/png_to_webp.py' - any-glob-to-any-file: 'split_photos.py' Security: - changed-files: - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/interfaces/DatabaseInterface.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/EmailController.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/H2SQLController.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/UserController.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/api/Email.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/exception/BackupNotFoundException.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/exception/NoProviderFoundExceptionjava' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/provider/**/*' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/AuthenticationType.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/ApiKeyAuthenticationToken.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/AttemptCounter.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/Authority.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/PersistentLogin.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/SessionEntity.java' + - any-glob-to-any-file: 'proprietary/src/main/java/stirling/software/proprietary/security/**/*' - any-glob-to-any-file: 'scripts/download-security-jar.sh' - any-glob-to-any-file: '.github/workflows/dependency-review.yml' - any-glob-to-any-file: '.github/workflows/scorecards.yml' API: - changed-files: - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/OpenApiConfig.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/MetricsController.java' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/**/*' - - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/api/**/*' + - any-glob-to-any-file: 'stirling-pdf/src/main/java/stirling/software/SPDF/config/OpenApiConfig.java' + - any-glob-to-any-file: 'stirling-pdf/src/main/java/stirling/software/SPDF/controller/web/MetricsController.java' + - any-glob-to-any-file: 'stirling-pdf/src/main/java/stirling/software/SPDF/controller/api/**/*' + - any-glob-to-any-file: 'stirling-pdf/src/main/java/stirling/software/SPDF/model/api/**/*' - any-glob-to-any-file: 'scripts/png_to_webp.py' - any-glob-to-any-file: 'split_photos.py' - any-glob-to-any-file: '.github/workflows/swagger.yml' @@ -88,7 +73,9 @@ Devtools: Test: - changed-files: - any-glob-to-any-file: 'cucumber/**/*' - - any-glob-to-any-file: 'src/test/**/*' + - any-glob-to-any-file: 'common/src/test/**/*' + - any-glob-to-any-file: 'proprietary/src/test/**/*' + - any-glob-to-any-file: 'stirling-pdf/src/test/**/*' - any-glob-to-any-file: 'src/testing/**/*' - any-glob-to-any-file: '.pre-commit-config' - any-glob-to-any-file: '.github/workflows/pre_commit.yml' diff --git a/.github/scripts/check_language_properties.py b/.github/scripts/check_language_properties.py index 10e6fb650..8ae7dbfc1 100644 --- a/.github/scripts/check_language_properties.py +++ b/.github/scripts/check_language_properties.py @@ -317,7 +317,7 @@ def check_for_differences(reference_file, file_list, branch, actor): report.append("## ❌ Overall Check Status: **_Failed_**") report.append("") report.append( - f"@{actor} please check your translation if it conforms to the standard. Follow the format of [messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties)" + f"@{actor} please check your translation if it conforms to the standard. Follow the format of [messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/stirling-pdf/src/main/resources/messages_en_GB.properties)" ) else: report.append("## ✅ Overall Check Status: **_Success_**") diff --git a/.github/workflows/check_properties.yml b/.github/workflows/check_properties.yml index d74e3084a..2e9ee8cbe 100644 --- a/.github/workflows/check_properties.yml +++ b/.github/workflows/check_properties.yml @@ -4,7 +4,7 @@ on: pull_request_target: types: [opened, synchronize, reopened] paths: - - "src/main/resources/messages_*.properties" + - "stirling-pdf/src/main/resources/messages_*.properties" permissions: contents: read # Allow read access to repository content @@ -61,7 +61,7 @@ jobs: run: | echo "Fetching PR changed files..." echo "Getting list of changed files from PR..." - gh pr view ${{ steps.get-pr-data.outputs.pr_number }} --json files -q ".files[].path" | grep -E '^src/main/resources/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$' > changed_files.txt # Filter only matching property files + gh pr view ${{ steps.get-pr-data.outputs.pr_number }} --json files -q ".files[].path" | grep -E '^stirling-pdf/src/main/resources/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$' > changed_files.txt # Filter only matching property files - name: Determine reference file test id: determine-file @@ -141,12 +141,12 @@ jobs: // Determine reference file let referenceFilePath; - if (changedFiles.includes("src/main/resources/messages_en_GB.properties")) { + if (changedFiles.includes("stirling-pdf/src/main/resources/messages_en_GB.properties")) { console.log("Using PR branch reference file."); const { data: fileContent } = await github.rest.repos.getContent({ owner: prRepoOwner, repo: prRepoName, - path: "src/main/resources/messages_en_GB.properties", + path: "stirling-pdf/src/main/resources/messages_en_GB.properties", ref: branch, }); @@ -158,7 +158,7 @@ jobs: const { data: fileContent } = await github.rest.repos.getContent({ owner: repoOwner, repo: repoName, - path: "src/main/resources/messages_en_GB.properties", + path: "stirling-pdf/src/main/resources/messages_en_GB.properties", ref: "main", }); diff --git a/.github/workflows/licenses-update.yml b/.github/workflows/licenses-update.yml index e040e5436..f9fb1e521 100644 --- a/.github/workflows/licenses-update.yml +++ b/.github/workflows/licenses-update.yml @@ -57,11 +57,11 @@ jobs: - name: Move and rename license file run: | - mv build/reports/dependency-license/index.json src/main/resources/static/3rdPartyLicenses.json + mv build/reports/dependency-license/index.json stirling-pdf/src/main/resources/static/3rdPartyLicenses.json - name: Commit changes run: | - git add src/main/resources/static/3rdPartyLicenses.json + git add stirling-pdf/src/main/resources/static/3rdPartyLicenses.json git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV - name: Create Pull Request diff --git a/.github/workflows/sync_files.yml b/.github/workflows/sync_files.yml index 92b4f3c87..dd29b0d4b 100644 --- a/.github/workflows/sync_files.yml +++ b/.github/workflows/sync_files.yml @@ -8,8 +8,8 @@ on: paths: - "build.gradle" - "README.md" - - "src/main/resources/messages_*.properties" - - "src/main/resources/static/3rdPartyLicenses.json" + - "stirling-pdf/src/main/resources/messages_*.properties" + - "stirling-pdf/src/main/resources/static/3rdPartyLicenses.json" - "scripts/ignore_translation.toml" permissions: @@ -41,11 +41,11 @@ jobs: - name: Sync translation property files run: | - python .github/scripts/check_language_properties.py --reference-file "src/main/resources/messages_en_GB.properties" --branch main + python .github/scripts/check_language_properties.py --reference-file "stirling-pdf/src/main/resources/messages_en_GB.properties" --branch main - name: Commit translation files run: | - git add src/main/resources/messages_*.properties + git add stirling-pdf/src/main/resources/messages_*.properties git diff --staged --quiet || git commit -m ":memo: Sync translation files" || echo "No changes detected" - name: Install dependencies @@ -101,4 +101,4 @@ jobs: sign-commits: true add-paths: | README.md - src/main/resources/messages_*.properties + stirling-pdf/src/main/resources/messages_*.properties diff --git a/.gitignore b/.gitignore index 06602d03b..039c653e3 100644 --- a/.gitignore +++ b/.gitignore @@ -125,6 +125,9 @@ SwaggerDoc.json *.rar *.db /build +/stirling-pdf/build +/common/build +/proprietary/build # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index beec5eb99..b4b3841e6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: - --skip="./.*,*.csv,*.json,*.ambr" - --quiet-level=2 files: \.(html|css|js|py|md)$ - exclude: (.vscode|.devcontainer|src/main/resources|Dockerfile|.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js) + exclude: (.vscode|.devcontainer|stirling-pdf/src/main/resources|Dockerfile|.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js) - repo: https://github.com/gitleaks/gitleaks rev: v8.26.0 hooks: diff --git a/DeveloperGuide.md b/DeveloperGuide.md index d484838e0..fb0ec5585 100644 --- a/DeveloperGuide.md +++ b/DeveloperGuide.md @@ -332,7 +332,7 @@ Thymeleaf is a server-side Java HTML template engine. It is used in Stirling-PDF ### Thymeleaf overview -In Stirling-PDF, Thymeleaf is used to create HTML templates that are rendered on the server side. These templates are located in the `src/main/resources/templates` directory. Thymeleaf templates use a combination of HTML and special Thymeleaf attributes to dynamically generate content. +In Stirling-PDF, Thymeleaf is used to create HTML templates that are rendered on the server side. These templates are located in the `stirling-pdf/src/main/resources/templates` directory. Thymeleaf templates use a combination of HTML and special Thymeleaf attributes to dynamically generate content. Some examples of this are: @@ -384,7 +384,7 @@ This would generate n entries of tr for each person in exampleData ### Adding a New Feature to the Backend (API) 1. **Create a New Controller:** - - Create a new Java class in the `src/main/java/stirling/software/SPDF/controller/api` directory. + - Create a new Java class in the `stirling-pdf/src/main/java/stirling/software/SPDF/controller/api` directory. - Annotate the class with `@RestController` and `@RequestMapping` to define the API endpoint. - Ensure to add API documentation annotations like `@Tag(name = "General", description = "General APIs")` and `@Operation(summary = "Crops a PDF document", description = "This operation takes an input PDF file and crops it according to the given coordinates. Input:PDF Output:PDF Type:SISO")`. @@ -411,7 +411,7 @@ This would generate n entries of tr for each person in exampleData ``` 2. **Define the Service Layer:** (Not required but often useful) - - Create a new service class in the `src/main/java/stirling/software/SPDF/service` directory. + - Create a new service class in the `stirling-pdf/src/main/java/stirling/software/SPDF/service` directory. - Implement the business logic for the new feature. ```java @@ -463,7 +463,7 @@ This would generate n entries of tr for each person in exampleData ### Adding a New Feature to the Frontend (UI) 1. **Create a New Thymeleaf Template:** - - Create a new HTML file in the `src/main/resources/templates` directory. + - Create a new HTML file in the `stirling-pdf/src/main/resources/templates` directory. - Use Thymeleaf attributes to dynamically generate content. - Use `extract-page.html` as a base example for the HTML template, which is useful to ensure importing of the general layout, navbar, and footer. @@ -507,7 +507,7 @@ This would generate n entries of tr for each person in exampleData ``` 2. **Create a New Controller for the UI:** - - Create a new Java class in the `src/main/java/stirling/software/SPDF/controller/ui` directory. + - Create a new Java class in the `stirling-pdf/src/main/java/stirling/software/SPDF/controller/ui` directory. - Annotate the class with `@Controller` and `@RequestMapping` to define the UI endpoint. ```java @@ -537,7 +537,7 @@ This would generate n entries of tr for each person in exampleData 3. **Update the Navigation Bar:** - Add a link to the new feature page in the navigation bar. - - Update the `src/main/resources/templates/fragments/navbar.html` file. + - Update the `stirling-pdf/src/main/resources/templates/fragments/navbar.html` file. ```html
DataSource
for the connection to the DB. If useDefault
- * is set to true
, it will use the default H2 DB. If it is set to false
- *
, it will use the user's custom configuration set in the settings.yml.
- *
- * @return a DataSource
using the configuration settings in the settings.yml
- * @throws UnsupportedProviderException if the type of database selected is not supported
- */
- @Bean
- @Qualifier("dataSource")
- public DataSource dataSource() throws UnsupportedProviderException {
- DataSourceBuilder> dataSourceBuilder = DataSourceBuilder.create();
-
- if (!runningProOrHigher) {
- return useDefaultDataSource(dataSourceBuilder);
- }
-
- if (!datasource.isEnableCustomDatabase()) {
- return useDefaultDataSource(dataSourceBuilder);
- }
-
- log.info("Using custom database configuration");
-
- if (!datasource.getCustomDatabaseUrl().isBlank()) {
- if (datasource.getCustomDatabaseUrl().contains("postgresql")) {
- dataSourceBuilder.driverClassName(DatabaseDriver.POSTGRESQL.getDriverClassName());
- }
-
- dataSourceBuilder.url(datasource.getCustomDatabaseUrl());
- } else {
- dataSourceBuilder.driverClassName(getDriverClassName(datasource.getType()));
- dataSourceBuilder.url(
- generateCustomDataSourceUrl(
- datasource.getType(),
- datasource.getHostName(),
- datasource.getPort(),
- datasource.getName()));
- }
- dataSourceBuilder.username(datasource.getUsername());
- dataSourceBuilder.password(datasource.getPassword());
-
- 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
- *
- * @param dataSourceType the type of the database
- * @param hostname the host name
- * @param port the port number to use for the database
- * @param dataSourceName the name the database to connect to
- * @return the DataSource
URL
- */
- private String generateCustomDataSourceUrl(
- String dataSourceType, String hostname, Integer port, String dataSourceName) {
- return DATASOURCE_URL_TEMPLATE.formatted(dataSourceType, hostname, port, dataSourceName);
- }
-
- /**
- * Selects the database driver based on the type of database chosen.
- *
- * @param driverName the type of the driver (e.g. 'h2', 'postgresql')
- * @return the fully qualified driver for the database chosen
- * @throws UnsupportedProviderException when an unsupported database is selected
- */
- private String getDriverClassName(String driverName) throws UnsupportedProviderException {
- try {
- ApplicationProperties.Driver driver =
- ApplicationProperties.Driver.valueOf(driverName.toUpperCase());
-
- switch (driver) {
- case H2 -> {
- log.debug("H2 driver selected");
- return DatabaseDriver.H2.getDriverClassName();
- }
- case POSTGRESQL -> {
- log.debug("Postgres driver selected");
- return DatabaseDriver.POSTGRESQL.getDriverClassName();
- }
- default -> {
- log.warn("{} driver selected", driverName);
- throw new UnsupportedProviderException(
- driverName + " is not currently supported");
- }
- }
- } catch (IllegalArgumentException e) {
- log.warn("Unknown driver: {}", driverName);
- throw new UnsupportedProviderException(driverName + " is not currently supported");
- }
- }
-}
diff --git a/enterprise/src/main/java/stirling/software/enterprise/security/configuration/SecurityConfiguration.java b/enterprise/src/main/java/stirling/software/enterprise/security/configuration/SecurityConfiguration.java
deleted file mode 100644
index ae4c54b5c..000000000
--- a/enterprise/src/main/java/stirling/software/enterprise/security/configuration/SecurityConfiguration.java
+++ /dev/null
@@ -1,321 +0,0 @@
-package stirling.software.enterprise.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.enterprise.security.CustomAuthenticationFailureHandler;
-import stirling.software.enterprise.security.CustomAuthenticationSuccessHandler;
-import stirling.software.enterprise.security.CustomLogoutSuccessHandler;
-import stirling.software.enterprise.security.filter.FirstLoginFilter;
-import stirling.software.enterprise.security.filter.IPRateLimitingFilter;
-import stirling.software.enterprise.security.filter.UserAuthenticationFilter;
-import stirling.software.enterprise.security.database.repository.JPATokenRepositoryImpl;
-import stirling.software.enterprise.security.database.repository.PersistentLoginRepository;
-import stirling.software.enterprise.security.model.User;
-import stirling.software.enterprise.security.oauth2.CustomOAuth2AuthenticationFailureHandler;
-import stirling.software.enterprise.security.oauth2.CustomOAuth2AuthenticationSuccessHandler;
-import stirling.software.enterprise.security.saml2.CustomSaml2AuthenticationFailureHandler;
-import stirling.software.enterprise.security.saml2.CustomSaml2AuthenticationSuccessHandler;
-import stirling.software.enterprise.security.saml2.CustomSaml2ResponseAuthenticationConverter;
-import stirling.software.enterprise.security.service.CustomOAuth2UserService;
-import stirling.software.enterprise.security.service.CustomUserDetailsService;
-import stirling.software.enterprise.security.service.LoginAttemptService;
-import stirling.software.enterprise.security.service.UserService;
-import stirling.software.enterprise.security.session.SessionPersistentRegistry;
-
-@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 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-
-