using Microsoft.AspNetCore.Authorization;
namespace TakeoutSaaS.Module.Authorization.Policies;
/// <summary>
/// 权限校验处理器。
/// </summary>
public sealed class PermissionAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
{
    /// <summary>
    /// 用户声明中权限的声明类型键。
    /// </summary>
    public const string PermissionClaimType = "permission";
    /// <summary>
    /// 校验当前用户是否具备要求的权限集合。
    /// </summary>
    /// <param name="context">授权上下文。</param>
    /// <param name="requirement">权限需求描述。</param>
    /// <returns>异步完成任务。</returns>
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
    {
        // 1. 校验用户已通过认证
        if (context.User?.Identity?.IsAuthenticated != true)
        {
            return Task.CompletedTask;
        }
        // 2. 收集用户已授予的权限标识
        var userPermissions = context.User
            .FindAll(PermissionClaimType)
            .Select(claim => claim.Value)
            .Where(value => !string.IsNullOrWhiteSpace(value))
            .Select(value => value.Trim())
            .ToHashSet(StringComparer.OrdinalIgnoreCase);
        // 3. 无权限直接结束
        if (userPermissions.Count == 0)
        {
            return Task.CompletedTask;
        }
        // 4. 任一权限匹配即视为授权通过
        if (requirement.Permissions.Any(userPermissions.Contains))
        {
            context.Succeed(requirement);
        }
        // 5. 结束处理
        return Task.CompletedTask;
    }
}
