The idea here is we have Roles, Permissions, and a table called PermissionRoles that connect the two. So a Permissions can be in many Roles, and many Permissions can have the same Role. So what the following code does is:
- Get all the permissions required for a user to authenticate, by ActionName
- Loop through each of these permissions
- Get the list PermissionsRole records that have one of those Permission objects
- Get the list of Roles from the list of PermissionRoles
- Loop through that list of Roles
- Check if a user is in any of those roles
This is the code, I feel like there may be a more efficient way to write this. It is implied that I have instantiated a UserManager and Database Context.
string[] permissions = Permissions.Split(',').ToArray();
IEnumerable<string> perms = permissions.Intersect(db.Permissions.Select(p => p.ActionName));
List<IdentityRole> roles = new List<IdentityRole>();
if (perms.Count() > 0)
{
foreach (var item in perms)
{
var currentUserId = httpContext.User.Identity.GetUserId();
var permissionsRoles = db.PermissionRoles.Where(p => p.Permission.ActionName == item && p.CompanyId == companyId).ToList();
var existingRoles = dbu.Roles.Select(x => x.Id).Intersect(permissionsRoles.Select(x => x.RoleId)).ToList();
foreach (var role in existingRoles)
{
ApplicationRole thisRole = dbu.Roles.Find(role);
if (userManager.IsInRole(currentUserId, thisRole.Name))
{
return true;
}
}
}
}
return false;