From 7dc79bf0039cbf6e135ec13beb60dab64b8b62f0 Mon Sep 17 00:00:00 2001 From: Pascal Linxweiler Date: Mon, 13 Jul 2026 14:44:07 +0200 Subject: [PATCH] fix: admin role mapping grants only, revoke behind opt-in SSO login for an existing admin whose token lacked the admin role was silently demoting the account, locking admins out of the dashboard. Missing admin role now leaves the flag alone unless RevokeAdminWithoutRole is enabled. Co-Authored-By: Claude Fable 5 --- .../Api/OidcAuthController.cs | 13 ++++++++++--- .../Configuration/PluginConfiguration.cs | 6 ++++++ .../Configuration/configPage.html | 9 ++++++++- .../Jellyfin.Plugin.OidcAuth.csproj | 4 ++-- README.md | 2 +- build.yaml | 2 +- dist/oidc-auth_1.0.3.0.zip | Bin 0 -> 95320 bytes manifest.json | 8 ++++++++ 8 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 dist/oidc-auth_1.0.3.0.zip diff --git a/Jellyfin.Plugin.OidcAuth/Api/OidcAuthController.cs b/Jellyfin.Plugin.OidcAuth/Api/OidcAuthController.cs index 5bbcb87..80962f1 100644 --- a/Jellyfin.Plugin.OidcAuth/Api/OidcAuthController.cs +++ b/Jellyfin.Plugin.OidcAuth/Api/OidcAuthController.cs @@ -143,9 +143,16 @@ public class OidcAuthController : ControllerBase var adminRoles = SplitCsv(Config.AdminRoles); if (adminRoles.Length > 0) { - var isAdmin = roles.Intersect(adminRoles, StringComparer.OrdinalIgnoreCase).Any(); - _logger.LogInformation("OIDC admin mapping for {Username}: admin roles [{AdminRoles}] => admin={IsAdmin}", username, Config.AdminRoles, isAdmin); - user.SetPermission(PermissionKind.IsAdministrator, isAdmin); + var hasAdminRole = roles.Intersect(adminRoles, StringComparer.OrdinalIgnoreCase).Any(); + _logger.LogInformation("OIDC admin mapping for {Username}: admin roles [{AdminRoles}] => hasAdminRole={HasAdminRole}", username, Config.AdminRoles, hasAdminRole); + if (hasAdminRole) + { + user.SetPermission(PermissionKind.IsAdministrator, true); + } + else if (Config.RevokeAdminWithoutRole) + { + user.SetPermission(PermissionKind.IsAdministrator, false); + } } await _userManager.UpdateUserAsync(user).ConfigureAwait(false); diff --git a/Jellyfin.Plugin.OidcAuth/Configuration/PluginConfiguration.cs b/Jellyfin.Plugin.OidcAuth/Configuration/PluginConfiguration.cs index fd2c321..521cc64 100644 --- a/Jellyfin.Plugin.OidcAuth/Configuration/PluginConfiguration.cs +++ b/Jellyfin.Plugin.OidcAuth/Configuration/PluginConfiguration.cs @@ -50,6 +50,12 @@ public class PluginConfiguration : BasePluginConfiguration /// public string AllowedRoles { get; set; } = string.Empty; + /// + /// Gets or sets a value indicating whether a missing admin role also revokes an + /// existing administrator flag on OIDC login. Off by default: admin roles only grant. + /// + public bool RevokeAdminWithoutRole { get; set; } + /// /// Gets or sets a value indicating whether unknown users are created on first login. /// diff --git a/Jellyfin.Plugin.OidcAuth/Configuration/configPage.html b/Jellyfin.Plugin.OidcAuth/Configuration/configPage.html index f19b2f4..39445c0 100644 --- a/Jellyfin.Plugin.OidcAuth/Configuration/configPage.html +++ b/Jellyfin.Plugin.OidcAuth/Configuration/configPage.html @@ -51,6 +51,13 @@
Comma separated. Users with one of these roles become Jellyfin administrators. Empty = never touch admin flag.
+
+ +
+