2023-08-13 01:14:14 +01:00
package stirling.software.SPDF.config.security ;
2023-08-27 00:39:22 +01:00
import java.io.IOException ;
import java.nio.file.Files ;
import java.nio.file.Path ;
import java.nio.file.Paths ;
import java.util.List ;
import java.util.UUID ;
2024-05-12 19:58:34 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2023-08-13 01:14:14 +01:00
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Component ;
import jakarta.annotation.PostConstruct ;
2023-08-26 17:30:49 +01:00
import stirling.software.SPDF.model.ApplicationProperties ;
2023-08-13 01:14:14 +01:00
import stirling.software.SPDF.model.Role ;
2023-12-30 19:11:27 +00:00
2023-08-13 01:14:14 +01:00
@Component
2023-08-27 11:59:08 +01:00
public class InitialSecuritySetup {
2023-08-13 01:14:14 +01:00
2023-08-26 17:30:49 +01:00
@Autowired private UserService userService ;
2023-09-02 00:05:50 +01:00
2023-08-26 22:33:23 +01:00
@Autowired ApplicationProperties applicationProperties ;
2023-08-26 17:30:49 +01:00
2024-05-12 19:58:34 +02:00
private static final Logger logger = LoggerFactory . getLogger ( InitialSecuritySetup . class );
2023-08-26 17:30:49 +01:00
@PostConstruct
public void init () {
if ( ! userService . hasUsers ()) {
2023-08-26 22:33:23 +01:00
2023-09-29 23:58:37 +01:00
String initialUsername =
applicationProperties . getSecurity (). getInitialLogin (). getUsername ();
String initialPassword =
applicationProperties . getSecurity (). getInitialLogin (). getPassword ();
2024-05-12 20:17:46 +02:00
if ( initialUsername != null && initialPassword != null ) {
2024-05-12 19:58:34 +02:00
try {
2024-05-12 20:17:46 +02:00
// https://github.com/Stirling-Tools/Stirling-PDF/issues/976
userService . isUsernameValidWithReturn ( initialUsername );
} catch ( IllegalArgumentException e ) {
Path pathToFile = Paths . get ( "configs/settings.yml" );
2024-05-18 19:38:39 +01:00
if ( Files . exists ( pathToFile )) {
logger . error (
"Invalid initial username provided , username can only contain letters, numbers and the following special characters @._+- or must be a valid email address." );
System . exit ( 1 );
2024-05-12 19:58:34 +02:00
}
2024-05-12 20:17:46 +02:00
throw e ;
2024-05-12 19:58:34 +02:00
}
2023-09-29 23:58:37 +01:00
userService . saveUser ( initialUsername , initialPassword , Role . ADMIN . getRoleId ());
2023-12-30 19:11:27 +00:00
} else {
2023-09-29 23:58:37 +01:00
initialUsername = "admin" ;
initialPassword = "stirling" ;
userService . saveUser (
initialUsername , initialPassword , Role . ADMIN . getRoleId (), true );
2023-12-30 19:11:27 +00:00
}
}
2024-04-14 23:07:03 +02:00
if ( ! userService . usernameExistsIgnoreCase ( Role . INTERNAL_API_USER . getRoleId ())) {
2023-12-25 12:58:49 +00:00
userService . saveUser (
Role . INTERNAL_API_USER . getRoleId (),
UUID . randomUUID (). toString (),
Role . INTERNAL_API_USER . getRoleId ());
2023-12-24 17:12:32 +00:00
userService . addApiKeyToUser ( Role . INTERNAL_API_USER . getRoleId ());
2023-12-30 19:11:27 +00:00
}
}
2023-08-26 17:30:49 +01:00
@PostConstruct
public void initSecretKey () throws IOException {
String secretKey = applicationProperties . getAutomaticallyGenerated (). getKey ();
2024-05-03 20:43:48 +01:00
if ( ! isValidUUID ( secretKey )) {
2023-08-26 17:30:49 +01:00
secretKey = UUID . randomUUID (). toString (); // Generating a random UUID as the secret key
saveKeyToConfig ( secretKey );
}
}
private void saveKeyToConfig ( String key ) throws IOException {
2023-08-26 22:33:23 +01:00
Path path = Paths . get ( "configs" , "settings.yml" ); // Target the configs/settings.yml
2023-08-26 17:30:49 +01:00
List < String > lines = Files . readAllLines ( path );
boolean keyFound = false ;
// Search for the existing key to replace it or place to add it
for ( int i = 0 ; i < lines . size (); i ++ ) {
if ( lines . get ( i ). startsWith ( "AutomaticallyGenerated:" )) {
keyFound = true ;
if ( i + 1 < lines . size () && lines . get ( i + 1 ). trim (). startsWith ( "key:" )) {
lines . set ( i + 1 , " key: " + key );
break ;
} else {
lines . add ( i + 1 , " key: " + key );
break ;
}
}
}
// If the section doesn't exist, append it
if ( ! keyFound ) {
lines . add ( "# Automatically Generated Settings (Do Not Edit Directly)" );
lines . add ( "AutomaticallyGenerated:" );
lines . add ( " key: " + key );
}
// Write back to the file
Files . write ( path , lines );
}
2024-05-05 13:33:17 +01:00
2024-05-03 20:43:48 +01:00
private boolean isValidUUID ( String uuid ) {
if ( uuid == null ) {
return false ;
}
try {
UUID . fromString ( uuid );
return true ;
} catch ( IllegalArgumentException e ) {
return false ;
}
}
2023-08-26 17:30:49 +01:00
}