|
|
@ -5,6 +5,7 @@ package de.srsoftware.oidc.app; |
|
|
|
import static de.srsoftware.oidc.api.Constants.*; |
|
|
|
import static de.srsoftware.oidc.api.Constants.*; |
|
|
|
import static de.srsoftware.oidc.api.data.Permission.*; |
|
|
|
import static de.srsoftware.oidc.api.data.Permission.*; |
|
|
|
import static de.srsoftware.utils.Optionals.emptyIfBlank; |
|
|
|
import static de.srsoftware.utils.Optionals.emptyIfBlank; |
|
|
|
|
|
|
|
import static de.srsoftware.utils.Optionals.nullable; |
|
|
|
import static de.srsoftware.utils.Paths.configDir; |
|
|
|
import static de.srsoftware.utils.Paths.configDir; |
|
|
|
import static de.srsoftware.utils.Paths.extension; |
|
|
|
import static de.srsoftware.utils.Paths.extension; |
|
|
|
import static de.srsoftware.utils.Strings.uuid; |
|
|
|
import static de.srsoftware.utils.Strings.uuid; |
|
|
@ -61,19 +62,20 @@ public class Application { |
|
|
|
var defaultFile = configDir.resolve("data.json"); |
|
|
|
var defaultFile = configDir.resolve("data.json"); |
|
|
|
var configFile = (argMap.get(CONFIG_PATH) instanceof Path p ? p : configDir.resolve("config.json")).toFile(); |
|
|
|
var configFile = (argMap.get(CONFIG_PATH) instanceof Path p ? p : configDir.resolve("config.json")).toFile(); |
|
|
|
var config = new Configuration(configFile); |
|
|
|
var config = new Configuration(configFile); |
|
|
|
|
|
|
|
var encryptionKey = nullable(System.getenv(ENCRYPTION_KEY)).or(() -> config.get(ENCRYPTION_KEY)); |
|
|
|
var passHasher = new UuidHasher(); |
|
|
|
var passHasher = new UuidHasher(); |
|
|
|
var firstHash = passHasher.hash(FIRST_USER_PASS, FIRST_UUID); |
|
|
|
var firstHash = passHasher.hash(FIRST_USER_PASS, FIRST_UUID); |
|
|
|
var firstUser = new User(FIRST_USER, firstHash, FIRST_USER, "%s@internal".formatted(FIRST_USER), FIRST_UUID).add(MANAGE_CLIENTS, MANAGE_PERMISSIONS, MANAGE_SMTP, MANAGE_USERS); |
|
|
|
var firstUser = new User(FIRST_USER, firstHash, FIRST_USER, "%s@internal".formatted(FIRST_USER), FIRST_UUID).add(MANAGE_CLIENTS, MANAGE_PERMISSIONS, MANAGE_SMTP, MANAGE_USERS); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FileStoreProvider fileStoreProvider = new FileStoreProvider(passHasher); |
|
|
|
FileStoreProvider fileStoreProvider = new FileStoreProvider(passHasher); |
|
|
|
var userService = setupUserService(config, defaultFile, fileStoreProvider, passHasher).init(firstUser); |
|
|
|
var userService = setupUserService(config, encryptionKey, defaultFile, fileStoreProvider, passHasher).init(firstUser); |
|
|
|
var sessionService = setupSessionService(config, defaultFile, fileStoreProvider); |
|
|
|
var sessionService = setupSessionService(config, defaultFile, fileStoreProvider); |
|
|
|
var mailConfig = setupMailConfig(config, defaultFile, fileStoreProvider); |
|
|
|
var mailConfig = setupMailConfig(config, encryptionKey, defaultFile, fileStoreProvider); |
|
|
|
var keyStore = setupKeyStore(config, configDir); |
|
|
|
var keyStore = setupKeyStore(config, encryptionKey, configDir); |
|
|
|
KeyManager keyManager = new RotatingKeyManager(keyStore); |
|
|
|
KeyManager keyManager = new RotatingKeyManager(keyStore); |
|
|
|
var authService = setupAuthService(config, defaultFile, fileStoreProvider); |
|
|
|
var authService = setupAuthService(config, defaultFile, fileStoreProvider); |
|
|
|
var clientService = setupClientService(config, defaultFile, fileStoreProvider); |
|
|
|
var clientService = setupClientService(config, encryptionKey, defaultFile, fileStoreProvider); |
|
|
|
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); |
|
|
|
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); |
|
|
|
var staticPages = (StaticPages) new StaticPages(basePath).bindPath(STATIC_PATH, FAVICON).on(server); |
|
|
|
var staticPages = (StaticPages) new StaticPages(basePath).bindPath(STATIC_PATH, FAVICON).on(server); |
|
|
|
new Forward(INDEX).bindPath(ROOT).on(server); |
|
|
|
new Forward(INDEX).bindPath(ROOT).on(server); |
|
|
@ -88,15 +90,14 @@ public class Application { |
|
|
|
server.start(); |
|
|
|
server.start(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static ClientService setupClientService(Configuration config, Path defaultFile, FileStoreProvider fileStoreProvider) throws SQLException { |
|
|
|
|
|
|
|
|
|
|
|
private static ClientService setupClientService(Configuration config, Optional<String> encryptionKey, Path defaultFile, FileStoreProvider fileStoreProvider) throws SQLException { |
|
|
|
var clientStore = new File(config.getOrDefault("client_store", defaultFile)); |
|
|
|
var clientStore = new File(config.getOrDefault("client_store", defaultFile)); |
|
|
|
var clientService = switch (extension(clientStore)) { |
|
|
|
var clientService = switch (extension(clientStore)) { |
|
|
|
case "db", "sqlite", "sqlite3" -> new SqliteClientService(connectionProvider.get(clientStore)); |
|
|
|
case "db", "sqlite", "sqlite3" -> new SqliteClientService(connectionProvider.get(clientStore)); |
|
|
|
default -> fileStoreProvider.get(clientStore); |
|
|
|
default -> fileStoreProvider.get(clientStore); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Optional<String> encryptionKey = config.get(ENCRYPTION_KEY); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (encryptionKey.isPresent()) { |
|
|
|
if (encryptionKey.isPresent()) { |
|
|
|
var salt = config.getOrDefault(SALT, uuid()); |
|
|
|
var salt = config.getOrDefault(SALT, uuid()); |
|
|
|
clientService = new EncryptedClientService(encryptionKey.get(), salt, clientService); |
|
|
|
clientService = new EncryptedClientService(encryptionKey.get(), salt, clientService); |
|
|
@ -120,15 +121,13 @@ public class Application { |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static MailConfig setupMailConfig(Configuration config, Path defaultFile, FileStoreProvider fileStoreProvider) throws SQLException { |
|
|
|
private static MailConfig setupMailConfig(Configuration config, Optional<String> encryptionKey, Path defaultFile, FileStoreProvider fileStoreProvider) throws SQLException { |
|
|
|
var mailConfigLocation = new File(config.getOrDefault("mail_config_storage", defaultFile)); |
|
|
|
var mailConfigLocation = new File(config.getOrDefault("mail_config_storage", defaultFile)); |
|
|
|
var mailConfig = switch (extension(mailConfigLocation)){ |
|
|
|
var mailConfig = switch (extension(mailConfigLocation)){ |
|
|
|
case "db", "sqlite", "sqlite3" -> new SqliteMailConfig(connectionProvider.get(mailConfigLocation)); |
|
|
|
case "db", "sqlite", "sqlite3" -> new SqliteMailConfig(connectionProvider.get(mailConfigLocation)); |
|
|
|
default -> fileStoreProvider.get(mailConfigLocation); |
|
|
|
default -> fileStoreProvider.get(mailConfigLocation); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Optional<String> encryptionKey = config.get(ENCRYPTION_KEY); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (encryptionKey.isPresent()) { |
|
|
|
if (encryptionKey.isPresent()) { |
|
|
|
var salt = config.getOrDefault(SALT, uuid()); |
|
|
|
var salt = config.getOrDefault(SALT, uuid()); |
|
|
|
mailConfig = new EncryptedMailConfig(mailConfig, encryptionKey.get(), salt); |
|
|
|
mailConfig = new EncryptedMailConfig(mailConfig, encryptionKey.get(), salt); |
|
|
@ -136,15 +135,13 @@ public class Application { |
|
|
|
return mailConfig; |
|
|
|
return mailConfig; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static UserService setupUserService(Configuration config, Path defaultFile, FileStoreProvider fileStoreProvider, UuidHasher passHasher) throws SQLException { |
|
|
|
private static UserService setupUserService(Configuration config, Optional<String> encryptionKey, Path defaultFile, FileStoreProvider fileStoreProvider, UuidHasher passHasher) throws SQLException { |
|
|
|
var userStorageLocation = new File(config.getOrDefault("user_storage", defaultFile)); |
|
|
|
var userStorageLocation = new File(config.getOrDefault("user_storage", defaultFile)); |
|
|
|
var userService = switch (extension(userStorageLocation).toLowerCase()){ |
|
|
|
var userService = switch (extension(userStorageLocation).toLowerCase()){ |
|
|
|
case "db", "sqlite", "sqlite3" -> new SqliteUserService(connectionProvider.get(userStorageLocation),passHasher); |
|
|
|
case "db", "sqlite", "sqlite3" -> new SqliteUserService(connectionProvider.get(userStorageLocation),passHasher); |
|
|
|
default -> fileStoreProvider.get(userStorageLocation); |
|
|
|
default -> fileStoreProvider.get(userStorageLocation); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Optional<String> encryptionKey = config.get(ENCRYPTION_KEY); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (encryptionKey.isPresent()) { |
|
|
|
if (encryptionKey.isPresent()) { |
|
|
|
var salt = config.getOrDefault(SALT, uuid()); |
|
|
|
var salt = config.getOrDefault(SALT, uuid()); |
|
|
|
userService = new EncryptedUserService(userService, encryptionKey.get(), salt, passHasher); |
|
|
|
userService = new EncryptedUserService(userService, encryptionKey.get(), salt, passHasher); |
|
|
@ -152,7 +149,7 @@ public class Application { |
|
|
|
return userService; |
|
|
|
return userService; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static KeyStorage setupKeyStore(Configuration config, Path defaultConfigDir) throws SQLException { |
|
|
|
private static KeyStorage setupKeyStore(Configuration config, Optional<String> encryptionKey, Path defaultConfigDir) throws SQLException { |
|
|
|
var keyStorageLocation = new File(config.getOrDefault("key_storage", defaultConfigDir.resolve("keys"))); |
|
|
|
var keyStorageLocation = new File(config.getOrDefault("key_storage", defaultConfigDir.resolve("keys"))); |
|
|
|
KeyStorage keyStore = null; |
|
|
|
KeyStorage keyStore = null; |
|
|
|
if ((keyStorageLocation.exists() && keyStorageLocation.isDirectory()) || !keyStorageLocation.getName().contains(".")) { |
|
|
|
if ((keyStorageLocation.exists() && keyStorageLocation.isDirectory()) || !keyStorageLocation.getName().contains(".")) { |
|
|
@ -162,8 +159,6 @@ public class Application { |
|
|
|
keyStore = new SqliteKeyStore(conn); |
|
|
|
keyStore = new SqliteKeyStore(conn); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Optional<String> encryptionKey = config.get(ENCRYPTION_KEY); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (encryptionKey.isPresent()) { |
|
|
|
if (encryptionKey.isPresent()) { |
|
|
|
var salt = config.getOrDefault(SALT, uuid()); |
|
|
|
var salt = config.getOrDefault(SALT, uuid()); |
|
|
|
keyStore = new EncryptedKeyStore(encryptionKey.get(), salt, keyStore); |
|
|
|
keyStore = new EncryptedKeyStore(encryptionKey.get(), salt, keyStore); |
|
|
|