diff --git a/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java b/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java index 7d0d5df2..c521d2ca 100644 --- a/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java +++ b/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java @@ -3,7 +3,6 @@ package stirling.software.SPDF.config.security; import java.sql.SQLException; import java.util.UUID; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import jakarta.annotation.PostConstruct; @@ -17,11 +16,20 @@ import stirling.software.SPDF.model.provider.UnsupportedProviderException; @Component public class InitialSecuritySetup { - @Autowired private UserService userService; + private final UserService userService; - @Autowired private ApplicationProperties applicationProperties; + private final ApplicationProperties applicationProperties; - @Autowired private DatabaseInterface databaseService; + private final DatabaseInterface databaseService; + + public InitialSecuritySetup( + UserService userService, + ApplicationProperties applicationProperties, + DatabaseInterface databaseService) { + this.userService = userService; + this.applicationProperties = applicationProperties; + this.databaseService = databaseService; + } @PostConstruct public void init() { 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 ca1ccbb5..9f1850f6 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 @@ -2,7 +2,6 @@ package stirling.software.SPDF.config.security.database; import javax.sql.DataSource; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; @@ -28,7 +27,6 @@ public class DatabaseConfig { private final ApplicationProperties applicationProperties; private final boolean runningEE; - @Autowired public DatabaseConfig(ApplicationProperties applicationProperties, boolean runningEE) { this.applicationProperties = applicationProperties; this.runningEE = true; // fixMe: change back 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 6dc9263c..0219e80a 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 @@ -20,7 +20,6 @@ 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; import org.springframework.jdbc.datasource.init.CannotReadScriptException; @@ -45,7 +44,6 @@ public class DatabaseService implements DatabaseInterface { private final ApplicationProperties applicationProperties; private final DataSource dataSource; - @Autowired public DatabaseService(ApplicationProperties applicationProperties, DataSource dataSource) { this.applicationProperties = applicationProperties; this.dataSource = dataSource; @@ -75,33 +73,39 @@ public class DatabaseService implements DatabaseInterface { @Override public List getBackupList() { List backupFiles = new ArrayList<>(); - Path backupPath = Paths.get(BACKUP_DIR); - try (DirectoryStream stream = - Files.newDirectoryStream( - backupPath, - path -> - path.getFileName().toString().startsWith(BACKUP_PREFIX) - && path.getFileName().toString().endsWith(SQL_SUFFIX))) { - for (Path entry : stream) { - BasicFileAttributes attrs = Files.readAttributes(entry, BasicFileAttributes.class); - LocalDateTime modificationDate = - LocalDateTime.ofInstant( - attrs.lastModifiedTime().toInstant(), ZoneId.systemDefault()); - LocalDateTime creationDate = - LocalDateTime.ofInstant( - attrs.creationTime().toInstant(), ZoneId.systemDefault()); - long fileSize = attrs.size(); - backupFiles.add( - new FileInfo( - entry.getFileName().toString(), - entry.toString(), - modificationDate, - fileSize, - creationDate)); + if (isH2Database()) { + Path backupPath = Paths.get(BACKUP_DIR); + + try (DirectoryStream stream = + Files.newDirectoryStream( + backupPath, + path -> + path.getFileName().toString().startsWith(BACKUP_PREFIX) + && path.getFileName() + .toString() + .endsWith(SQL_SUFFIX))) { + for (Path entry : stream) { + BasicFileAttributes attrs = + Files.readAttributes(entry, BasicFileAttributes.class); + LocalDateTime modificationDate = + LocalDateTime.ofInstant( + attrs.lastModifiedTime().toInstant(), ZoneId.systemDefault()); + LocalDateTime creationDate = + LocalDateTime.ofInstant( + attrs.creationTime().toInstant(), ZoneId.systemDefault()); + long fileSize = attrs.size(); + backupFiles.add( + new FileInfo( + entry.getFileName().toString(), + entry.toString(), + modificationDate, + fileSize, + creationDate)); + } + } catch (IOException e) { + log.error("Error reading backup directory: {}", e.getMessage(), e); } - } catch (IOException e) { - log.error("Error reading backup directory: {}", e.getMessage(), e); } return backupFiles; @@ -196,11 +200,7 @@ public class DatabaseService implements DatabaseInterface { public String getH2Version() { String version = "Unknown"; - if (applicationProperties - .getSystem() - .getDatasource() - .getType() - .equals(ApplicationProperties.Driver.H2.name())) { + if (isH2Database()) { try (Connection conn = dataSource.getConnection()) { try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT H2VERSION() AS version")) { @@ -217,6 +217,13 @@ public class DatabaseService implements DatabaseInterface { return version; } + private boolean isH2Database() { + ApplicationProperties.Datasource datasource = + applicationProperties.getSystem().getDatasource(); + return !datasource.isEnableCustomDatabase() + || datasource.getType().equals(ApplicationProperties.Driver.H2.name()); + } + /** * Deletes a backup file. * @@ -251,11 +258,7 @@ public class DatabaseService implements DatabaseInterface { } private void executeDatabaseScript(Path scriptPath) { - if (applicationProperties - .getSystem() - .getDatasource() - .getType() - .equals(ApplicationProperties.Driver.H2.name())) { + if (isH2Database()) { try (Connection conn = dataSource.getConnection()) { ScriptUtils.executeSqlScript( conn, new EncodedResource(new PathResource(scriptPath))); diff --git a/src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java b/src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java index 657bfd9f..8a5231c7 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java @@ -77,8 +77,7 @@ public class DatabaseController { @GetMapping("/import-database-file/{fileName}") public String importDatabaseFromBackupUI( @Parameter(description = "Name of the file to import", required = true) @PathVariable - String fileName) - throws IOException { + String fileName) { if (fileName == null || fileName.isEmpty()) { return "redirect:/database?error=fileNullOrEmpty"; } diff --git a/src/main/java/stirling/software/SPDF/model/SessionEntity.java b/src/main/java/stirling/software/SPDF/model/SessionEntity.java index 3b4989d5..2742ed96 100644 --- a/src/main/java/stirling/software/SPDF/model/SessionEntity.java +++ b/src/main/java/stirling/software/SPDF/model/SessionEntity.java @@ -15,7 +15,7 @@ import lombok.Data; public class SessionEntity implements Serializable { @Id private String sessionId; - @Lob private String principalName; + private String principalName; private Date lastRequest; diff --git a/src/main/java/stirling/software/SPDF/model/User.java b/src/main/java/stirling/software/SPDF/model/User.java index 56bcdf33..23334724 100644 --- a/src/main/java/stirling/software/SPDF/model/User.java +++ b/src/main/java/stirling/software/SPDF/model/User.java @@ -47,7 +47,7 @@ public class User implements Serializable { @ElementCollection @MapKeyColumn(name = "setting_key") @Lob - @Column(name = "setting_value", columnDefinition = "CLOB") + @Column(name = "setting_value", columnDefinition = "text") @CollectionTable(name = "user_settings", joinColumns = @JoinColumn(name = "user_id")) private Map settings = new HashMap<>(); // Key-value pairs of settings. diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index 28fe882a..519b6f6e 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -87,7 +87,7 @@ system: 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 your own custom database configuration - customDatabaseUrl: jdbc:postgresql://localhost:5432/postgres # set the url for your own custom database connection + customDatabaseUrl: jdbc:postgresql://localhost:5432/postgres # set the url for your own custom database connection. If provided, the type, hostName, port and name are not necessary and will not be used 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 diff --git a/src/test/java/stirling/software/SPDF/config/security/database/DatabaseServiceTest.java b/src/test/java/stirling/software/SPDF/config/security/database/DatabaseServiceTest.java index 2b2aef4f..45ef8b23 100644 --- a/src/test/java/stirling/software/SPDF/config/security/database/DatabaseServiceTest.java +++ b/src/test/java/stirling/software/SPDF/config/security/database/DatabaseServiceTest.java @@ -1,7 +1,10 @@ package stirling.software.SPDF.config.security.database; -import java.nio.file.attribute.FileAttribute; -import org.junit.jupiter.api.AfterEach; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import javax.sql.DataSource; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -9,13 +12,11 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import static org.junit.jupiter.api.Assertions.*; +import stirling.software.SPDF.model.ApplicationProperties; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class DatabaseServiceTest { @@ -24,7 +25,10 @@ class DatabaseServiceTest { private final String BACKUP_PATH = "configs/db/backup/"; @Mock - private DatabaseConfig databaseConfig; + private ApplicationProperties applicationProperties; + + @Mock + private DataSource dataSource; @InjectMocks private DatabaseService databaseService; @@ -36,6 +40,13 @@ class DatabaseServiceTest { @Test void testHasNoBackups() { + ApplicationProperties.System system = mock(ApplicationProperties.System.class); + ApplicationProperties.Datasource datasource = mock(ApplicationProperties.Datasource.class); + + when(applicationProperties.getSystem()).thenReturn(system); + when(system.getDatasource()).thenReturn(datasource); + when(datasource.isEnableCustomDatabase()).thenReturn(false); + assertFalse(databaseService.hasBackup()); }