further optimization of permissions - removed reference to Role to reduce API payload and minimize information disclosure
This commit is contained in:
@ -1,3 +1,7 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using System;
|
||||
|
||||
namespace Oqtane.Models
|
||||
{
|
||||
/// <summary>
|
||||
@ -17,47 +21,41 @@ namespace Oqtane.Models
|
||||
public int SiteId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the Entity these permissions apply to.
|
||||
/// Name of the Entity these permissions apply to (ie. Module )
|
||||
/// </summary>
|
||||
public string EntityName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID of the Entity these permissions apply to.
|
||||
/// ID of the Entity these permissions apply to (ie. a ModuleId). A value of -1 indicates the permission applies to all EntityNames regardless of ID (ie. API permissions)
|
||||
/// </summary>
|
||||
public int EntityId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What this permission is called.
|
||||
/// TODO: todoc - must clarify what exactly this means, I assume any module can give it's own names for Permissions
|
||||
/// Name of the permission (ie. View)
|
||||
/// </summary>
|
||||
public string PermissionName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Role"/> this permission applies to. So if all users in the Role _Customers_ have this permission, then it would reference that Role.
|
||||
/// If null, then the permission doesn't target a role but probably a <see cref="User"/> (see <see cref="UserId"/>).
|
||||
/// <see cref="Role"/> this permission applies to. If null then this is a <see cref="User"/> permission.
|
||||
/// </summary>
|
||||
public int? RoleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The role name associated to the RoleId.
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public string RoleName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="User"/> this permission applies to.
|
||||
/// If null, then the permission doesn't target a User but probably a <see cref="Role"/> (see <see cref="RoleId"/>).
|
||||
/// <see cref="User"/> this permission applies to. If null then this is a <see cref="Role"/> permission.
|
||||
/// </summary>
|
||||
public int? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines if Authorization is sufficient to receive this permission.
|
||||
/// The type of permission (ie. grant = true, deny = false)
|
||||
/// </summary>
|
||||
public bool IsAuthorized { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the <see cref="Role"/> based on the <see cref="RoleId"/> - can be nullable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It's not certain if this will always be populated. TODO: todoc/verify
|
||||
/// </remarks>
|
||||
public Role Role { get; set; }
|
||||
|
||||
public Permission()
|
||||
{
|
||||
}
|
||||
@ -90,17 +88,22 @@ namespace Oqtane.Models
|
||||
PermissionName = permissionName;
|
||||
if (!string.IsNullOrEmpty(roleName))
|
||||
{
|
||||
Role = new Role { Name = roleName };
|
||||
RoleId = null;
|
||||
RoleName = roleName;
|
||||
UserId = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Role = null;
|
||||
RoleId = null;
|
||||
RoleName = null;
|
||||
UserId = userId;
|
||||
}
|
||||
IsAuthorized = isAuthorized;
|
||||
}
|
||||
|
||||
[Obsolete("The Role property is deprecated", false)]
|
||||
[NotMapped]
|
||||
[JsonIgnore] // exclude from API payload
|
||||
public Role Role { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -51,20 +51,20 @@ namespace Oqtane.Security
|
||||
{
|
||||
// check if denied first
|
||||
isAuthorized = !permissionList.Where(item => !item.IsAuthorized && (
|
||||
(item.Role != null && (
|
||||
(item.Role.Name == RoleNames.Everyone) ||
|
||||
(item.Role.Name == RoleNames.Unauthenticated && userId == -1) ||
|
||||
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.Role.Name))) ||
|
||||
(item.UserId == null && (
|
||||
(item.RoleName == RoleNames.Everyone) ||
|
||||
(item.RoleName == RoleNames.Unauthenticated && userId == -1) ||
|
||||
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.RoleName))) ||
|
||||
(item.UserId != null && item.UserId.Value == userId))).Any();
|
||||
|
||||
if (isAuthorized)
|
||||
{
|
||||
// then check if authorized
|
||||
isAuthorized = permissionList.Where(item => item.IsAuthorized && (
|
||||
(item.Role != null && (
|
||||
(item.Role.Name == RoleNames.Everyone) ||
|
||||
(item.Role.Name == RoleNames.Unauthenticated && userId == -1) ||
|
||||
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.Role.Name))) ||
|
||||
(item.UserId == null && (
|
||||
(item.RoleName == RoleNames.Everyone) ||
|
||||
(item.RoleName == RoleNames.Unauthenticated && userId == -1) ||
|
||||
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.RoleName))) ||
|
||||
(item.UserId != null && item.UserId.Value == userId))).Any();
|
||||
}
|
||||
}
|
||||
@ -74,7 +74,7 @@ namespace Oqtane.Security
|
||||
|
||||
public static bool ContainsRole(List<Permission> permissions, string permissionName, string roleName)
|
||||
{
|
||||
return permissions.Any(item => item.PermissionName == permissionName && item.Role.Name == roleName);
|
||||
return permissions.Any(item => item.PermissionName == permissionName && item.RoleName == roleName);
|
||||
}
|
||||
|
||||
public static bool ContainsUser(List<Permission> permissions, string permissionName, int userId)
|
||||
|
Reference in New Issue
Block a user