From 58937a6e9187bf80a8c666cb5e63bfc3289438cc Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Fri, 9 May 2025 16:48:48 +0100 Subject: [PATCH] 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); - } -}