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); } }