using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace Core.Cerberos.Adapters.Attributes
{
///
/// Custom authorization attribute that checks if the user has any of the required permissions.
///
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public class PermissionAttribute : AuthorizeAttribute, IAuthorizationFilter
{
private readonly string _requiredPermissions;
///
/// Initializes a new instance of the class.
///
/// The array of permissions required to access the resource.
public PermissionAttribute(string requiredPermissions)
{
_requiredPermissions = requiredPermissions;
}
///
/// Called during the authorization process to determine if the user has any of the required permissions.
///
/// The context in which the authorization filter operates.
public void OnAuthorization(AuthorizationFilterContext context)
{
try
{
var hasPermission = false;
var servicePermissionsList = _requiredPermissions.Replace(" ", "").Split(',').ToList();
var servicePermissions = servicePermissionsList.Select(s => new Permission
{
Name = s.Substring(0, s.IndexOf('.')),
AccessLevel = s.Substring(s.IndexOf('.') + 1),
});
var userPermissionsList = context.HttpContext.User.Claims
.Where(c => c.Type == "permissions")
.Select(c => c.Value)
.ToList();
var userPermissions = userPermissionsList.Select(s => new Permission
{
Name = s.Substring(0, s.IndexOf('.')),
AccessLevel = s.Substring(s.IndexOf('.') + 1),
});
foreach (var servicePermission in servicePermissions)
{
hasPermission = userPermissions
.Where(up => up.Name == servicePermission.Name && up.AccessLevel == "All"
|| up.Name == servicePermission.Name && up.AccessLevel == servicePermission.AccessLevel)
.Count() > 0 ? true : false;
if (hasPermission) break;
}
if (!hasPermission)
context.Result = new UnauthorizedResult();
}
catch (Exception ex)
{
context.Result = new UnauthorizedResult();
}
}
}
}