adding checks for H2

This commit is contained in:
Dario Ghunney Ware 2025-01-02 15:53:49 +00:00
parent 6b9d85a119
commit db1af5c8cf
8 changed files with 77 additions and 58 deletions

View File

@ -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() {

View File

@ -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

View File

@ -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<FileInfo> getBackupList() {
List<FileInfo> backupFiles = new ArrayList<>();
Path backupPath = Paths.get(BACKUP_DIR);
try (DirectoryStream<Path> 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<Path> 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)));

View File

@ -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";
}

View File

@ -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;

View File

@ -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<String, String> settings = new HashMap<>(); // Key-value pairs of settings.

View File

@ -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

View File

@ -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());
}