using System.Security.Claims; using Microsoft.AspNetCore.Authorization; namespace JetHerald.Authorization; public static class Permissions { public const string PolicyPrefix = "permission://"; public const string ClaimId = "Permission"; } public class PermissionAttribute : AuthorizeAttribute { public PermissionAttribute(string permission) => Policy = Permissions.PolicyPrefix + permission; } public class PermissionRequirement : IAuthorizationRequirement { public string Permission { get; } public PermissionRequirement(string permtext) => Permission = permtext[Permissions.PolicyPrefix.Length..]; } public class PermissionHandler : AuthorizationHandler { protected override Task HandleRequirementAsync( AuthorizationHandlerContext context, PermissionRequirement requirement) { var permissions = context.User.FindFirstValue(Permissions.ClaimId); if (PermissionParser.ProvePermission(permissions, requirement.Permission)) context.Succeed(requirement); else context.Fail(); return Task.CompletedTask; } } public class PermissionPolicyProvider : IAuthorizationPolicyProvider { public DefaultAuthorizationPolicyProvider Fallback { get; } public PermissionPolicyProvider(IOptions opt) => Fallback = new DefaultAuthorizationPolicyProvider(opt); public Task GetDefaultPolicyAsync() => Fallback.GetDefaultPolicyAsync(); public Task GetFallbackPolicyAsync() => Fallback.GetFallbackPolicyAsync(); public Task GetPolicyAsync(string policyName) { if (policyName.StartsWith(Permissions.PolicyPrefix)) { var policy = new AuthorizationPolicyBuilder(); policy.AddRequirements(new PermissionRequirement(policyName)); return Task.FromResult(policy.Build()); } return Fallback.GetPolicyAsync(policyName); } }