diff --git a/build.gradle b/build.gradle index a0547ee4..cad901a7 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 0e06d83a..3e848ada 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 f8414275..2e54db8b 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 89124a81..ae346d78 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 42175aef..2cefb74e 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 eab29f3e..d68cadc6 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 8d52b3dd..7af08c99 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 ab1c51df..19e1431b 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 0ed84dc0..8942b0b1 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 74ac58c0..db5c1bab 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 62f0a076..199b6dd3 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 {