Merge pull request #5408 from sbwalker/dev

improve user experience of permissions grid
This commit is contained in:
Shaun Walker
2025-07-22 16:12:48 -04:00
committed by GitHub
4 changed files with 263 additions and 255 deletions

View File

@ -9,7 +9,7 @@
@if (_permissions != null) @if (_permissions != null)
{ {
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<table class="table table-borderless"> <table class="table table-borderless">
@ -28,7 +28,7 @@
@foreach (var permissionname in _permissionnames) @foreach (var permissionname in _permissionnames)
{ {
<td style="text-align: center;"> <td style="text-align: center;">
<TriStateCheckBox Value=@GetPermissionValue(permissionname, role.Name, -1) Disabled="@GetPermissionDisabled(permissionname, role.Name)" OnChange="@(e => PermissionChanged(e, permissionname, role.Name, -1))" /> <TriStateCheckBox Value="@GetPermissionValue(permissionname, role.Name, -1)" Disabled="@GetPermissionDisabled(permissionname, role.Name)" OnChange="@(e => PermissionChanged(e, permissionname, role.Name, -1))" />
</td> </td>
} }
</tr> </tr>
@ -64,7 +64,7 @@
@foreach (var permissionname in _permissionnames) @foreach (var permissionname in _permissionnames)
{ {
<td style="text-align: center; width: 1px;"> <td style="text-align: center; width: 1px;">
<TriStateCheckBox Value=@GetPermissionValue(permissionname, "", user.UserId) Disabled="@GetPermissionDisabled(permissionname, "")" OnChange="@(e => PermissionChanged(e, permissionname, "", user.UserId))" /> <TriStateCheckBox Value="@GetPermissionValue(permissionname, "", user.UserId)" Disabled="@GetPermissionDisabled(permissionname, "")" OnChange="@(e => PermissionChanged(e, permissionname, "", user.UserId))" />
</td> </td>
} }
</tr> </tr>
@ -88,7 +88,7 @@
<ModuleMessage Type="MessageType.Warning" Message="@_message" /> <ModuleMessage Type="MessageType.Warning" Message="@_message" />
</div> </div>
</div> </div>
</div> </div>
} }
@code { @code {
@ -119,10 +119,7 @@
} }
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId, true); _roles = await RoleService.GetRolesAsync(ModuleState.SiteId, true);
if (!UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) _roles.RemoveAll(item => item.Name == RoleNames.Host); // remove host role
{
_roles.RemoveAll(item => item.Name == RoleNames.Host);
}
// get permission names // get permission names
if (string.IsNullOrEmpty(PermissionNames)) if (string.IsNullOrEmpty(PermissionNames))
@ -222,24 +219,24 @@
private bool GetPermissionDisabled(string permissionName, string roleName) private bool GetPermissionDisabled(string permissionName, string roleName)
{ {
var disabled = false;
// administrator role permissions can only be changed by a host
if (roleName == RoleNames.Admin && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) if (roleName == RoleNames.Admin && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{ {
return true; disabled = true;
}
else
{
if (GetEntityName(permissionName) != EntityName && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
{
return true;
}
else
{
return false;
}
}
} }
private void PermissionChanged(bool? value, string permissionName, string roleName, int userId) // API permissions can only be changed by an administrator
if (GetEntityName(permissionName) != EntityName && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
{
disabled = true;
}
return disabled;
}
private bool? PermissionChanged(bool? value, string permissionName, string roleName, int userId)
{ {
if (roleName != "") if (roleName != "")
{ {
@ -248,6 +245,14 @@
{ {
_permissions.Remove(permission); _permissions.Remove(permission);
} }
// system roles cannot be denied - only custom roles can be denied
var role = _roles.FirstOrDefault(item => item.Name == roleName);
if (value != null && !value.Value && role.IsSystem)
{
value = null;
}
if (value != null) if (value != null)
{ {
_permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionName), GetPermissionName(permissionName), roleName, null, value.Value)); _permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionName), GetPermissionName(permissionName), roleName, null, value.Value));
@ -265,6 +270,7 @@
_permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionName), GetPermissionName(permissionName), null, userId, value.Value)); _permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionName), GetPermissionName(permissionName), null, userId, value.Value));
} }
} }
return value;
} }
private async Task<Dictionary<string, string>> GetUsers(string filter) private async Task<Dictionary<string, string>> GetUsers(string filter)
@ -305,29 +311,20 @@
private void ValidatePermissions() private void ValidatePermissions()
{ {
// remove deny all users, unauthenticated, and registered users
var permissions = _permissions.Where(item => !item.IsAuthorized &&
(item.RoleName == RoleNames.Everyone || item.RoleName == RoleNames.Unauthenticated || item.RoleName == RoleNames.Registered)).ToList();
foreach (var permission in permissions)
{
_permissions.Remove(permission);
}
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{ {
// remove deny administrators and host users // remove host role permissions
permissions = _permissions.Where(item => !item.IsAuthorized && var permissions = _permissions.Where(item => item.RoleName == RoleNames.Host).ToList();
(item.RoleName == RoleNames.Admin || item.RoleName == RoleNames.Host)).ToList();
foreach (var permission in permissions) foreach (var permission in permissions)
{ {
_permissions.Remove(permission); _permissions.Remove(permission);
} }
// add host role permissions if administrator role is not assigned (to prevent lockout)
foreach (var permissionname in _permissionnames) 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.RoleName == RoleNames.Admin))
if (!_permissions.Any(item => item.EntityName == GetEntityName(permissionname) && item.PermissionName == GetPermissionName(permissionname) &&
(item.RoleName == RoleNames.Admin || item.RoleName == RoleNames.Host)))
{ {
_permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionname), GetPermissionName(permissionname), RoleNames.Admin, null, true)); _permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionname), GetPermissionName(permissionname), RoleNames.Host, null, true));
} }
} }
} }

View File

@ -16,7 +16,7 @@
public bool Disabled { get; set; } public bool Disabled { get; set; }
[Parameter] [Parameter]
public Action<bool?> OnChange { get; set; } public Func<bool?, bool?> OnChange { get; set; }
protected override void OnInitialized() protected override void OnInitialized()
{ {
@ -41,12 +41,14 @@
break; break;
} }
_value = OnChange(_value);
SetImage(); SetImage();
OnChange(_value);
} }
} }
private void SetImage() private void SetImage()
{
if (!Disabled)
{ {
switch (_value) switch (_value)
{ {
@ -63,6 +65,12 @@
_title = string.Empty; _title = string.Empty;
break; break;
} }
}
else
{
_src = "images/disabled.png";
_title = Localizer["PermissionDisabled"];
}
StateHasChanged(); StateHasChanged();
} }

View File

@ -123,4 +123,7 @@
<data name="PermissionDenied" xml:space="preserve"> <data name="PermissionDenied" xml:space="preserve">
<value>Permission Denied</value> <value>Permission Denied</value>
</data> </data>
<data name="PermissionDisabled" xml:space="preserve">
<value>Permission Disabled</value>
</data>
</root> </root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B