Save all settings as json instead of having lots of keys

This commit is contained in:
Amelia 2025-07-01 13:50:59 +02:00
parent e8f74709f3
commit dc91696769
No known key found for this signature in database
GPG key ID: D6D0ECE365407EAA
7 changed files with 63 additions and 111 deletions

View file

@ -1,17 +1,25 @@
#nullable enable
using API.Entities.Enums;
namespace API.DTOs.Settings;
public record OidcConfigDto: OidcPublicConfigDto
{
/// <inheritdoc cref="ServerSettingKey.OidcProvisionAccounts"/>
/// <summary>
/// If true, auto creates a new account when someone logs in via OpenID Connect
/// </summary>
public bool ProvisionAccounts { get; set; }
/// <inheritdoc cref="ServerSettingKey.OidcRequireVerifiedEmail"/>
public bool RequireVerifiedEmail { get; set; }
/// <inheritdoc cref="ServerSettingKey.OidcProvisionUserSettings"/>
/// <summary>
/// Require emails to be verified by the OpenID Connect provider when creating accounts on login
/// </summary>
public bool RequireVerifiedEmail { get; set; } = true;
/// <summary>
/// Overwrite Kavita roles, libraries and age rating with OpenIDConnect provides roles on log in.
/// </summary>
public bool ProvisionUserSettings { get; set; }
/// <inheritdoc cref="ServerSettingKey.OidcAutoLogin"/>
/// <summary>
/// Requires roles to be configured in OIDC
/// </summary>
public bool RequireRoles { get; set; } = true;
/// <summary>
/// Returns true if the <see cref="OidcPublicConfigDto.Authority"/> has been set

View file

@ -9,10 +9,17 @@ public record OidcPublicConfigDto
public string? Authority { get; set; }
/// <inheritdoc cref="ServerSettingKey.OidcClientId"/>
public string? ClientId { get; set; }
/// <inheritdoc cref="ServerSettingKey.OidcAutoLogin"/>
/// <summary>
/// Optional OpenID Connect ClientSecret, required if authority is set
/// </summary>
public bool AutoLogin { get; set; }
/// <inheritdoc cref="ServerSettingKey.DisablePasswordAuthentication"/>
/// <summary>
/// Disables password authentication for non-admin users
/// </summary>
public bool DisablePasswordAuthentication { get; set; }
/// <inheritdoc cref="ServerSettingKey.OidcProviderName"/>
public string ProviderName { get; set; } = string.Empty;
/// <summary>
/// Name of your provider, used to display on the login screen
/// </summary>
/// <remarks>Default to OpenID Connect</remarks>
public string ProviderName { get; set; } = "OpenID Connect";
}

View file

@ -5,9 +5,11 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
using API.Constants;
using API.Data.Repositories;
using API.DTOs.Settings;
using API.Entities;
using API.Entities.Enums;
using API.Entities.Enums.Theme;
@ -254,12 +256,7 @@ public static class Seed
}, // Not used from DB, but DB is sync with appSettings.json
new() { Key = ServerSettingKey.OidcAuthority, Value = Configuration.OidcAuthority },
new() { Key = ServerSettingKey.OidcClientId, Value = Configuration.OidcClientId},
new() { Key = ServerSettingKey.OidcAutoLogin, Value = "false"},
new() { Key = ServerSettingKey.OidcProvisionAccounts, Value = "false"},
new() { Key = ServerSettingKey.OidcRequireVerifiedEmail, Value = "true"},
new() { Key = ServerSettingKey.OidcProvisionUserSettings, Value = "false"},
new() { Key = ServerSettingKey.DisablePasswordAuthentication, Value = "false"},
new() { Key = ServerSettingKey.OidcProviderName, Value = "OpenID Connect"},
new() { Key = ServerSettingKey.OidcConfiguration, Value = JsonSerializer.Serialize(new OidcConfigDto())},
new() {Key = ServerSettingKey.EmailHost, Value = string.Empty},
new() {Key = ServerSettingKey.EmailPort, Value = string.Empty},

View file

@ -208,34 +208,9 @@ public enum ServerSettingKey
[Description("OpenIDConnectClientId")]
OidcClientId = 41,
/// <summary>
/// Optional OpenID Connect ClientSecret, required if authority is set
/// A Json object of type <see cref="API.DTOs.Settings.OidcConfigDto"/>
/// </summary>
[Description("OpenIdConnectAutoLogin")]
OidcAutoLogin = 42,
/// <summary>
/// If true, auto creates a new account when someone logs in via OpenID Connect
/// </summary>
[Description("OpenIDConnectCreateAccounts")]
OidcProvisionAccounts = 43,
/// <summary>
/// Require emails to be verified by the OpenID Connect provider when creating accounts on login
/// </summary>
[Description("OpenIDConnectVerifiedEmail")]
OidcRequireVerifiedEmail = 44,
/// <summary>
/// Overwrite Kavita roles, libraries and age rating with OpenIDConnect provides roles on log in.
/// </summary>
[Description("OpenIDConnectSyncUserSettings")]
OidcProvisionUserSettings = 45,
/// <summary>
/// Disables password authentication for non-admin users
/// </summary>
[Description("DisablePasswordAuthentication")]
DisablePasswordAuthentication = 46,
/// <summary>
/// Name of your provider, used to display on the login screen
/// </summary>
/// <remarks>Default to OpenID Connect</remarks>
[Description("OidcProviderName")]
OidcProviderName = 47,
[Description("OidcConfiguration")]
OidcConfiguration = 42,
}

View file

@ -1,4 +1,7 @@
using System.Security.Claims;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using API.Constants;
using Kavita.Common;
using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames;
@ -41,4 +44,12 @@ public static class ClaimsPrincipalExtensions
return true;
}
public static List<string> GetAccessRoles(this ClaimsPrincipal claimsPrincipal)
{
return claimsPrincipal.FindAll(ClaimTypes.Role)
.Select(r => r.Value)
.Where(r => PolicyConstants.ValidRoles.Contains(r))
.ToList();
}
}

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;
using API.DTOs.Settings;
using API.Entities;
using API.Entities.Enums;
@ -137,29 +138,12 @@ public class ServerSettingConverter : ITypeConverter<IEnumerable<ServerSetting>,
destination.OidcConfig ??= new OidcConfigDto();
destination.OidcConfig.ClientId = row.Value;
break;
case ServerSettingKey.OidcAutoLogin:
case ServerSettingKey.OidcConfiguration:
destination.OidcConfig ??= new OidcConfigDto();
destination.OidcConfig.AutoLogin = bool.Parse(row.Value);
break;
case ServerSettingKey.OidcProvisionAccounts:
destination.OidcConfig ??= new OidcConfigDto();
destination.OidcConfig.ProvisionAccounts = bool.Parse(row.Value);
break;
case ServerSettingKey.OidcRequireVerifiedEmail:
destination.OidcConfig ??= new OidcConfigDto();
destination.OidcConfig.RequireVerifiedEmail = bool.Parse(row.Value);
break;
case ServerSettingKey.OidcProvisionUserSettings:
destination.OidcConfig ??= new OidcConfigDto();
destination.OidcConfig.ProvisionUserSettings = bool.Parse(row.Value);
break;
case ServerSettingKey.DisablePasswordAuthentication:
destination.OidcConfig ??= new OidcConfigDto();
destination.OidcConfig.DisablePasswordAuthentication = bool.Parse(row.Value);
break;
case ServerSettingKey.OidcProviderName:
destination.OidcConfig ??= new OidcConfigDto();
destination.OidcConfig.ProviderName = row.Value;
var configuration = JsonSerializer.Deserialize<OidcConfigDto>(row.Value)!;
configuration.Authority = destination.OidcConfig.Authority;
configuration.ClientId = destination.OidcConfig.ClientId;
destination.OidcConfig = configuration;
break;
case ServerSettingKey.LicenseKey:
case ServerSettingKey.EnableAuthentication:

View file

@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Net;
using System.Text.Json;
using System.Threading.Tasks;
using API.Data;
using API.DTOs.KavitaPlus.Metadata;
@ -413,64 +414,33 @@ public class SettingsService : ISettingsService
private async Task UpdateOidcSettings(ServerSetting setting, ServerSettingDto updateSettingsDto)
{
if (setting.Key == ServerSettingKey.OidcAuthority &&
updateSettingsDto.OidcConfig.Authority + string.Empty != setting.Value)
if (setting.Key == ServerSettingKey.OidcAuthority && setting.Value != updateSettingsDto.OidcConfig.Authority)
{
if (!await IsValidAuthority(updateSettingsDto.OidcConfig.Authority + string.Empty))
{
throw new KavitaException("oidc-invalid-authority");
}
setting.Value = updateSettingsDto.OidcConfig.Authority + string.Empty;
Configuration.OidcAuthority = setting.Value;
setting.Value = updateSettingsDto.OidcConfig.Authority;
_unitOfWork.SettingsRepository.Update(setting);
_logger.LogWarning("OIDC Authority is changing, clearing all external ids");
await _oidcService.ClearOidcIds();
return;
}
if (setting.Key == ServerSettingKey.OidcClientId &&
updateSettingsDto.OidcConfig.ClientId + string.Empty != setting.Value)
if (setting.Key == ServerSettingKey.OidcClientId && setting.Value != updateSettingsDto.OidcConfig.ClientId)
{
setting.Value = updateSettingsDto.OidcConfig.ClientId + string.Empty;
Configuration.OidcClientId = setting.Value;
setting.Value = updateSettingsDto.OidcConfig.ClientId;
_unitOfWork.SettingsRepository.Update(setting);
return;
}
if (setting.Key == ServerSettingKey.OidcAutoLogin &&
updateSettingsDto.OidcConfig.AutoLogin + string.Empty != setting.Value)
{
setting.Value = updateSettingsDto.OidcConfig.AutoLogin + string.Empty;
_unitOfWork.SettingsRepository.Update(setting);
}
if (setting.Key != ServerSettingKey.OidcConfiguration) return;
if (setting.Key == ServerSettingKey.OidcProvisionAccounts &&
updateSettingsDto.OidcConfig.ProvisionAccounts + string.Empty != setting.Value)
{
setting.Value = updateSettingsDto.OidcConfig.ProvisionAccounts + string.Empty;
_unitOfWork.SettingsRepository.Update(setting);
}
if (setting.Key == ServerSettingKey.OidcProvisionUserSettings &&
updateSettingsDto.OidcConfig.ProvisionUserSettings + string.Empty != setting.Value)
{
setting.Value = updateSettingsDto.OidcConfig.ProvisionUserSettings + string.Empty;
_unitOfWork.SettingsRepository.Update(setting);
}
if (setting.Key == ServerSettingKey.DisablePasswordAuthentication &&
updateSettingsDto.OidcConfig.DisablePasswordAuthentication + string.Empty != setting.Value)
{
setting.Value = updateSettingsDto.OidcConfig.DisablePasswordAuthentication + string.Empty;
_unitOfWork.SettingsRepository.Update(setting);
}
if (setting.Key == ServerSettingKey.OidcProviderName &&
updateSettingsDto.OidcConfig.ProviderName + string.Empty != setting.Value)
{
setting.Value = updateSettingsDto.OidcConfig.ProviderName + string.Empty;
_unitOfWork.SettingsRepository.Update(setting);
}
var newValue = JsonSerializer.Serialize(updateSettingsDto.OidcConfig);
if (setting.Value == newValue) return;
setting.Value = JsonSerializer.Serialize(updateSettingsDto.OidcConfig);
_unitOfWork.SettingsRepository.Update(setting);
}
private void UpdateEmailSettings(ServerSetting setting, ServerSettingDto updateSettingsDto)