using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.IdentityModel.JsonWebTokens; namespace OpenWarehouse.auth.api.Common.PrivilageManager; /// /// Attribute to enforce privilege-based authorization. /// public class HasPrivilegeAttribute : Attribute, IAsyncAuthorizationFilter { private GlobalPrivilage.Privilege[] Privileges { get; } /// /// Initializes a new instance of the class with one or more required privileges. /// /// The privileges required to access the resource. public HasPrivilegeAttribute(params GlobalPrivilage.Privilege[] privileges) { Privileges = privileges; } /// /// Performs the privilege check during authorization. /// /// The authorization filter context. public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { var userActionId = context.HttpContext.User.FindFirstValue(JwtRegisteredClaimNames.Sub); var userManager = context.HttpContext.RequestServices.GetRequiredService>(); var privilegeManager = context.HttpContext.RequestServices.GetRequiredService(); if (userActionId != null) { var userAction = await userManager.FindByIdAsync(userActionId); if (userAction == null || !await UserHasAnyRequiredPrivilege(privilegeManager, userAction)) { context.Result = new ContentResult { StatusCode = StatusCodes.Status403Forbidden, Content = "Access Denied: You do not have the required privileges to perform this action.", ContentType = "text/plain" }; } } } /// /// Checks if the user has at least one of the required privileges. /// /// The privilege manager service. /// The user to check privileges for. /// True if the user has any required privilege; otherwise, false. private async Task UserHasAnyRequiredPrivilege(PrivilegeManager privilegeManager, ApplicationUser user) { foreach (var privilege in Privileges) { if (await privilegeManager.UserHasGlobalPrivilage(user, privilege)) { return true; } } return false; } }