Rework Admin UI #6

Merged
MasterMito merged 18 commits from epic/admin_rework_second_try into main 2026-03-20 11:55:38 +01:00
3 changed files with 81 additions and 13 deletions
Showing only changes of commit bb373a6b8e - Show all commits
@@ -56,12 +56,35 @@ public class ClubRoleClaimsTransformation : IClaimsTransformation
// --- NEW: Skip DB role lookup if user is a global admin ---
var realmAccess = principal.FindFirst("realm_access")?.Value;
if (!string.IsNullOrEmpty(realmAccess) && realmAccess.Contains("\"admin\"", StringComparison.OrdinalIgnoreCase))
if (!string.IsNullOrEmpty(realmAccess) && IsAdminUser(realmAccess))
{
return Task.FromResult(principal);
}
// ---------------------------------------------------------
static bool IsAdminUser(string realmAccess)
{
try
{
using var doc = System.Text.Json.JsonDocument.Parse(realmAccess);
if (doc.RootElement.TryGetProperty("roles", out var rolesElement) &&
rolesElement.ValueKind == System.Text.Json.JsonValueKind.Array)
{
foreach (var role in rolesElement.EnumerateArray())
{
if (role.GetString()?.Equals("admin", StringComparison.OrdinalIgnoreCase) == true)
return true;
}
}
}
catch
{
// If JSON parsing fails, fallback to string contains check
return realmAccess.Contains("admin", StringComparison.OrdinalIgnoreCase);
}
return false;
}
// Look up the user's role in the database for the requested tenant
_httpContextAccessor.HttpContext!.Items["TenantId"] = tenantId;
var memberRole = GetMemberRole(userIdClaim, tenantId);
@@ -46,12 +46,35 @@ public class TenantValidationMiddleware
{
// NEW: Skip check if user is a global admin
var realmAccess = context.User.FindFirst("realm_access")?.Value;
if (!string.IsNullOrEmpty(realmAccess) && realmAccess.Contains("\"admin\"", StringComparison.OrdinalIgnoreCase))
if (!string.IsNullOrEmpty(realmAccess) && IsAdminUser(realmAccess))
{
await _next(context);
return;
}
static bool IsAdminUser(string realmAccess)
{
try
{
using var doc = System.Text.Json.JsonDocument.Parse(realmAccess);
if (doc.RootElement.TryGetProperty("roles", out var rolesElement) &&
rolesElement.ValueKind == System.Text.Json.JsonValueKind.Array)
{
foreach (var role in rolesElement.EnumerateArray())
{
if (role.GetString()?.Equals("admin", StringComparison.OrdinalIgnoreCase) == true)
return true;
}
}
}
catch
{
// If JSON parsing fails, fallback to string contains check
return realmAccess.Contains("admin", StringComparison.OrdinalIgnoreCase);
}
return false;
}
context.Response.StatusCode = StatusCodes.Status403Forbidden;
await context.Response.WriteAsJsonAsync(new { error = "User does not have clubs claim" });
return;
+23 -1
View File
@@ -53,7 +53,29 @@ builder.Services.AddAuthorizationBuilder()
.AddPolicy("RequireGlobalAdmin", policy => policy.RequireAssertion(context =>
{
var realmAccess = context.User.FindFirst("realm_access")?.Value;
return realmAccess != null && realmAccess.Contains("\"admin\"");
if (string.IsNullOrEmpty(realmAccess))
return false;
try
{
using var doc = System.Text.Json.JsonDocument.Parse(realmAccess);
if (doc.RootElement.TryGetProperty("roles", out var rolesElement) &&
rolesElement.ValueKind == System.Text.Json.JsonValueKind.Array)
{
foreach (var role in rolesElement.EnumerateArray())
{
if (role.GetString() == "admin")
return true;
}
}
}
catch
{
// If JSON parsing fails, fallback to string contains check
return realmAccess.Contains("admin", StringComparison.OrdinalIgnoreCase);
}
return false;
}))
.AddPolicy("RequireManager", policy => policy.RequireRole("Manager"))
.AddPolicy("RequireMember", policy => policy.RequireRole("Manager", "Member"))