using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
namespace ROLAC.API.Authorization;
///
/// Materializes PERM:<module>:<action> policies on demand so we never
/// have to register every module/action combination at startup. Any other policy name
/// (including the default and Roles= policies) is delegated to the framework's
/// default provider, so existing [Authorize(Roles=...)] usages keep working.
///
public class PermissionPolicyProvider : IAuthorizationPolicyProvider
{
private readonly DefaultAuthorizationPolicyProvider _fallback;
public PermissionPolicyProvider(IOptions options)
=> _fallback = new DefaultAuthorizationPolicyProvider(options);
public Task GetDefaultPolicyAsync() => _fallback.GetDefaultPolicyAsync();
public Task GetFallbackPolicyAsync() => _fallback.GetFallbackPolicyAsync();
public Task GetPolicyAsync(string policyName)
{
var parsed = HasPermissionAttribute.Parse(policyName);
if (parsed is null)
return _fallback.GetPolicyAsync(policyName);
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddRequirements(new PermissionRequirement(parsed.Value.Module, parsed.Value.Action))
.Build();
return Task.FromResult(policy);
}
}