mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-04-08 01:16:26 +02:00
#2270: clean up
This commit is contained in:
parent
3918a5ede9
commit
2ec6c98e0b
@ -9,5 +9,9 @@ import stirling.software.SPDF.utils.FileInfo;
|
|||||||
public interface DatabaseInterface {
|
public interface DatabaseInterface {
|
||||||
void exportDatabase() throws SQLException, UnsupportedProviderException;
|
void exportDatabase() throws SQLException, UnsupportedProviderException;
|
||||||
|
|
||||||
|
void importDatabase();
|
||||||
|
|
||||||
|
boolean hasBackup();
|
||||||
|
|
||||||
List<FileInfo> getBackupList();
|
List<FileInfo> getBackupList();
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,10 @@ public class InitialSecuritySetup {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
try {
|
try {
|
||||||
|
if (databaseService.hasBackup()) {
|
||||||
|
databaseService.importDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
if (!userService.hasUsers()) {
|
if (!userService.hasUsers()) {
|
||||||
initializeAdminUser();
|
initializeAdminUser();
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
import stirling.software.SPDF.model.exception.BackupNotFoundException;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
||||||
import stirling.software.SPDF.utils.FileInfo;
|
import stirling.software.SPDF.utils.FileInfo;
|
||||||
|
|
||||||
@ -37,19 +38,35 @@ public class DatabaseService implements DatabaseInterface {
|
|||||||
|
|
||||||
public static final String BACKUP_PREFIX = "backup_";
|
public static final String BACKUP_PREFIX = "backup_";
|
||||||
public static final String SQL_SUFFIX = ".sql";
|
public static final String SQL_SUFFIX = ".sql";
|
||||||
private static final Path BACKUP_PATH = Paths.get("configs/db/backup/");
|
private static final String BACKUP_DIR = "configs/db/backup/";
|
||||||
|
|
||||||
@Autowired private DatabaseConfig databaseConfig;
|
@Autowired private DatabaseConfig databaseConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if there is at least one backup
|
||||||
|
*
|
||||||
|
* @return true if there are backup scripts, false if there are not
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasBackup() {
|
||||||
|
Path filePath = Paths.get(BACKUP_DIR + "*");
|
||||||
|
|
||||||
|
return Files.exists(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the backup directory and filter for files with the prefix "backup_" and suffix ".sql"
|
||||||
|
*
|
||||||
|
* @return a <code>List</code> of backup files
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<FileInfo> getBackupList() {
|
public List<FileInfo> getBackupList() {
|
||||||
List<FileInfo> backupFiles = new ArrayList<>();
|
List<FileInfo> backupFiles = new ArrayList<>();
|
||||||
|
Path backupPath = Paths.get(BACKUP_DIR);
|
||||||
|
|
||||||
// Read the backup directory and filter for files with the prefix "backup_" and suffix
|
|
||||||
// ".sql"
|
|
||||||
try (DirectoryStream<Path> stream =
|
try (DirectoryStream<Path> stream =
|
||||||
Files.newDirectoryStream(
|
Files.newDirectoryStream(
|
||||||
BACKUP_PATH,
|
backupPath,
|
||||||
path ->
|
path ->
|
||||||
path.getFileName().toString().startsWith(BACKUP_PREFIX)
|
path.getFileName().toString().startsWith(BACKUP_PREFIX)
|
||||||
&& path.getFileName().toString().endsWith(SQL_SUFFIX))) {
|
&& path.getFileName().toString().endsWith(SQL_SUFFIX))) {
|
||||||
@ -77,7 +94,17 @@ public class DatabaseService implements DatabaseInterface {
|
|||||||
return backupFiles;
|
return backupFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Imports a database backup from the specified file.
|
@Override
|
||||||
|
public void importDatabase() {
|
||||||
|
if (!hasBackup()) throw new BackupNotFoundException("No backup scripts were found.");
|
||||||
|
|
||||||
|
List<FileInfo> backupList = this.getBackupList();
|
||||||
|
backupList.sort(Comparator.comparing(FileInfo::getModificationDate).reversed());
|
||||||
|
|
||||||
|
executeDatabaseScript(Paths.get(backupList.get(0).getFilePath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Imports a database backup from the specified file. */
|
||||||
public boolean importDatabaseFromUI(String fileName) {
|
public boolean importDatabaseFromUI(String fileName) {
|
||||||
try {
|
try {
|
||||||
importDatabaseFromUI(getBackupFilePath(fileName));
|
importDatabaseFromUI(getBackupFilePath(fileName));
|
||||||
@ -92,7 +119,7 @@ public class DatabaseService implements DatabaseInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Imports a database backup from the specified path.
|
/** Imports a database backup from the specified path. */
|
||||||
private void importDatabaseFromUI(Path tempTemplatePath) throws IOException {
|
private void importDatabaseFromUI(Path tempTemplatePath) throws IOException {
|
||||||
executeDatabaseScript(tempTemplatePath);
|
executeDatabaseScript(tempTemplatePath);
|
||||||
LocalDateTime dateNow = LocalDateTime.now();
|
LocalDateTime dateNow = LocalDateTime.now();
|
||||||
@ -104,9 +131,9 @@ public class DatabaseService implements DatabaseInterface {
|
|||||||
Files.deleteIfExists(tempTemplatePath);
|
Files.deleteIfExists(tempTemplatePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Filter and delete old backups if there are more than 5 */
|
||||||
@Override
|
@Override
|
||||||
public void exportDatabase() throws SQLException, UnsupportedProviderException {
|
public void exportDatabase() throws SQLException, UnsupportedProviderException {
|
||||||
// Filter and delete old backups if there are more than 5
|
|
||||||
List<FileInfo> filteredBackupList =
|
List<FileInfo> filteredBackupList =
|
||||||
this.getBackupList().stream()
|
this.getBackupList().stream()
|
||||||
.filter(backup -> !backup.getFileName().startsWith(BACKUP_PREFIX + "user_"))
|
.filter(backup -> !backup.getFileName().startsWith(BACKUP_PREFIX + "user_"))
|
||||||
@ -149,7 +176,11 @@ public class DatabaseService implements DatabaseInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves the H2 database version.
|
/**
|
||||||
|
* Retrieves the H2 database version.
|
||||||
|
*
|
||||||
|
* @return <code>String</code> of the H2 version
|
||||||
|
*/
|
||||||
public String getH2Version() {
|
public String getH2Version() {
|
||||||
String version = "Unknown";
|
String version = "Unknown";
|
||||||
|
|
||||||
@ -175,7 +206,11 @@ public class DatabaseService implements DatabaseInterface {
|
|||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deletes a backup file.
|
/**
|
||||||
|
* Deletes a backup file.
|
||||||
|
*
|
||||||
|
* @return true if successful, false if not
|
||||||
|
*/
|
||||||
public boolean deleteBackupFile(String fileName) throws IOException {
|
public boolean deleteBackupFile(String fileName) throws IOException {
|
||||||
if (!isValidFileName(fileName)) {
|
if (!isValidFileName(fileName)) {
|
||||||
log.error("Invalid file name: {}", fileName);
|
log.error("Invalid file name: {}", fileName);
|
||||||
@ -191,10 +226,14 @@ public class DatabaseService implements DatabaseInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the Path object for a given backup file name.
|
/**
|
||||||
|
* Gets the Path for a given backup file name.
|
||||||
|
*
|
||||||
|
* @return the <code>Path</code> object for the given file name
|
||||||
|
*/
|
||||||
public Path getBackupFilePath(String fileName) {
|
public Path getBackupFilePath(String fileName) {
|
||||||
Path filePath = Paths.get(BACKUP_PATH.toString(), fileName).normalize();
|
Path filePath = Paths.get(BACKUP_DIR, fileName).normalize();
|
||||||
if (!filePath.startsWith(BACKUP_PATH)) {
|
if (!filePath.startsWith(BACKUP_DIR)) {
|
||||||
throw new SecurityException("Path traversal detected");
|
throw new SecurityException("Path traversal detected");
|
||||||
}
|
}
|
||||||
return filePath;
|
return filePath;
|
||||||
@ -212,8 +251,12 @@ public class DatabaseService implements DatabaseInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for invalid characters or sequences
|
||||||
|
*
|
||||||
|
* @return true if it contains no invalid characters, false if it does
|
||||||
|
*/
|
||||||
private boolean isValidFileName(String fileName) {
|
private boolean isValidFileName(String fileName) {
|
||||||
// Check for invalid characters or sequences
|
|
||||||
return fileName != null
|
return fileName != null
|
||||||
&& !fileName.contains("..")
|
&& !fileName.contains("..")
|
||||||
&& !fileName.contains("/")
|
&& !fileName.contains("/")
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package stirling.software.SPDF.model.exception;
|
||||||
|
|
||||||
|
public class BackupNotFoundException extends RuntimeException {
|
||||||
|
public BackupNotFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package stirling.software.SPDF.config.security.database;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
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.*;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class DatabaseServiceTest {
|
||||||
|
|
||||||
|
private final Path BACKUP_PATH = Paths.get("configs/db/backup/*");
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private DatabaseConfig databaseConfig;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private DatabaseService databaseService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHasBackups() throws IOException {
|
||||||
|
Files.createDirectories(BACKUP_PATH);
|
||||||
|
|
||||||
|
assertTrue(databaseService.hasBackup());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user