diff --git a/build.gradle b/build.gradle index a0547ee4d..cad901a7d 100644 --- a/build.gradle +++ b/build.gradle @@ -72,6 +72,29 @@ sourceSets { } } + + test { + java { + if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") { + exclude "stirling/software/SPDF/config/security/**" + exclude "stirling/software/SPDF/controller/api/UserControllerTest.java" + exclude "stirling/software/SPDF/controller/api/DatabaseControllerTest.java" + exclude "stirling/software/SPDF/controller/web/AccountWebControllerTest.java" + exclude "stirling/software/SPDF/controller/web/DatabaseWebControllerTest.java" + exclude "stirling/software/SPDF/model/ApiKeyAuthenticationTokenTest.java" + exclude "stirling/software/SPDF/model/AttemptCounterTest.java" + exclude "stirling/software/SPDF/model/AuthorityTest.java" + exclude "stirling/software/SPDF/model/PersistentLoginTest.java" + exclude "stirling/software/SPDF/model/SessionEntityTest.java" + exclude "stirling/software/SPDF/model/UserTest.java" + exclude "stirling/software/SPDF/repository/**" + } + + if (System.getenv("STIRLING_PDF_DESKTOP_UI") == "false") { + exclude "stirling/software/SPDF/UI/impl/**" + } + } + } } openApi { diff --git a/exampleYmlFiles/docker-compose-latest-fat-security.yml b/exampleYmlFiles/docker-compose-latest-fat-security.yml index 0e06d83a0..3e848ada1 100644 --- a/exampleYmlFiles/docker-compose-latest-fat-security.yml +++ b/exampleYmlFiles/docker-compose-latest-fat-security.yml @@ -36,7 +36,7 @@ services: SYSTEM_DATASOURCE_HOSTNAME: "db" SYSTEM_DATASOURCE_PORT: "5432" SYSTEM_DATASOURCE_NAME: "stirling_pdf" - SYSTEM_DATASOURCE_USEDEFAULT: "false" + SYSTEM_DATASOURCE_ENABLECUSTOMDATABASE: "false" SYSTEM_DATASOURCE_USERNAME: "admin" SYSTEM_DATASOURCE_PASSWORD: "stirling" restart: on-failure:5 diff --git a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml b/exampleYmlFiles/docker-compose-latest-security-with-sso.yml index f84142757..2e54db8b8 100644 --- a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml +++ b/exampleYmlFiles/docker-compose-latest-security-with-sso.yml @@ -44,7 +44,7 @@ services: SYSTEM_DATASOURCE_HOSTNAME: "db" SYSTEM_DATASOURCE_PORT: "5432" SYSTEM_DATASOURCE_NAME: "stirling_pdf" - SYSTEM_DATASOURCE_USEDEFAULT: "false" + SYSTEM_DATASOURCE_ENABLECUSTOMDATABASE: "false" SYSTEM_DATASOURCE_USERNAME: "admin" SYSTEM_DATASOURCE_PASSWORD: "stirling" restart: on-failure:5 diff --git a/exampleYmlFiles/docker-compose-latest-security.yml b/exampleYmlFiles/docker-compose-latest-security.yml index 89124a810..ae346d789 100644 --- a/exampleYmlFiles/docker-compose-latest-security.yml +++ b/exampleYmlFiles/docker-compose-latest-security.yml @@ -36,7 +36,7 @@ services: SYSTEM_DATASOURCE_HOSTNAME: "db" SYSTEM_DATASOURCE_PORT: "5432" SYSTEM_DATASOURCE_NAME: "stirling_pdf" - SYSTEM_DATASOURCE_USEDEFAULT: "false" + SYSTEM_DATASOURCE_ENABLECUSTOMDATABASE: "false" SYSTEM_DATASOURCE_USERNAME: "admin" SYSTEM_DATASOURCE_PASSWORD: "stirling" restart: on-failure:5 diff --git a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml b/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml index 42175aef7..2cefb74e2 100644 --- a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml +++ b/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml @@ -33,7 +33,7 @@ services: SYSTEM_DATASOURCE_HOSTNAME: "db" SYSTEM_DATASOURCE_PORT: "5432" SYSTEM_DATASOURCE_NAME: "stirling_pdf" - SYSTEM_DATASOURCE_USEDEFAULT: "false" + SYSTEM_DATASOURCE_ENABLECUSTOMDATABASE: "false" SYSTEM_DATASOURCE_USERNAME: "admin" SYSTEM_DATASOURCE_PASSWORD: "stirling" restart: on-failure:5 diff --git a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java index eab29f3e3..d68cadc65 100644 --- a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java +++ b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseConfig.java @@ -1,8 +1,5 @@ package stirling.software.SPDF.config.security.database; -import java.sql.Connection; -import java.sql.SQLException; - import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; @@ -15,16 +12,22 @@ import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.provider.UnsupportedProviderException; -@Getter @Slf4j +@Getter @Configuration public class DatabaseConfig { + public static final String DATASOURCE_DEFAULT_URL = + "jdbc:h2:file:./configs/stirling-pdf-DB-2.3.232;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"; 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 applicationProperties; - public DatabaseConfig(@Autowired ApplicationProperties applicationProperties) { + @Autowired + public DatabaseConfig(ApplicationProperties applicationProperties) { this.applicationProperties = applicationProperties; } @@ -42,12 +45,12 @@ public class DatabaseConfig { ApplicationProperties.Datasource datasource = system.getDatasource(); DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); - if (datasource.isUseDefault()) { + if (datasource.isEnableCustomDatabase()) { log.debug("Using default H2 database"); - dataSourceBuilder.driverClassName("org.h2.Driver"); - dataSourceBuilder.url(datasource.getDefaultUrl()); - dataSourceBuilder.username("sa"); + dataSourceBuilder.driverClassName(DEFAULT_DRIVER); + dataSourceBuilder.url(DATASOURCE_DEFAULT_URL); + dataSourceBuilder.username(DEFAULT_USERNAME); return dataSourceBuilder.build(); } @@ -79,15 +82,6 @@ public class DatabaseConfig { return DATASOURCE_URL_TEMPLATE.formatted(dataSourceType, hostname, port, dataSourceName); } - /** - * @return a Connection using the configured DataSource - * @throws SQLException if a database access error occurs - * @throws UnsupportedProviderException when an unsupported database is selected - */ - public Connection connection() throws SQLException, UnsupportedProviderException { - return dataSource().getConnection(); - } - /** * Selects the database driver based on the type of database chosen. * @@ -103,11 +97,11 @@ public class DatabaseConfig { switch (driver) { case H2 -> { log.debug("H2 driver selected"); - return "org.h2.Driver"; + return DEFAULT_DRIVER; } case POSTGRESQL -> { log.debug("Postgres driver selected"); - return "org.postgresql.Driver"; + return POSTGRES_DRIVER; } default -> { log.warn("{} driver selected", driverName); diff --git a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseService.java b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseService.java index 8d52b3dd2..7af08c99e 100644 --- a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseService.java +++ b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseService.java @@ -18,6 +18,8 @@ import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; +import javax.sql.DataSource; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.PathResource; import org.springframework.core.io.support.EncodedResource; @@ -29,7 +31,6 @@ import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.config.interfaces.DatabaseInterface; import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.exception.BackupNotFoundException; -import stirling.software.SPDF.model.provider.UnsupportedProviderException; import stirling.software.SPDF.utils.FileInfo; @Slf4j @@ -40,7 +41,14 @@ public class DatabaseService implements DatabaseInterface { public static final String SQL_SUFFIX = ".sql"; private static final String BACKUP_DIR = "configs/db/backup/"; - @Autowired private DatabaseConfig databaseConfig; + private final ApplicationProperties applicationProperties; + private final DataSource dataSource; + + @Autowired + public DatabaseService(ApplicationProperties applicationProperties, DataSource dataSource) { + this.applicationProperties = applicationProperties; + this.dataSource = dataSource; + } /** * Checks if there is at least one backup @@ -133,7 +141,7 @@ public class DatabaseService implements DatabaseInterface { /** Filter and delete old backups if there are more than 5 */ @Override - public void exportDatabase() throws SQLException, UnsupportedProviderException { + public void exportDatabase() throws SQLException { List filteredBackupList = this.getBackupList().stream() .filter(backup -> !backup.getFileName().startsWith(BACKUP_PREFIX + "user_")) @@ -148,12 +156,12 @@ public class DatabaseService implements DatabaseInterface { Path insertOutputFilePath = this.getBackupFilePath(BACKUP_PREFIX + dateNow.format(myFormatObj) + SQL_SUFFIX); - try (Connection conn = databaseConfig.connection()) { + try (Connection conn = dataSource.getConnection()) { ScriptUtils.executeSqlScript( conn, new EncodedResource(new PathResource(insertOutputFilePath))); log.info("Database export completed: {}", insertOutputFilePath); - } catch (SQLException | UnsupportedProviderException e) { + } catch (SQLException e) { log.error("Error during database export: {}", e.getMessage(), e); throw e; } catch (ScriptException e) { @@ -184,13 +192,12 @@ public class DatabaseService implements DatabaseInterface { public String getH2Version() { String version = "Unknown"; - if (databaseConfig - .getApplicationProperties() + if (applicationProperties .getSystem() .getDatasource() .getType() .equals(ApplicationProperties.Driver.H2.name())) { - try (Connection conn = databaseConfig.connection()) { + try (Connection conn = dataSource.getConnection()) { try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT H2VERSION() AS version")) { if (rs.next()) { @@ -198,7 +205,7 @@ public class DatabaseService implements DatabaseInterface { log.info("H2 Database Version: {}", version); } } - } catch (SQLException | UnsupportedProviderException e) { + } catch (SQLException e) { log.error("Error retrieving H2 version: {}", e.getMessage(), e); } } @@ -240,14 +247,21 @@ public class DatabaseService implements DatabaseInterface { } private void executeDatabaseScript(Path scriptPath) { - try (Connection conn = databaseConfig.connection()) { - ScriptUtils.executeSqlScript(conn, new EncodedResource(new PathResource(scriptPath))); + if (applicationProperties + .getSystem() + .getDatasource() + .getType() + .equals(ApplicationProperties.Driver.H2.name())) { + try (Connection conn = dataSource.getConnection()) { + ScriptUtils.executeSqlScript( + conn, new EncodedResource(new PathResource(scriptPath))); - log.info("Database import completed: {}", scriptPath); - } catch (SQLException | UnsupportedProviderException e) { - log.error("Error during database import: {}", e.getMessage(), e); - } catch (ScriptException e) { - log.error("Error: File {} not found", scriptPath.toString(), e); + log.info("Database import completed: {}", scriptPath); + } catch (SQLException e) { + log.error("Error during database import: {}", e.getMessage(), e); + } catch (ScriptException e) { + log.error("Error: File {} not found", scriptPath.toString(), e); + } } } diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index ab1c51dfc..19e1431b7 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -252,14 +252,13 @@ public class ApplicationProperties { @Data public static class Datasource { + private boolean enableCustomDatabase; private String type; private String hostName; private Integer port; private String name; private String username; @ToString.Exclude private String password; - private boolean useDefault; - private final String defaultUrl; } public enum Driver { diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index 0ed84dc0d..8942b0b12 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -86,14 +86,13 @@ system: tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored. enableAnalytics: undefined # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true datasource: + enableCustomDatabase: true # set this property to 'true' if you would like to use the default database configuration type: postgresql # the type of the database to set (e.g. 'h2', 'postgresql') hostName: localhost # the host name to use for the database url. Set to 'localhost' when running the app locally. Set to match the name of the container name of your database container when running the app on a server (Docker configuration) port: 5432 # set the port number of the database. Ensure this matches the port the database is listening to name: postgres # set the name of your database. Should match the name of the database you create username: postgres # set the database username password: postgres # set the database password - useDefault: 'true' # set this property to 'true' if you would like to use the default database configuration - defaultUrl: jdbc:h2:file:./configs/stirling-pdf-DB-2.3.232;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE # the default database url for the application ui: appName: '' # application's visible name diff --git a/src/test/java/stirling/software/SPDF/config/security/database/DatabaseConfigTest.java b/src/test/java/stirling/software/SPDF/config/security/database/DatabaseConfigTest.java index 74ac58c0a..db5c1bab1 100644 --- a/src/test/java/stirling/software/SPDF/config/security/database/DatabaseConfigTest.java +++ b/src/test/java/stirling/software/SPDF/config/security/database/DatabaseConfigTest.java @@ -29,12 +29,10 @@ class DatabaseConfigTest { void testDefaultConfigurationForDataSource() throws UnsupportedProviderException { var system = mock(ApplicationProperties.System.class); var datasource = mock(ApplicationProperties.Datasource.class); - var testUrl = "jdbc:h2:mem:test"; when(applicationProperties.getSystem()).thenReturn(system); when(system.getDatasource()).thenReturn(datasource); - when(datasource.isUseDefault()).thenReturn(true); - when(datasource.getDefaultUrl()).thenReturn(testUrl); + when(datasource.isEnableCustomDatabase()).thenReturn(true); var result = databaseConfig.dataSource(); @@ -48,7 +46,7 @@ class DatabaseConfigTest { when(applicationProperties.getSystem()).thenReturn(system); when(system.getDatasource()).thenReturn(datasource); - when(datasource.isUseDefault()).thenReturn(false); + when(datasource.isEnableCustomDatabase()).thenReturn(false); when(datasource.getType()).thenReturn("postgresql"); when(datasource.getHostName()).thenReturn("localhost"); when(datasource.getPort()).thenReturn(5432); @@ -69,7 +67,7 @@ class DatabaseConfigTest { when(applicationProperties.getSystem()).thenReturn(system); when(system.getDatasource()).thenReturn(datasource); - when(datasource.isUseDefault()).thenReturn(false); + when(datasource.isEnableCustomDatabase()).thenReturn(false); when(datasource.getType()).thenReturn(datasourceType); assertThrows(UnsupportedProviderException.class, () -> databaseConfig.dataSource()); diff --git a/src/test/java/stirling/software/SPDF/integrationtests/SPDFApplicationIntegrationTest.java b/src/test/java/stirling/software/SPDF/integrationtests/SPDFApplicationIntegrationTest.java index 62f0a0765..199b6dd30 100644 --- a/src/test/java/stirling/software/SPDF/integrationtests/SPDFApplicationIntegrationTest.java +++ b/src/test/java/stirling/software/SPDF/integrationtests/SPDFApplicationIntegrationTest.java @@ -13,7 +13,6 @@ import static java.nio.file.Files.delete; import static java.nio.file.Files.exists; import static org.junit.jupiter.api.Assertions.assertTrue; -@Disabled @SpringBootTest public class SPDFApplicationIntegrationTest {