using System.Collections.Generic;
using System.Security.Claims;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Kavita.Common;
using Microsoft.AspNetCore.Authentication;
namespace API.Helpers;
///
/// Adds assigned roles from Keycloak under the default claim
///
public class RolesClaimsTransformation: IClaimsTransformation
{
private const string ResourceAccessClaim = "resource_access";
private string _clientId;
public Task TransformAsync(ClaimsPrincipal principal)
{
var resourceAccess = principal.FindFirst(ResourceAccessClaim);
if (resourceAccess == null) return Task.FromResult(principal);
var resources = JsonSerializer.Deserialize>(resourceAccess.Value);
if (resources == null) return Task.FromResult(principal);
if (string.IsNullOrEmpty(_clientId))
{
_clientId = Configuration.OidcClientId;
}
var kavitaResource = resources.GetValueOrDefault(_clientId);
if (kavitaResource == null) return Task.FromResult(principal);
foreach (var role in kavitaResource.Roles)
{
((ClaimsIdentity)principal.Identity)?.AddClaim(new Claim(ClaimTypes.Role, role));
}
return Task.FromResult(principal);
}
private sealed class Resource
{
[JsonPropertyName("roles")]
public IList Roles { get; set; } = [];
}
}