Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
Leigh Pointer
2025-07-23 14:50:24 +02:00
7 changed files with 271 additions and 261 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>

View File

@@ -433,6 +433,8 @@
private List<Permission> GenerateDefaultPermissions(int siteId, string moduleDefinitionName) private List<Permission> GenerateDefaultPermissions(int siteId, string moduleDefinitionName)
{ {
var permissions = new List<Permission>(); var permissions = new List<Permission>();
// set module view permissions
if (_visibility == "view") if (_visibility == "view")
{ {
// set module view permissions to page view permissions // set module view permissions to page view permissions
@@ -444,18 +446,18 @@
permissions = SetPermissions(permissions, siteId, PermissionNames.View, PermissionNames.Edit); permissions = SetPermissions(permissions, siteId, PermissionNames.View, PermissionNames.Edit);
} }
// get module permissions // set remaining module permissions
var permissionNames = $"{PermissionNames.View},{PermissionNames.Edit}"; var permissionNames = PermissionNames.Edit;
var moduleDefinition = _allModuleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == moduleDefinitionName); var moduleDefinition = _allModuleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == moduleDefinitionName);
if (moduleDefinition != null && !string.IsNullOrEmpty(moduleDefinition.PermissionNames)) if (moduleDefinition != null && !string.IsNullOrEmpty(moduleDefinition.PermissionNames))
{ {
permissionNames = moduleDefinition.PermissionNames; permissionNames = moduleDefinition.PermissionNames; // custom module permissions
} }
foreach (var permission in permissionNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) foreach (var permission in permissionNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{ {
if (permission != PermissionNames.View) if (permission != PermissionNames.View)
{ {
// set remaining module permissions to page edit permissions // set module permissions to page edit permissions
permissions = SetPermissions(permissions, siteId, permission, PermissionNames.Edit); permissions = SetPermissions(permissions, siteId, permission, PermissionNames.Edit);
} }
} }

View File

@@ -33,7 +33,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MySql.Data" Version="9.3.0" /> <PackageReference Include="MySql.Data" Version="9.4.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.3.efcore.9.0.0" /> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.3.efcore.9.0.0" />
</ItemGroup> </ItemGroup>

View File

@@ -47,7 +47,7 @@
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="9.0.7" /> <PackageReference Include="Microsoft.Data.Sqlite.Core" Version="9.0.7" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.11" /> <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.11" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.1" /> <PackageReference Include="HtmlAgilityPack" Version="1.12.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" />
<PackageReference Include="MailKit" Version="4.13.0" /> <PackageReference Include="MailKit" Version="4.13.0" />
</ItemGroup> </ItemGroup>

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B