mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 16:20:04 +00:00
Refactored ConfigProperties
This commit is contained in:
@@ -43,11 +43,11 @@ class ConfigEndpoint(
|
|||||||
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
fun isSsoEnabled(): Boolean? {
|
fun isSsoEnabled(): Boolean? {
|
||||||
return config.get(ConfigProperties.SsoEnabled)
|
return config.get(ConfigProperties.SSO.OIDC.Enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
fun getLogoutUrl(): String? {
|
fun getLogoutUrl(): String? {
|
||||||
return config.get(ConfigProperties.SsoLogoutUrl)
|
return config.get(ConfigProperties.SSO.OIDC.LogoutUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,119 +13,133 @@ sealed class ConfigProperties<T : Serializable>(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
/** Libraries */
|
/** Libraries */
|
||||||
data object LibraryAllowPublicAccess : ConfigProperties<Boolean>(
|
sealed class Libraries {
|
||||||
Boolean::class,
|
data object AllowPublicAccess : ConfigProperties<Boolean>(
|
||||||
"library.allow-public-access",
|
Boolean::class,
|
||||||
"Allow access to game libraries without login",
|
"library.allow-public-access",
|
||||||
false
|
"Allow access to game libraries without login",
|
||||||
)
|
false
|
||||||
|
)
|
||||||
|
|
||||||
data object LibraryEnableFilesystemWatcher : ConfigProperties<Boolean>(
|
sealed class Scan {
|
||||||
Boolean::class,
|
data object EnableFilesystemWatcher : ConfigProperties<Boolean>(
|
||||||
"library.scan.enable-filesystem-watcher",
|
Boolean::class,
|
||||||
"Enable automatic library scanning using file system watchers",
|
"library.scan.enable-filesystem-watcher",
|
||||||
true
|
"Enable automatic library scanning using file system watchers",
|
||||||
)
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
data object LibraryMetadataUpdateEnabled : ConfigProperties<Boolean>(
|
sealed class Metadata {
|
||||||
Boolean::class,
|
data object UpdateEnabled : ConfigProperties<Boolean>(
|
||||||
"library.metadata.update.enabled",
|
Boolean::class,
|
||||||
"Enable periodic refresh of video game metadata",
|
"library.metadata.update.enabled",
|
||||||
true
|
"Enable periodic refresh of video game metadata",
|
||||||
)
|
true
|
||||||
|
)
|
||||||
|
|
||||||
data object LibraryMetadataUpdateSchedule : ConfigProperties<String>(
|
data object UpdateSchedule : ConfigProperties<String>(
|
||||||
String::class,
|
String::class,
|
||||||
"library.metadata.update.schedule",
|
"library.metadata.update.schedule",
|
||||||
"Schedule for periodic metadata refresh in cron format",
|
"Schedule for periodic metadata refresh in cron format",
|
||||||
"0 0 * * 0"
|
"0 0 * * 0"
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** User management */
|
/** User management */
|
||||||
data object UsersAllowNewSignUps : ConfigProperties<Boolean>(
|
sealed class Users {
|
||||||
Boolean::class,
|
sealed class SignUps {
|
||||||
"users.sign-ups.allow",
|
data object Allow : ConfigProperties<Boolean>(
|
||||||
"Allow new users to sign up by themselves",
|
Boolean::class,
|
||||||
false
|
"users.sign-ups.allow",
|
||||||
)
|
"Allow new users to sign up by themselves",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
data object UsersConfirmNewSignUps : ConfigProperties<Boolean>(
|
data object Confirm : ConfigProperties<Boolean>(
|
||||||
Boolean::class,
|
Boolean::class,
|
||||||
"users.sign-ups.confirm",
|
"users.sign-ups.confirm",
|
||||||
"Admins need to confirm new users",
|
"Admins need to confirm new users",
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Single Sign-On */
|
/** Single Sign-On */
|
||||||
data object SsoEnabled : ConfigProperties<Boolean>(
|
sealed class SSO {
|
||||||
Boolean::class,
|
sealed class OIDC {
|
||||||
"sso.oidc.enabled",
|
data object Enabled : ConfigProperties<Boolean>(
|
||||||
"Enable SSO via OIDC/OAuth2",
|
Boolean::class,
|
||||||
false
|
"sso.oidc.enabled",
|
||||||
)
|
"Enable SSO via OIDC/OAuth2",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
data object SsoClientId : ConfigProperties<String>(
|
data object MatchExistingUsersBy : ConfigProperties<MatchUsersBy>(
|
||||||
String::class,
|
MatchUsersBy::class,
|
||||||
"sso.oidc.client-id",
|
"sso.oidc.match-existing-users-by",
|
||||||
"Client ID"
|
"Match existing users by",
|
||||||
)
|
MatchUsersBy.username,
|
||||||
|
MatchUsersBy.entries
|
||||||
|
)
|
||||||
|
|
||||||
data object SsoClientSecret : ConfigProperties<String>(
|
data object AutoRegisterNewUsers : ConfigProperties<Boolean>(
|
||||||
String::class,
|
Boolean::class,
|
||||||
"sso.oidc.client-secret",
|
"sso.oidc.auto-register-new-users",
|
||||||
"Client secret"
|
"Automatically create new users after registration",
|
||||||
)
|
true
|
||||||
|
)
|
||||||
|
|
||||||
data object SsoIssuerUrl : ConfigProperties<String>(
|
data object ClientId : ConfigProperties<String>(
|
||||||
String::class,
|
String::class,
|
||||||
"sso.oidc.issuer-url",
|
"sso.oidc.client-id",
|
||||||
"Issuer URL"
|
"Client ID"
|
||||||
)
|
)
|
||||||
|
|
||||||
data object SsoAuthorizeUrl : ConfigProperties<String>(
|
data object ClientSecret : ConfigProperties<String>(
|
||||||
String::class,
|
String::class,
|
||||||
"sso.oidc.authorize-url",
|
"sso.oidc.client-secret",
|
||||||
"Authorize URL"
|
"Client secret"
|
||||||
)
|
)
|
||||||
|
|
||||||
data object SsoTokenUrl : ConfigProperties<String>(
|
data object IssuerUrl : ConfigProperties<String>(
|
||||||
String::class,
|
String::class,
|
||||||
"sso.oidc.token-url",
|
"sso.oidc.issuer-url",
|
||||||
"Token URL"
|
"Issuer URL"
|
||||||
)
|
)
|
||||||
|
|
||||||
data object SsoUserInfoUrl : ConfigProperties<String>(
|
data object AuthorizeUrl : ConfigProperties<String>(
|
||||||
String::class,
|
String::class,
|
||||||
"sso.oidc.userinfo-url",
|
"sso.oidc.authorize-url",
|
||||||
"Userinfo URL"
|
"Authorize URL"
|
||||||
)
|
)
|
||||||
|
|
||||||
data object SsoJwksUrl : ConfigProperties<String>(
|
data object TokenUrl : ConfigProperties<String>(
|
||||||
String::class,
|
String::class,
|
||||||
"sso.oidc.jwks-url",
|
"sso.oidc.token-url",
|
||||||
"JWKS URL"
|
"Token URL"
|
||||||
)
|
)
|
||||||
|
|
||||||
data object SsoLogoutUrl : ConfigProperties<String>(
|
data object UserInfoUrl : ConfigProperties<String>(
|
||||||
String::class,
|
String::class,
|
||||||
"sso.oidc.logout-url",
|
"sso.oidc.userinfo-url",
|
||||||
"Logout URL"
|
"Userinfo URL"
|
||||||
)
|
)
|
||||||
|
|
||||||
data object SsoMatchExistingUsersBy : ConfigProperties<MatchUsersBy>(
|
data object JwksUrl : ConfigProperties<String>(
|
||||||
MatchUsersBy::class,
|
String::class,
|
||||||
"sso.oidc.match-existing-users-by",
|
"sso.oidc.jwks-url",
|
||||||
"Match existing users by",
|
"JWKS URL"
|
||||||
MatchUsersBy.username,
|
)
|
||||||
MatchUsersBy.entries
|
|
||||||
)
|
|
||||||
|
|
||||||
data object SsoAutoRegisterNewUsers : ConfigProperties<Boolean>(
|
data object LogoutUrl : ConfigProperties<String>(
|
||||||
Boolean::class,
|
String::class,
|
||||||
"sso.oidc.auto-register-new-users",
|
"sso.oidc.logout-url",
|
||||||
"Automatically create new users after registration",
|
"Logout URL"
|
||||||
true
|
)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Notifications */
|
/** Notifications */
|
||||||
sealed class Notifications {
|
sealed class Notifications {
|
||||||
@@ -166,58 +180,30 @@ sealed class ConfigProperties<T : Serializable>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data object NotificationsTemplateNewUser : ConfigProperties<String>(
|
|
||||||
String::class,
|
|
||||||
"notifications.templates.new-user",
|
|
||||||
"Template for new user notifications"
|
|
||||||
)
|
|
||||||
|
|
||||||
data object NotificationsTemplateNewInvite : ConfigProperties<String>(
|
|
||||||
String::class,
|
|
||||||
"notifications.templates.new-invite",
|
|
||||||
"Template for new user notifications"
|
|
||||||
)
|
|
||||||
|
|
||||||
data object NotificationsTemplateNewPasswordRequest : ConfigProperties<String>(
|
|
||||||
String::class,
|
|
||||||
"notifications.templates.new-password-request",
|
|
||||||
"Template for new password request notifications"
|
|
||||||
)
|
|
||||||
|
|
||||||
data object NotificationsTemplateNewGame : ConfigProperties<String>(
|
|
||||||
String::class,
|
|
||||||
"notifications.templates.new-game",
|
|
||||||
"Template for new game notifications"
|
|
||||||
)
|
|
||||||
|
|
||||||
data object NotificationsTemplateNewGameRequest : ConfigProperties<String>(
|
|
||||||
String::class,
|
|
||||||
"notifications.templates.new-game-request",
|
|
||||||
"Template for new game request notifications"
|
|
||||||
)
|
|
||||||
|
|
||||||
/** Logs */
|
/** Logs */
|
||||||
data object LogsFolder : ConfigProperties<String>(
|
sealed class Logs {
|
||||||
String::class,
|
data object Folder : ConfigProperties<String>(
|
||||||
"logs.folder",
|
String::class,
|
||||||
"Storage folder for log files",
|
"logs.folder",
|
||||||
"./logs"
|
"Storage folder for log files",
|
||||||
)
|
"./logs"
|
||||||
|
)
|
||||||
|
|
||||||
data object LogsMaxHistoryDays : ConfigProperties<Int>(
|
data object MaxHistoryDays : ConfigProperties<Int>(
|
||||||
Int::class,
|
Int::class,
|
||||||
"logs.max-history-days",
|
"logs.max-history-days",
|
||||||
"Log retention in days",
|
"Log retention in days",
|
||||||
30
|
30
|
||||||
)
|
)
|
||||||
|
|
||||||
data object LogsLevel : ConfigProperties<LogLevel>(
|
data object Level : ConfigProperties<LogLevel>(
|
||||||
LogLevel::class,
|
LogLevel::class,
|
||||||
"logs.level",
|
"logs.level",
|
||||||
"Log level",
|
"Log level",
|
||||||
LogLevel.INFO,
|
LogLevel.INFO,
|
||||||
LogLevel.entries
|
LogLevel.entries
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class MatchUsersBy {
|
enum class MatchUsersBy {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class DynamicAccessInterceptor(
|
|||||||
// Check if method is annotated with @DynamicPublicAccess
|
// Check if method is annotated with @DynamicPublicAccess
|
||||||
if (method.isAnnotationPresent(DynamicPublicAccess::class.java)) {
|
if (method.isAnnotationPresent(DynamicPublicAccess::class.java)) {
|
||||||
// Check if user is authenticated or public access is enabled
|
// Check if user is authenticated or public access is enabled
|
||||||
if (request.userPrincipal != null || configService.get(ConfigProperties.LibraryAllowPublicAccess) == true) {
|
if (request.userPrincipal != null || configService.get(ConfigProperties.Libraries.AllowPublicAccess) == true) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class SecurityConfig(
|
|||||||
|
|
||||||
super.configure(http)
|
super.configure(http)
|
||||||
|
|
||||||
if (config.get(ConfigProperties.SsoEnabled) == true) {
|
if (config.get(ConfigProperties.SSO.OIDC.Enabled) == true) {
|
||||||
setOAuth2LoginPage(http, "/oauth2/authorization/$ssoProviderKey")
|
setOAuth2LoginPage(http, "/oauth2/authorization/$ssoProviderKey")
|
||||||
// Use custom success handler to handle user registration
|
// Use custom success handler to handle user registration
|
||||||
http.oauth2Login { oauth2Login -> oauth2Login.successHandler(ssoAuthenticationSuccessHandler) }
|
http.oauth2Login { oauth2Login -> oauth2Login.successHandler(ssoAuthenticationSuccessHandler) }
|
||||||
@@ -74,16 +74,16 @@ class SecurityConfig(
|
|||||||
@Conditional(SsoEnabledCondition::class)
|
@Conditional(SsoEnabledCondition::class)
|
||||||
fun clientRegistrationRepository(): ClientRegistrationRepository? {
|
fun clientRegistrationRepository(): ClientRegistrationRepository? {
|
||||||
val clientRegistration = ClientRegistration.withRegistrationId(ssoProviderKey)
|
val clientRegistration = ClientRegistration.withRegistrationId(ssoProviderKey)
|
||||||
.clientId(config.get(ConfigProperties.SsoClientId))
|
.clientId(config.get(ConfigProperties.SSO.OIDC.ClientId))
|
||||||
.clientSecret(config.get(ConfigProperties.SsoClientSecret))
|
.clientSecret(config.get(ConfigProperties.SSO.OIDC.ClientSecret))
|
||||||
.scope("openid", "profile", "email")
|
.scope("openid", "profile", "email")
|
||||||
.userNameAttributeName("preferred_username")
|
.userNameAttributeName("preferred_username")
|
||||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
|
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
|
||||||
.issuerUri(config.get(ConfigProperties.SsoIssuerUrl))
|
.issuerUri(config.get(ConfigProperties.SSO.OIDC.IssuerUrl))
|
||||||
.authorizationUri(config.get(ConfigProperties.SsoAuthorizeUrl))
|
.authorizationUri(config.get(ConfigProperties.SSO.OIDC.AuthorizeUrl))
|
||||||
.tokenUri(config.get(ConfigProperties.SsoTokenUrl))
|
.tokenUri(config.get(ConfigProperties.SSO.OIDC.TokenUrl))
|
||||||
.userInfoUri(config.get(ConfigProperties.SsoUserInfoUrl))
|
.userInfoUri(config.get(ConfigProperties.SSO.OIDC.UserInfoUrl))
|
||||||
.jwkSetUri(config.get(ConfigProperties.SsoJwksUrl))
|
.jwkSetUri(config.get(ConfigProperties.SSO.OIDC.JwksUrl))
|
||||||
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
|
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class SsoAuthenticationSuccessHandler(
|
|||||||
// If user is not registered via SSO, check if user is already registered by username or email
|
// If user is not registered via SSO, check if user is already registered by username or email
|
||||||
// This is meant to map existing users to SSO users
|
// This is meant to map existing users to SSO users
|
||||||
if (matchedUser == null) {
|
if (matchedUser == null) {
|
||||||
matchedUser = when (config.get(ConfigProperties.SsoMatchExistingUsersBy)) {
|
matchedUser = when (config.get(ConfigProperties.SSO.OIDC.MatchExistingUsersBy)) {
|
||||||
MatchUsersBy.username -> userService.getByUsername(oidcUser.preferredUsername)
|
MatchUsersBy.username -> userService.getByUsername(oidcUser.preferredUsername)
|
||||||
MatchUsersBy.email -> userService.getByEmail(oidcUser.email)
|
MatchUsersBy.email -> userService.getByEmail(oidcUser.email)
|
||||||
else -> throw IllegalStateException("Unknown 'match users by' configuration")
|
else -> throw IllegalStateException("Unknown 'match users by' configuration")
|
||||||
@@ -43,7 +43,7 @@ class SsoAuthenticationSuccessHandler(
|
|||||||
// User could not be found in the database
|
// User could not be found in the database
|
||||||
if (matchedUser == null) {
|
if (matchedUser == null) {
|
||||||
// Check if new user registration is enabled
|
// Check if new user registration is enabled
|
||||||
if (config.get(ConfigProperties.SsoAutoRegisterNewUsers) == false) {
|
if (config.get(ConfigProperties.SSO.OIDC.AutoRegisterNewUsers) == false) {
|
||||||
response.sendRedirect("/")
|
response.sendRedirect("/")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ class SsoEnabledCondition : Condition {
|
|||||||
val password = environment.getProperty("spring.datasource.password");
|
val password = environment.getProperty("spring.datasource.password");
|
||||||
val connection = DriverManager.getConnection(url, user, password);
|
val connection = DriverManager.getConnection(url, user, password);
|
||||||
|
|
||||||
connection.use { connection ->
|
connection.use { c ->
|
||||||
val statement = connection.prepareStatement("SELECT \"value\" FROM app_config WHERE \"key\" = ?")
|
val statement = c.prepareStatement("SELECT \"value\" FROM app_config WHERE \"key\" = ?")
|
||||||
statement.setString(1, ConfigProperties.SsoEnabled.key)
|
statement.setString(1, ConfigProperties.SSO.OIDC.Enabled.key)
|
||||||
val resultSet = statement.executeQuery()
|
val resultSet = statement.executeQuery()
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
return resultSet.getBoolean("value")
|
return resultSet.getBoolean("value")
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ class LogService(
|
|||||||
@EventListener(ApplicationStartedEvent::class)
|
@EventListener(ApplicationStartedEvent::class)
|
||||||
fun configureFileLogging() {
|
fun configureFileLogging() {
|
||||||
return configureFileLogging(
|
return configureFileLogging(
|
||||||
config.get(ConfigProperties.LogsFolder)!!,
|
config.get(ConfigProperties.Logs.Folder)!!,
|
||||||
config.get(ConfigProperties.LogsMaxHistoryDays)!!,
|
config.get(ConfigProperties.Logs.MaxHistoryDays)!!,
|
||||||
config.get(ConfigProperties.LogsLevel)!!
|
config.get(ConfigProperties.Logs.Level)!!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user