2025-04-16 17:01:39 +01:00

111 lines
4.2 KiB
Java

package stirling.software.SPDF.config.security;
import java.sql.SQLException;
import java.util.UUID;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.Role;
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
/**
* This class is responsible for the initial security setup of the application. It checks if there
* are any existing users and initializes the admin user if none exist. It also migrates OAuth2
* users to SSO and initializes an internal API user.
*/
@Slf4j
@Component
/*
todo: add @ConditionOnProperty to check if the application is running in a specific environment
add @Profile for enterprise/pro or higher
*/
// @Profile({"pro", "enterprise"})
public class InitialSecuritySetup {
private final UserService userService;
private final ApplicationProperties applicationProperties;
@Lazy 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() {
try {
initialiseDB();
initializeInternalApiUser();
} catch (IllegalArgumentException | SQLException | UnsupportedProviderException e) {
log.error("Failed to initialize security setup.", e);
System.exit(1);
}
}
@ConditionalOnProperty(name = "premium.proFeatures.database", havingValue = "true")
private void initialiseDB() throws SQLException, UnsupportedProviderException {
if (!userService.hasUsers()) {
if (databaseService.hasBackup()) {
databaseService.importDatabase();
} else {
initializeAdminUser();
}
}
userService.migrateOauth2ToSSO();
}
private void initializeAdminUser() throws SQLException, UnsupportedProviderException {
String initialUsername =
applicationProperties.getSecurity().getInitialLogin().getUsername();
String initialPassword =
applicationProperties.getSecurity().getInitialLogin().getPassword();
if (initialUsername != null
&& !initialUsername.isEmpty()
&& initialPassword != null
&& !initialPassword.isEmpty()
&& userService.findByUsernameIgnoreCase(initialUsername).isEmpty()) {
userService.saveUser(initialUsername, initialPassword, Role.ADMIN.getRoleId());
log.info("Admin user created: {}", initialUsername);
} else {
createDefaultAdminUser();
}
}
private void createDefaultAdminUser() throws SQLException, UnsupportedProviderException {
String defaultUsername = "admin";
String defaultPassword = "stirling";
if (userService.findByUsernameIgnoreCase(defaultUsername).isEmpty()) {
userService.saveUser(defaultUsername, defaultPassword, Role.ADMIN.getRoleId(), true);
log.info("Default admin user created: {}", defaultUsername);
}
}
private void initializeInternalApiUser()
throws IllegalArgumentException, SQLException, UnsupportedProviderException {
if (!userService.usernameExistsIgnoreCase(Role.INTERNAL_API_USER.getRoleId())) {
userService.saveUser(
Role.INTERNAL_API_USER.getRoleId(),
UUID.randomUUID().toString(),
Role.INTERNAL_API_USER.getRoleId());
userService.addApiKeyToUser(Role.INTERNAL_API_USER.getRoleId());
log.info("Internal API user created: {}", Role.INTERNAL_API_USER.getRoleId());
}
userService.syncCustomApiUser(applicationProperties.getSecurity().getCustomGlobalAPIKey());
}
}