Major refactoring replacing permission strings with permission collections. These changes will require extensive regression testing. These changes may include breaking changes which will need to be identified and resolved to provide backward compatibility.

This commit is contained in:
Shaun Walker 2023-02-28 17:59:21 -05:00
parent c4cd1a5a54
commit 8605e3ca5a
24 changed files with 274 additions and 477 deletions

View File

@ -99,7 +99,7 @@
private string _imagesizes = string.Empty; private string _imagesizes = string.Empty;
private string _capacity = "0"; private string _capacity = "0";
private bool _isSystem; private bool _isSystem;
private string _permissions = string.Empty; private List<Permission> _permissions;
private string _createdBy; private string _createdBy;
private DateTime _createdOn; private DateTime _createdOn;
private string _modifiedBy; private string _modifiedBy;

View File

@ -206,7 +206,7 @@
private string _contact = ""; private string _contact = "";
private string _license = ""; private string _license = "";
private string _runtimes = ""; private string _runtimes = "";
private string _permissions; private List<Permission> _permissions;
private string _createdby; private string _createdby;
private DateTime _createdon; private DateTime _createdon;
private string _modifiedby; private string _modifiedby;

View File

@ -101,7 +101,7 @@
private string _containerType; private string _containerType;
private string _allPages = "false"; private string _allPages = "false";
private string _permissionNames = ""; private string _permissionNames = "";
private string _permissions = null; private List<Permission> _permissions;
private string _pageId; private string _pageId;
private PermissionGrid _permissionGrid; private PermissionGrid _permissionGrid;
private Type _moduleSettingsType; private Type _moduleSettingsType;

View File

@ -183,7 +183,7 @@
private string _themetype = string.Empty; private string _themetype = string.Empty;
private string _containertype = string.Empty; private string _containertype = string.Empty;
private string _icon = string.Empty; private string _icon = string.Empty;
private string _permissions = string.Empty; private List<Permission> _permissions = null;
private PermissionGrid _permissionGrid; private PermissionGrid _permissionGrid;
private Type _themeSettingsType; private Type _themeSettingsType;
private object _themeSettings; private object _themeSettings;
@ -202,7 +202,6 @@
_containers = ThemeService.GetContainerControls(_themeList, _themetype); _containers = ThemeService.GetContainerControls(_themeList, _themetype);
_containertype = PageState.Site.DefaultContainerType; _containertype = PageState.Site.DefaultContainerType;
_children = PageState.Pages.Where(item => item.ParentId == null).ToList(); _children = PageState.Pages.Where(item => item.ParentId == null).ToList();
_permissions = string.Empty;
ThemeSettings(); ThemeSettings();
} }
catch (Exception ex) catch (Exception ex)

View File

@ -221,7 +221,7 @@
private string _themetype; private string _themetype;
private string _containertype = "-"; private string _containertype = "-";
private string _icon; private string _icon;
private string _permissions = null; private List<Permission> _permissions = null;
private string _createdby; private string _createdby;
private DateTime _createdon; private DateTime _createdon;
private string _modifiedby; private string _modifiedby;

View File

@ -40,7 +40,7 @@
@code { @code {
private bool _visible = false; private bool _visible = false;
private string _permissions = string.Empty; private List<Permission> _permissions;
private bool _editmode = false; private bool _editmode = false;
private bool _authorized = false; private bool _authorized = false;
private string _iconSpan = string.Empty; private string _iconSpan = string.Empty;
@ -61,7 +61,7 @@
public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel
[Parameter] [Parameter]
public string Permissions { get; set; } // optional - can be used to specify a permission string public List<Permission> Permissions { get; set; } // optional - can be used to specify permissions
[Parameter] [Parameter]
public string Class { get; set; } // optional public string Class { get; set; } // optional
@ -109,7 +109,7 @@
Header = Localize(nameof(Header), Header); Header = Localize(nameof(Header), Header);
Message = Localize(nameof(Message), Message); Message = Localize(nameof(Message), Message);
_permissions = (string.IsNullOrEmpty(Permissions)) ? ModuleState.Permissions : Permissions; _permissions = (Permissions == null) ? ModuleState.Permissions : Permissions;
_authorized = IsAuthorized(); _authorized = IsAuthorized();
} }

View File

@ -26,7 +26,7 @@
private string _text = string.Empty; private string _text = string.Empty;
private string _parameters = string.Empty; private string _parameters = string.Empty;
private string _url = string.Empty; private string _url = string.Empty;
private string _permissions = string.Empty; private List<Permission> _permissions;
private bool _editmode = false; private bool _editmode = false;
private bool _authorized = false; private bool _authorized = false;
private string _classname = "btn btn-primary"; private string _classname = "btn btn-primary";
@ -52,7 +52,7 @@
public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel
[Parameter] [Parameter]
public string Permissions { get; set; } // optional - can be used to specify a permission string public List<Permission> Permissions { get; set; } // optional - can be used to specify permissions
[Parameter] [Parameter]
public bool Disabled { get; set; } // optional public bool Disabled { get; set; } // optional
@ -119,7 +119,7 @@
_iconSpan = $"<span class=\"{IconName}\"></span>{(IconOnly ? "" : "&nbsp")}"; _iconSpan = $"<span class=\"{IconName}\"></span>{(IconOnly ? "" : "&nbsp")}";
} }
_permissions = (string.IsNullOrEmpty(Permissions)) ? ModuleState.Permissions : Permissions; _permissions = (Permissions == null) ? ModuleState.Permissions : Permissions;
_text = Localize(nameof(Text), _text); _text = Localize(nameof(Text), _text);
_url = (ModuleId == -1) ? EditUrl(Action, _parameters) : EditUrl(ModuleId, Action, _parameters); _url = (ModuleId == -1) ? EditUrl(Action, _parameters) : EditUrl(ModuleId, Action, _parameters);
if (!string.IsNullOrEmpty(ReturnUrl)) if (!string.IsNullOrEmpty(ReturnUrl))

View File

@ -15,20 +15,19 @@
<tbody> <tbody>
<tr> <tr>
<th scope="col">@Localizer["Role"]</th> <th scope="col">@Localizer["Role"]</th>
@foreach (PermissionString permission in _permissions) @foreach (var permissionname in _permissionnames)
{ {
<th style="text-align: center; width: 1px;">@((MarkupString)GetPermissionName(permission).Replace(" ", "<br />"))</th> <th style="text-align: center; width: 1px;">@((MarkupString)DisplayPermissionName(permissionname).Replace(" ", "<br />"))</th>
} }
</tr> </tr>
@foreach (Role role in _roles) @foreach (Role role in _roles)
{ {
<tr> <tr>
<td>@role.Name</td> <td>@role.Name</td>
@foreach (PermissionString permission in _permissions) @foreach (var permissionname in _permissionnames)
{ {
var p = permission;
<td style="text-align: center;"> <td style="text-align: center;">
<TriStateCheckBox Value=@GetPermissionValue(p.Permissions, role.Name) Disabled="@GetPermissionDisabled(p.EntityName, p.PermissionName, role.Name)" OnChange="@(e => PermissionChanged(e, p.EntityName, p.PermissionName, role.Name))" /> <TriStateCheckBox Value=@GetPermissionValue(permissionname, role.Name, -1) Disabled="@GetPermissionDisabled(permissionname, role.Name)" OnChange="@(e => PermissionChanged(e, permissionname, role.Name, -1))" />
</td> </td>
} }
</tr> </tr>
@ -50,23 +49,21 @@
<thead> <thead>
<tr> <tr>
<th scope="col">@Localizer["User"]</th> <th scope="col">@Localizer["User"]</th>
@foreach (PermissionString permission in _permissions) @foreach (var permissionname in _permissionnames)
{ {
<th style="text-align: center; width: 1px;">@Localizer[permission.PermissionName]</th> <th style="text-align: center; width: 1px;">@((MarkupString)DisplayPermissionName(permissionname).Replace(" ", "<br />"))</th>
} }
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach (User user in _users) @foreach (User user in _users)
{ {
string userid = "[" + user.UserId.ToString() + "]";
<tr> <tr>
<td>@user.DisplayName</td> <td>@user.DisplayName</td>
@foreach (PermissionString permission in _permissions) @foreach (var permissionname in _permissionnames)
{ {
var p = permission;
<td style="text-align: center; width: 1px;"> <td style="text-align: center; width: 1px;">
<TriStateCheckBox Value=@GetPermissionValue(p.Permissions, userid) Disabled="@GetPermissionDisabled(p.EntityName, p.PermissionName, "")" OnChange="@(e => PermissionChanged(e, p.EntityName, p.PermissionName, userid))" /> <TriStateCheckBox Value=@GetPermissionValue(permissionname, "", user.UserId) Disabled="@GetPermissionDisabled(permissionname, "")" OnChange="@(e => PermissionChanged(e, permissionname, "", user.UserId))" />
</td> </td>
} }
</tr> </tr>
@ -94,9 +91,9 @@
} }
@code { @code {
private string _permissionnames = string.Empty; private List<string> _permissionnames;
private List<Permission> _permissions;
private List<Role> _roles; private List<Role> _roles;
private List<PermissionString> _permissions;
private List<User> _users = new List<User>(); private List<User> _users = new List<User>();
private AutoComplete _user; private AutoComplete _user;
private string _message = string.Empty; private string _message = string.Empty;
@ -108,28 +105,31 @@
public string PermissionNames { get; set; } public string PermissionNames { get; set; }
[Parameter] [Parameter]
public string Permissions { get; set; } public List<Permission> Permissions { get; set; }
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
if (string.IsNullOrEmpty(PermissionNames))
{
_permissionnames = Shared.PermissionNames.View + "," + Shared.PermissionNames.Edit;
}
else
{
_permissionnames = PermissionNames;
}
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId, true); _roles = await RoleService.GetRolesAsync(ModuleState.SiteId, true);
if (!UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) if (!UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{ {
_roles.RemoveAll(item => item.Name == RoleNames.Host); _roles.RemoveAll(item => item.Name == RoleNames.Host);
} }
_permissions = new List<PermissionString>(); // get permission names
if (string.IsNullOrEmpty(PermissionNames))
{
_permissionnames = new List<string>();
_permissionnames.Add(Shared.PermissionNames.View);
_permissionnames.Add(Shared.PermissionNames.Edit);
}
else
{
_permissionnames = PermissionNames.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
}
foreach (string permissionname in _permissionnames.Split(',', StringSplitOptions.RemoveEmptyEntries)) // initialize permissions
_permissions = new List<Permission>();
foreach (string permissionname in _permissionnames)
{ {
// permission names can be in the form of "EntityName:PermissionName:Roles" // permission names can be in the form of "EntityName:PermissionName:Roles"
if (permissionname.Contains(":")) if (permissionname.Contains(":"))
@ -137,78 +137,83 @@
var segments = permissionname.Split(':'); var segments = permissionname.Split(':');
if (segments.Length == 3) if (segments.Length == 3)
{ {
if (!segments[2].Contains(RoleNames.Admin)) foreach (var role in segments[2].Split(';'))
{ {
segments[2] = RoleNames.Admin + ";" + segments[2]; // ensure admin access _permissions.Add(new Permission(segments[0], segments[1], role, null, true));
}
// ensure admin access
if (!_permissions.Any(item => item.EntityName == segments[0] && item.PermissionName == segments[1] && item.Role.Name == RoleNames.Admin))
{
_permissions.Add(new Permission(segments[0], segments[1], RoleNames.Admin, null, true));
} }
_permissions.Add(new PermissionString { EntityName = segments[0], PermissionName = segments[1], Permissions = segments[2] });
} }
} }
else else
{ {
_permissions.Add(new PermissionString { EntityName = EntityName, PermissionName = permissionname, Permissions = RoleNames.Admin }); _permissions.Add(new Permission(EntityName, permissionname, RoleNames.Admin, null, true));
} }
} }
if (!string.IsNullOrEmpty(Permissions)) // populate permissions and users
if (Permissions.Any())
{ {
// populate permissions foreach (var permission in Permissions)
foreach (PermissionString permissionstring in UserSecurity.GetPermissionStrings(Permissions))
{ {
int index = _permissions.FindIndex(item => item.EntityName == permissionstring.EntityName && item.PermissionName == permissionstring.PermissionName); if (!_permissions.Any(item => item.EntityName == permission.EntityName && item.PermissionName == permission.PermissionName && item.Role.Name == permission.Role.Name))
if (index != -1)
{ {
_permissions[index].Permissions = permissionstring.Permissions; _permissions.Add(permission);
} }
if (permission.UserId != null)
if (permissionstring.Permissions.Contains("["))
{ {
foreach (string user in permissionstring.Permissions.Split('[', StringSplitOptions.RemoveEmptyEntries)) if (!_users.Any(item => item.UserId == permission.UserId.Value))
{ {
if (user.Contains("]")) _users.Add(await UserService.GetUserAsync(permission.UserId.Value, ModuleState.SiteId));
{
var userid = int.Parse(user.Substring(0, user.IndexOf("]")));
if (_users.Where(item => item.UserId == userid).FirstOrDefault() == null)
{
_users.Add(await UserService.GetUserAsync(userid, ModuleState.SiteId));
}
}
} }
} }
} }
} }
} }
private string GetPermissionName(PermissionString permission) private string GetPermissionName(string permissionName)
{ {
var permissionname = Localizer[permission.PermissionName].ToString(); return (permissionName.Contains(":")) ? permissionName.Split(':')[1] : permissionName;
if (!string.IsNullOrEmpty(EntityName))
{
permissionname += " " + Localizer[permission.EntityName].ToString();
}
return permissionname;
} }
private bool? GetPermissionValue(string permissions, string securityKey) private string GetEntityName(string permissionName)
{ {
if ((";" + permissions + ";").Contains(";" + "!" + securityKey + ";")) return (permissionName.Contains(":")) ? permissionName.Split(':')[0] : EntityName;
}
private string DisplayPermissionName(string permissionName)
{
var name = Localizer[GetPermissionName(permissionName)].ToString();
name += " " + Localizer[GetEntityName(permissionName)].ToString();
return name;
}
private bool? GetPermissionValue(string permissionName, string roleName, int userId)
{
bool? isauthorized = null;
if (roleName != "")
{ {
return false; // deny permission var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.Role.Name == roleName);
if (permission != null)
{
isauthorized = permission.IsAuthorized;
}
} }
else else
{ {
if ((";" + permissions + ";").Contains(";" + securityKey + ";")) var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.UserId == userId);
if (permission != null)
{ {
return true; // grant permission isauthorized = permission.IsAuthorized;
}
else
{
return null; // not specified
} }
} }
return isauthorized;
} }
private bool GetPermissionDisabled(string entityName, string permissionName, string roleName) private bool GetPermissionDisabled(string permissionName, string roleName)
{ {
if (roleName == RoleNames.Admin && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) if (roleName == RoleNames.Admin && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{ {
@ -216,7 +221,7 @@
} }
else else
{ {
if (entityName != EntityName && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin)) if (GetEntityName(permissionName) != EntityName && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
{ {
return true; return true;
} }
@ -227,6 +232,34 @@
} }
} }
private void PermissionChanged(bool? value, string permissionName, string roleName, int userId)
{
if (roleName != "")
{
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.Role.Name == roleName);
if (permission == null)
{
_permissions.Remove(permission);
}
if (value != null)
{
_permissions.Add(new Permission(GetEntityName(permissionName), GetPermissionName(permissionName), roleName, null, value.Value));
}
}
else
{
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.UserId == userId);
if (permission == null)
{
_permissions.Remove(permission);
}
if (value != null)
{
_permissions.Add(new Permission(GetEntityName(permissionName), GetPermissionName(permissionName), null, userId, value.Value));
}
}
}
private async Task<Dictionary<string, string>> GetUsers(string filter) private async Task<Dictionary<string, string>> GetUsers(string filter)
{ {
var users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered); var users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered);
@ -251,62 +284,39 @@
_user.Clear(); _user.Clear();
} }
private void PermissionChanged(bool? value, string entityName, string permissionName, string securityId) public List<Permission> GetPermissions()
{
var selected = value;
int index = _permissions.FindIndex(item => item.EntityName == entityName && item.PermissionName == permissionName);
if (index != -1)
{
var permission = _permissions[index];
var ids = permission.Permissions.Split(';').ToList();
ids.Remove(securityId); // remove grant permission
ids.Remove("!" + securityId); // remove deny permission
switch (selected)
{
case true:
ids.Add(securityId); // add grant permission
break;
case false:
ids.Add("!" + securityId); // add deny permission
break;
case null:
break; // permission not specified
}
_permissions[index].Permissions = string.Join(";", ids.ToArray());
}
}
public string GetPermissions()
{ {
ValidatePermissions(); ValidatePermissions();
return UserSecurity.SetPermissionStrings(_permissions); return _permissions;
} }
private void ValidatePermissions() private void ValidatePermissions()
{ {
PermissionString permission; // remove deny all users, unauthenticated, and registered users
for (int index = 0; index < _permissions.Count; index++) var permissions = _permissions.Where(item => !item.IsAuthorized &&
(item.Role.Name == RoleNames.Everyone || item.Role.Name == RoleNames.Unauthenticated || item.Role.Name == RoleNames.Registered));
foreach (var permission in permissions)
{ {
permission = _permissions[index]; _permissions.Remove(permission);
List<string> ids = permission.Permissions.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList(); }
ids.Remove("!" + RoleNames.Everyone); // remove deny all users if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
ids.Remove("!" + RoleNames.Unauthenticated); // remove deny unauthenticated {
ids.Remove("!" + RoleNames.Registered); // remove deny registered users // remove deny administrators and host users
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) permissions = _permissions.Where(item => !item.IsAuthorized &&
(item.Role.Name == RoleNames.Admin || item.Role.Name == RoleNames.Host));
foreach (var permission in permissions)
{ {
ids.Remove("!" + RoleNames.Admin); // remove deny administrators _permissions.Remove(permission);
ids.Remove("!" + RoleNames.Host); // remove deny host users }
if (!ids.Contains(RoleNames.Host) && !ids.Contains(RoleNames.Admin)) foreach (var permissionname in _permissionnames)
{
// add administrators role if neither host or administrator is assigned
if (!_permissions.Any(item => item.EntityName == GetEntityName(permissionname) && item.PermissionName == GetPermissionName(permissionname) &&
(item.Role.Name == RoleNames.Admin || item.Role.Name == RoleNames.Host)))
{ {
// add administrators role if host user role is not assigned _permissions.Add(new Permission(GetEntityName(permissionname), GetPermissionName(permissionname), RoleNames.Admin, null, true));
ids.Add(RoleNames.Admin);
} }
} }
permission.Permissions = string.Join(";", ids.ToArray()); }
_permissions[index] = permission;
}
} }
} }

View File

@ -136,36 +136,32 @@ namespace Oqtane.Themes.Controls
private async Task<string> Publish(string url, PageModule pagemodule) private async Task<string> Publish(string url, PageModule pagemodule)
{ {
var permissions = UserSecurity.GetPermissionStrings(pagemodule.Module.Permissions); var permissions = pagemodule.Module.Permissions;
foreach (var permissionstring in permissions) if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Everyone))
{ {
if (permissionstring.PermissionName == PermissionNames.View) permissions.Add(new Permission(EntityNames.Page, pagemodule.PageId, PermissionNames.View, RoleNames.Everyone, null, true));
{
List<string> ids = permissionstring.Permissions.Split(';').ToList();
if (!ids.Contains(RoleNames.Everyone)) ids.Add(RoleNames.Everyone);
if (!ids.Contains(RoleNames.Registered)) ids.Add(RoleNames.Registered);
permissionstring.Permissions = string.Join(";", ids.ToArray());
}
} }
pagemodule.Module.Permissions = UserSecurity.SetPermissionStrings(permissions); if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Registered))
{
permissions.Add(new Permission(EntityNames.Page, pagemodule.PageId, PermissionNames.View, RoleNames.Registered, null, true));
}
pagemodule.Module.Permissions = permissions;
await ModuleService.UpdateModuleAsync(pagemodule.Module); await ModuleService.UpdateModuleAsync(pagemodule.Module);
return url; return url;
} }
private async Task<string> Unpublish(string url, PageModule pagemodule) private async Task<string> Unpublish(string url, PageModule pagemodule)
{ {
var permissions = UserSecurity.GetPermissionStrings(pagemodule.Module.Permissions); var permissions = pagemodule.Module.Permissions;
foreach (var permissionstring in permissions) if (permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Everyone))
{ {
if (permissionstring.PermissionName == PermissionNames.View) permissions.Remove(permissions.First(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Everyone));
{
List<string> ids = permissionstring.Permissions.Split(';').ToList();
ids.Remove(RoleNames.Everyone);
ids.Remove(RoleNames.Registered);
permissionstring.Permissions = string.Join(";", ids.ToArray());
}
} }
pagemodule.Module.Permissions = UserSecurity.SetPermissionStrings(permissions); if (permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Registered))
{
permissions.Remove(permissions.First(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Registered));
}
pagemodule.Module.Permissions = permissions;
await ModuleService.UpdateModuleAsync(pagemodule.Module); await ModuleService.UpdateModuleAsync(pagemodule.Module);
return url; return url;
} }

View File

@ -392,20 +392,21 @@
module.ModuleDefinitionName = ModuleDefinitionName; module.ModuleDefinitionName = ModuleDefinitionName;
module.AllPages = false; module.AllPages = false;
List<PermissionString> permissions = UserSecurity.GetPermissionStrings(PageState.Page.Permissions); var permissions = new List<Permission>();
if (Visibility == "view") if (Visibility == "view")
{ {
// set module view permissions to page view permissions // set module view permissions to page view permissions
permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions = permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions; permissions = PageState.Page.Permissions.Where(item => item.PermissionName == PermissionNames.View).ToList();
} }
else else
{ {
// set module view permissions to page edit permissions // set module view permissions to page edit permissions
permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions = permissions.Find(p => p.PermissionName == PermissionNames.Edit).Permissions; permissions = PageState.Page.Permissions.Where(item => item.PermissionName == PermissionNames.Edit).ToList();
} }
// set entityname // set entity name and permission name
permissions.ForEach(item => item.EntityName = EntityNames.Module); permissions.ForEach(item => item.EntityName = EntityNames.Module);
module.Permissions = UserSecurity.SetPermissionStrings(permissions); permissions.ForEach(item => item.PermissionName = PermissionNames.View);
module.Permissions = permissions;
module = await ModuleService.AddModuleAsync(module); module = await ModuleService.AddModuleAsync(module);
ModuleId = module.ModuleId.ToString(); ModuleId = module.ModuleId.ToString();
@ -527,32 +528,17 @@
{ {
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions)) if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
{ {
List<PermissionString> permissions; var permissions = PageState.Page.Permissions;
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Everyone))
// publish/unpublish page {
var page = PageState.Page; permissions.Add(new Permission(EntityNames.Page, PageState.Page.PageId, PermissionNames.View, RoleNames.Everyone, null, true));
permissions = UserSecurity.GetPermissionStrings(page.Permissions); }
foreach (var permissionstring in permissions) if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Registered))
{ {
if (permissionstring.PermissionName == PermissionNames.View) permissions.Add(new Permission(EntityNames.Page, PageState.Page.PageId, PermissionNames.View, RoleNames.Registered, null, true));
{ }
List<string> ids = permissionstring.Permissions.Split(';').ToList(); PageState.Page.Permissions = permissions;
switch (action) await PageService.UpdatePageAsync(PageState.Page);
{
case "publish":
if (!ids.Contains(RoleNames.Everyone)) ids.Add(RoleNames.Everyone);
if (!ids.Contains(RoleNames.Registered)) ids.Add(RoleNames.Registered);
break;
case "unpublish":
ids.Remove(RoleNames.Everyone);
ids.Remove(RoleNames.Registered);
break;
}
permissionstring.Permissions = string.Join(";", ids.ToArray());
}
}
page.Permissions = UserSecurity.SetPermissionStrings(permissions);
await PageService.UpdatePageAsync(page);
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true)); NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
} }
} }

View File

@ -104,7 +104,7 @@ namespace Oqtane.Controllers
{ {
if (ModelState.IsValid && folder.SiteId == _alias.SiteId) if (ModelState.IsValid && folder.SiteId == _alias.SiteId)
{ {
string permissions; List<Permission> permissions;
if (folder.ParentId != null) if (folder.ParentId != null)
{ {
permissions = _folders.GetFolder(folder.ParentId.Value).Permissions; permissions = _folders.GetFolder(folder.ParentId.Value).Permissions;

View File

@ -128,7 +128,7 @@ namespace Oqtane.Controllers
{ {
if (ModelState.IsValid && page.SiteId == _alias.SiteId) if (ModelState.IsValid && page.SiteId == _alias.SiteId)
{ {
string permissions; List<Permission> permissions;
if (page.ParentId != null) if (page.ParentId != null)
{ {
permissions = _pages.GetPage(page.ParentId.Value).Permissions; permissions = _pages.GetPage(page.ParentId.Value).Permissions;
@ -274,9 +274,8 @@ namespace Oqtane.Controllers
} }
// get differences between current and new page permissions // get differences between current and new page permissions
var newPermissions = _permissionRepository.DecodePermissions(page.Permissions, page.SiteId, EntityNames.Page, page.PageId).ToList(); var added = GetPermissionsDifferences(page.Permissions, currentPermissions);
var added = GetPermissionsDifferences(newPermissions, currentPermissions); var removed = GetPermissionsDifferences(currentPermissions, page.Permissions);
var removed = GetPermissionsDifferences(currentPermissions, newPermissions);
// synchronize module permissions // synchronize module permissions
if (added.Count > 0 || removed.Count > 0) if (added.Count > 0 || removed.Count > 0)

View File

@ -1,66 +1,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Text.Json;
using Oqtane.Models; using Oqtane.Models;
namespace Oqtane.Extensions namespace Oqtane.Extensions
{ {
public static class PermissionExtension public static class PermissionExtension
{ {
public static string EncodePermissions(this IEnumerable<Permission> permissionList) public static List<Permission> EncodePermissions(this IEnumerable<Permission> permissionList)
{ {
List<PermissionString> permissionstrings = new List<PermissionString>(); return permissionList.ToList();
string entityname = "";
string permissionname = "";
string permissions = "";
StringBuilder permissionsbuilder = new StringBuilder();
string securityid = "";
foreach (Permission permission in permissionList.OrderBy(item => item.EntityName).ThenBy(item => item.PermissionName))
{
// permission collections are grouped by entityname and permissionname
if (entityname != permission.EntityName || permissionname != permission.PermissionName)
{
permissions = permissionsbuilder.ToString();
if (permissions != "")
{
permissionstrings.Add(new PermissionString { EntityName = entityname, PermissionName = permissionname, Permissions = permissions.Substring(0, permissions.Length - 1) });
}
entityname = permission.EntityName;
permissionname = permission.PermissionName;
permissionsbuilder = new StringBuilder();
}
// deny permissions are prefixed with a "!"
string prefix = !permission.IsAuthorized ? "!" : "";
// encode permission
if (permission.UserId == null)
{
securityid = prefix + permission.Role.Name + ";";
}
else
{
securityid = prefix + "[" + permission.UserId + "];";
}
// insert deny permissions at the beginning and append grant permissions at the end
if (prefix == "!")
{
permissionsbuilder.Insert(0, securityid);
}
else
{
permissionsbuilder.Append(securityid);
}
}
permissions = permissionsbuilder.ToString();
if (permissions != "")
{
permissionstrings.Add(new PermissionString { EntityName = entityname, PermissionName = permissionname, Permissions = permissions.Substring(0, permissions.Length - 1) });
}
return JsonSerializer.Serialize(permissionstrings);
} }
} }
} }

View File

@ -11,13 +11,11 @@ namespace Oqtane.Repository
IEnumerable<Permission> GetPermissions(int siteId, string entityName, string permissionName); IEnumerable<Permission> GetPermissions(int siteId, string entityName, string permissionName);
IEnumerable<Permission> GetPermissions(int siteId, string entityName, int entityId); IEnumerable<Permission> GetPermissions(int siteId, string entityName, int entityId);
IEnumerable<Permission> GetPermissions(int siteId, string entityName, int entityId, string permissionName); IEnumerable<Permission> GetPermissions(int siteId, string entityName, int entityId, string permissionName);
Permission AddPermission(Permission permission); Permission AddPermission(Permission permission);
Permission UpdatePermission(Permission permission); Permission UpdatePermission(Permission permission);
void UpdatePermissions(int siteId, string entityName, int entityId, string permissionStrings); void UpdatePermissions(int siteId, string entityName, int entityId, List<Permission> permissions);
Permission GetPermission(int permissionId); Permission GetPermission(int permissionId);
void DeletePermission(int permissionId); void DeletePermission(int permissionId);
void DeletePermissions(int siteId, string entityName, int entityId); void DeletePermissions(int siteId, string entityName, int entityId);
IEnumerable<Permission> DecodePermissions(string permissions, int siteId, string entityName, int entityId);
} }
} }

View File

@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore;
using Oqtane.Models; using Oqtane.Models;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Oqtane.Infrastructure; using Oqtane.Infrastructure;
using Oqtane.Modules.Admin.Users;
namespace Oqtane.Repository namespace Oqtane.Repository
{ {
@ -77,11 +78,28 @@ namespace Oqtane.Repository
return permission; return permission;
} }
public void UpdatePermissions(int siteId, string entityName, int entityId, string permissionStrings) public void UpdatePermissions(int siteId, string entityName, int entityId, List<Permission> permissions)
{ {
// ensure permissions are fully populated
List<Role> roles = _roles.GetRoles(siteId, true).ToList();
foreach (var permission in permissions)
{
permission.SiteId = siteId;
permission.EntityName = (string.IsNullOrEmpty(permission.EntityName)) ? entityName : permission.EntityName;
permission.EntityId = (permission.EntityName == entityName) ? entityId : -1;
if (permission.RoleId == null && permission.Role != null && !string.IsNullOrEmpty(permission.Role.Name))
{
var role = roles.FirstOrDefault(item => item.Name == permission.Role.Name);
if (role != null)
{
permission.RoleId = role.RoleId;
}
}
permission.Role = null;
}
// add or update permissions
bool modified = false; bool modified = false;
var existing = new List<Permission>(); var existing = new List<Permission>();
var permissions = DecodePermissions(permissionStrings, siteId, entityName, entityId);
foreach (var permission in permissions) foreach (var permission in permissions)
{ {
if (!existing.Any(item => item.EntityName == permission.EntityName && item.PermissionName == permission.PermissionName)) if (!existing.Any(item => item.EntityName == permission.EntityName && item.PermissionName == permission.PermissionName))
@ -108,6 +126,7 @@ namespace Oqtane.Repository
modified = true; modified = true;
} }
} }
// delete permissions
foreach (var permission in existing) foreach (var permission in existing)
{ {
if (!permissions.Any(item => item.EntityName == permission.EntityName && item.PermissionName == permission.PermissionName if (!permissions.Any(item => item.EntityName == permission.EntityName && item.PermissionName == permission.PermissionName
@ -163,122 +182,5 @@ namespace Oqtane.Repository
_cache.Remove($"permissions:{alias.TenantId}:{siteId}:{entityName}"); _cache.Remove($"permissions:{alias.TenantId}:{siteId}:{entityName}");
} }
} }
}
// permissions are stored in the format "{permissionname:!rolename1;![userid1];rolename2;rolename3;[userid2];[userid3]}" where "!" designates Deny permissions
public string EncodePermissions(IEnumerable<Permission> permissionList)
{
List<PermissionString> permissionstrings = new List<PermissionString>();
string permissionname = "";
string permissions = "";
StringBuilder permissionsbuilder = new StringBuilder();
string securityid = "";
foreach (Permission permission in permissionList.OrderBy(item => item.PermissionName))
{
// permission collections are grouped by permissionname
if (permissionname != permission.PermissionName)
{
permissions = permissionsbuilder.ToString();
if (permissions != "")
{
permissionstrings.Add(new PermissionString { PermissionName = permissionname, Permissions = permissions.Substring(0, permissions.Length - 1) });
}
permissionname = permission.PermissionName;
permissionsbuilder = new StringBuilder();
}
// deny permissions are prefixed with a "!"
string prefix = !permission.IsAuthorized ? "!" : "";
// encode permission
if (permission.UserId == null)
{
securityid = prefix + permission.Role.Name + ";";
}
else
{
securityid = prefix + "[" + permission.UserId + "];";
}
// insert deny permissions at the beginning and append grant permissions at the end
if (prefix == "!")
{
permissionsbuilder.Insert(0, securityid);
}
else
{
permissionsbuilder.Append(securityid);
}
}
permissions = permissionsbuilder.ToString();
if (permissions != "")
{
permissionstrings.Add(new PermissionString { PermissionName = permissionname, Permissions = permissions.Substring(0, permissions.Length - 1) });
}
return JsonSerializer.Serialize(permissionstrings);
}
public IEnumerable<Permission> DecodePermissions(string permissionStrings, int siteId, string entityName, int entityId)
{
List<Permission> permissions = new List<Permission>();
List<Role> roles = _roles.GetRoles(siteId, true).ToList();
string securityid = "";
foreach (PermissionString permissionstring in JsonSerializer.Deserialize<List<PermissionString>>(permissionStrings))
{
foreach (string id in permissionstring.Permissions.Split(';', StringSplitOptions.RemoveEmptyEntries))
{
securityid = id;
Permission permission = new Permission();
permission.SiteId = siteId;
if (!string.IsNullOrEmpty(permissionstring.EntityName))
{
permission.EntityName = permissionstring.EntityName;
}
else
{
permission.EntityName = entityName;
}
if (permission.EntityName == entityName)
{
permission.EntityId = entityId;
}
else
{
permission.EntityId = -1;
}
permission.PermissionName = permissionstring.PermissionName;
permission.RoleId = null;
permission.UserId = null;
permission.IsAuthorized = true;
if (securityid.StartsWith("!"))
{
// deny permission
securityid = securityid.Replace("!", "");
permission.IsAuthorized = false;
}
if (securityid.StartsWith("[") && securityid.EndsWith("]"))
{
// user id
securityid = securityid.Replace("[", "").Replace("]", "");
permission.UserId = int.Parse(securityid);
}
else
{
// role name
Role role = roles.SingleOrDefault(item => item.Name == securityid);
if (role != null)
{
permission.RoleId = role.RoleId;
}
}
if (permission.UserId != null || permission.RoleId != null)
{
permissions.Add(permission);
}
}
}
return permissions;
}
}
} }

View File

@ -5,6 +5,7 @@ using System.Security.Claims;
using Oqtane.Repository; using Oqtane.Repository;
using Oqtane.Extensions; using Oqtane.Extensions;
using System; using System;
using System.Collections.Generic;
namespace Oqtane.Security namespace Oqtane.Security
{ {
@ -12,7 +13,7 @@ namespace Oqtane.Security
{ {
bool IsAuthorized(ClaimsPrincipal user, int siteId, string entityName, int entityId, string permissionName, string roles); bool IsAuthorized(ClaimsPrincipal user, int siteId, string entityName, int entityId, string permissionName, string roles);
bool IsAuthorized(ClaimsPrincipal user, int siteId, string entityName, int entityId, string permissionName); bool IsAuthorized(ClaimsPrincipal user, int siteId, string entityName, int entityId, string permissionName);
bool IsAuthorized(ClaimsPrincipal user, string permissionName, string permissions); bool IsAuthorized(ClaimsPrincipal user, string permissionName, List<Permission> permissions);
User GetUser(ClaimsPrincipal user); User GetUser(ClaimsPrincipal user);
User GetUser(); User GetUser();
@ -36,7 +37,7 @@ namespace Oqtane.Security
var permissions = _permissions.GetPermissions(siteId, entityName, entityId, permissionName).ToList(); var permissions = _permissions.GetPermissions(siteId, entityName, entityId, permissionName).ToList();
if (permissions != null && permissions.Count != 0) if (permissions != null && permissions.Count != 0)
{ {
return IsAuthorized(principal, permissionName, permissions.EncodePermissions()); return IsAuthorized(principal, permissionName, permissions.ToList());
} }
else else
{ {
@ -46,10 +47,10 @@ namespace Oqtane.Security
public bool IsAuthorized(ClaimsPrincipal principal, int siteId, string entityName, int entityId, string permissionName) public bool IsAuthorized(ClaimsPrincipal principal, int siteId, string entityName, int entityId, string permissionName)
{ {
return IsAuthorized(principal, permissionName, _permissions.GetPermissions(siteId, entityName, entityId, permissionName)?.EncodePermissions()); return IsAuthorized(principal, permissionName, _permissions.GetPermissions(siteId, entityName, entityId, permissionName).ToList());
} }
public bool IsAuthorized(ClaimsPrincipal principal, string permissionName, string permissions) public bool IsAuthorized(ClaimsPrincipal principal, string permissionName, List<Permission> permissions)
{ {
return UserSecurity.IsAuthorized(GetUser(principal), permissionName, permissions); return UserSecurity.IsAuthorized(GetUser(principal), permissionName, permissions);
} }
@ -96,7 +97,7 @@ namespace Oqtane.Security
// deprecated // deprecated
public bool IsAuthorized(ClaimsPrincipal principal, string entityName, int entityId, string permissionName) public bool IsAuthorized(ClaimsPrincipal principal, string entityName, int entityId, string permissionName)
{ {
return IsAuthorized(principal, permissionName, _permissions.GetPermissions(_accessor.HttpContext.GetAlias().SiteId, entityName, entityId, permissionName)?.EncodePermissions()); return IsAuthorized(principal, permissionName, _permissions.GetPermissions(_accessor.HttpContext.GetAlias().SiteId, entityName, entityId, permissionName).ToList());
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
namespace Oqtane.Models namespace Oqtane.Models
@ -68,7 +69,7 @@ namespace Oqtane.Models
/// TODO: todoc what would this contain? /// TODO: todoc what would this contain?
/// </summary> /// </summary>
[NotMapped] [NotMapped]
public string Permissions { get; set; } public List<Permission> Permissions { get; set; }
/// <summary> /// <summary>
/// Folder Depth /// Folder Depth

View File

@ -42,7 +42,7 @@ namespace Oqtane.Models
#endregion #endregion
[NotMapped] [NotMapped]
public string Permissions { get; set; } public List<Permission> Permissions { get; set; }
[NotMapped] [NotMapped]
public Dictionary<string, string> Settings { get; set; } public Dictionary<string, string> Settings { get; set; }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Oqtane.Documentation; using Oqtane.Documentation;
@ -99,7 +100,7 @@ namespace Oqtane.Models
[NotMapped] [NotMapped]
public string AssemblyName { get; set; } public string AssemblyName { get; set; }
[NotMapped] [NotMapped]
public string Permissions { get; set; } public List<Permission> Permissions { get; set; }
[NotMapped] [NotMapped]
public string Template { get; set; } public string Template { get; set; }
} }

View File

@ -98,7 +98,7 @@ namespace Oqtane.Models
public List<Resource> Resources { get; set; } public List<Resource> Resources { get; set; }
[NotMapped] [NotMapped]
public string Permissions { get; set; } public List<Permission> Permissions { get; set; }
[NotMapped] [NotMapped]
public Dictionary<string, string> Settings { get; set; } public Dictionary<string, string> Settings { get; set; }

View File

@ -1,4 +1,5 @@
using System; using System;
using Oqtane.Shared;
namespace Oqtane.Models namespace Oqtane.Models
{ {
@ -66,15 +67,41 @@ namespace Oqtane.Models
public Permission(string permissionName, string roleName, bool isAuthorized) public Permission(string permissionName, string roleName, bool isAuthorized)
{ {
PermissionName = permissionName; Initialize("", -1, permissionName, roleName, null, isAuthorized);
Role = new Role { Name = roleName };
IsAuthorized = isAuthorized;
} }
public Permission(string permissionName, int userId, bool isAuthorized) public Permission(string permissionName, int userId, bool isAuthorized)
{ {
Initialize("", -1, permissionName, "", userId, isAuthorized);
}
public Permission(string entityName, string permissionName, string roleName, int? userId, bool isAuthorized)
{
Initialize(entityName, -1, permissionName, roleName, userId, isAuthorized);
}
public Permission(string entityName, int entityId, string permissionName, string roleName, int? userId, bool isAuthorized)
{
Initialize(entityName, entityId, permissionName, roleName, userId, isAuthorized);
}
private void Initialize(string entityName, int entityId, string permissionName, string roleName, int? userId, bool isAuthorized)
{
EntityName = entityName;
EntityId = entityId;
PermissionName = permissionName; PermissionName = permissionName;
UserId = userId; if (!string.IsNullOrEmpty(roleName))
{
Role = new Role { Name = roleName };
RoleId = null;
UserId = null;
}
else
{
Role = null;
RoleId = null;
UserId = userId;
}
IsAuthorized = isAuthorized; IsAuthorized = isAuthorized;
} }
} }

View File

@ -1,23 +0,0 @@
namespace Oqtane.Models
{
/// <summary>
/// Use this to define a <see cref="PermissionName"/> which addresses a set of multiple permissions.
/// </summary>
public class PermissionString
{
/// <summary>
/// A term describing the entity
/// </summary>
public string EntityName { get; set; }
/// <summary>
/// A term describing a set of permissions
/// </summary>
public string PermissionName { get; set; }
/// <summary>
/// The permissions
/// </summary>
public string Permissions { get; set; }
}
}

View File

@ -18,7 +18,7 @@ namespace Oqtane.Models
public string Icon { get; set; } public string Icon { get; set; }
public bool IsNavigation { get; set; } public bool IsNavigation { get; set; }
public bool IsPersonalizable { get; set; } public bool IsPersonalizable { get; set; }
public string PagePermissions { get; set; } public List<Permission> PagePermissions { get; set; }
public List<PageTemplateModule> PageTemplateModules { get; set; } public List<PageTemplateModule> PageTemplateModules { get; set; }
[Obsolete("This property is obsolete", false)] [Obsolete("This property is obsolete", false)]
@ -30,7 +30,7 @@ namespace Oqtane.Models
public string ModuleDefinitionName { get; set; } public string ModuleDefinitionName { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string Pane { get; set; } public string Pane { get; set; }
public string ModulePermissions { get; set; } public List<Permission> ModulePermissions { get; set; }
public string Content { get; set; } public string Content { get; set; }
} }
} }

View File

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Text.Json;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Shared; using Oqtane.Shared;
@ -10,38 +9,25 @@ namespace Oqtane.Security
{ {
public class UserSecurity public class UserSecurity
{ {
public static List<PermissionString> GetPermissionStrings(string permissionStrings) public static bool IsAuthorized(User user, string roles)
{ {
return JsonSerializer.Deserialize<List<PermissionString>>(permissionStrings); var permissions = new List<Permission>();
} foreach (var role in roles.Split(';', StringSplitOptions.RemoveEmptyEntries))
public static string SetPermissionStrings(List<PermissionString> permissionStrings)
{
return JsonSerializer.Serialize(permissionStrings);
}
public static string GetPermissions(string permissionName, string permissionStrings)
{
string permissions = "";
List<PermissionString> permissionstrings = JsonSerializer.Deserialize<List<PermissionString>>(permissionStrings);
PermissionString permissionstring = permissionstrings.FirstOrDefault(item => item.PermissionName == permissionName);
if (permissionstring != null)
{ {
permissions = permissionstring.Permissions; permissions.Add(new Permission("", role, true));
} }
return permissions; return IsAuthorized(user, permissions);
} }
public static bool IsAuthorized(User user, string permissionName, string permissionStrings) public static bool IsAuthorized(User user, string permissionName, List<Permission> permissions)
{ {
return IsAuthorized(user, GetPermissions(permissionName, permissionStrings)); return IsAuthorized(user, permissions.Where(item => item.PermissionName == permissionName).ToList());
} }
// permissions are stored in the format "!rolename1;![userid1];rolename2;rolename3;[userid2];[userid3]" where "!" designates Deny permissions public static bool IsAuthorized(User user, List<Permission> permissions)
public static bool IsAuthorized(User user, string permissions)
{ {
bool authorized = false; bool authorized = false;
if (permissions != "") if (permissions != null && permissions.Any())
{ {
if (user == null) if (user == null)
{ {
@ -56,77 +42,43 @@ namespace Oqtane.Security
return authorized; return authorized;
} }
private static bool IsAuthorized(int userId, string roles, string permissions) private static bool IsAuthorized(int userId, string roles, List<Permission> permissions)
{ {
bool isAuthorized = false; bool isAuthorized = false;
if (permissions != null) if (permissions != null && permissions.Any())
{ {
foreach (string permission in permissions.Split(';', StringSplitOptions.RemoveEmptyEntries)) // check if denied first
isAuthorized = !permissions.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.UserId.Value == userId))).Any();
if (isAuthorized)
{ {
bool? allowed = VerifyPermission(userId, roles, permission); // then check if authorized
if (allowed.HasValue) isAuthorized = permissions.Where(item => item.IsAuthorized && (
{ (item.Role != null && (
isAuthorized = allowed.Value; (item.Role.Name == RoleNames.Everyone) ||
break; (item.Role.Name == RoleNames.Unauthenticated && userId == -1) ||
} roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.Role.Name))) ||
(item.UserId != null && item.UserId.Value == userId))).Any();
} }
} }
return isAuthorized; return isAuthorized;
} }
private static bool? VerifyPermission(int userId, string roles, string permission) public static bool ContainsRole(List<Permission> permissions, string permissionName, string roleName)
{ {
bool? allowed = null; return permissions.Any(item => item.PermissionName == permissionName && item.Role.Name == roleName);
//permissions strings are encoded with deny permissions at the beginning and grant permissions at the end for optimal performance
if (!String.IsNullOrEmpty(permission))
{
// deny permission
if (permission.StartsWith("!"))
{
string denyRole = permission.Replace("!", "");
if (denyRole == RoleNames.Everyone || IsAllowed(userId, roles, denyRole))
{
allowed = false;
}
}
else // grant permission
{
if (permission == RoleNames.Everyone || IsAllowed(userId, roles, permission))
{
allowed = true;
}
}
}
return allowed;
} }
private static bool IsAllowed(int userId, string roles, string permission) public static bool ContainsUser(List<Permission> permissions, string permissionName, int userId)
{ {
if (permission == RoleNames.Unauthenticated) return permissions.Any(item => item.PermissionName == permissionName && item.UserId == userId);
{
return userId == -1;
}
if ("[" + userId + "]" == permission)
{
return true;
}
if (roles != null)
{
return roles.IndexOf(";" + permission + ";") != -1;
}
return false;
}
public static bool ContainsRole(string permissionStrings, string permissionName, string roleName)
{
return GetPermissionStrings(permissionStrings).FirstOrDefault(item => item.PermissionName == permissionName).Permissions.Split(';').Contains(roleName);
}
public static bool ContainsUser(string permissionStrings, string permissionName, int userId)
{
return GetPermissionStrings(permissionStrings).FirstOrDefault(item => item.PermissionName == permissionName).Permissions.Split(';').Contains($"[{userId}]");
} }
public static ClaimsIdentity CreateClaimsIdentity(Alias alias, User user, List<UserRole> userroles) public static ClaimsIdentity CreateClaimsIdentity(Alias alias, User user, List<UserRole> userroles)