Added permissions to users controller and the client.

This commit is contained in:
Masu-Baumgartner
2024-10-07 16:37:18 +02:00
parent bb29177e41
commit 19afc5d055
11 changed files with 101 additions and 19 deletions

View File

@@ -27,7 +27,8 @@ public class DefaultSidebarItemProvider : ISidebarItemProvider
Group = "Admin",
Path = "/admin",
Priority = 0,
RequiresExactMatch = true
RequiresExactMatch = true,
Permission = "admin.overview"
},
new SidebarItem()
{
@@ -36,7 +37,8 @@ public class DefaultSidebarItemProvider : ISidebarItemProvider
Group = "Admin",
Path = "/admin/users",
Priority = 1,
RequiresExactMatch = false
RequiresExactMatch = false,
Permission = "admin.users.read"
},
new SidebarItem()
{
@@ -45,7 +47,8 @@ public class DefaultSidebarItemProvider : ISidebarItemProvider
Group = "Admin",
Path = "/admin/api",
Priority = 2,
RequiresExactMatch = false
RequiresExactMatch = false,
Permission = "admin.api.read"
},
new SidebarItem()
{
@@ -54,7 +57,8 @@ public class DefaultSidebarItemProvider : ISidebarItemProvider
Group = "Admin",
Path = "/admin/system",
Priority = 3,
RequiresExactMatch = false
RequiresExactMatch = false,
Permission = "admin.system.info"
},
];
}

View File

@@ -8,4 +8,5 @@ public class SidebarItem
public string Path { get; set; }
public int Priority { get; set; }
public bool RequiresExactMatch { get; set; } = false;
public string? Permission { get; set; }
}

View File

@@ -13,7 +13,6 @@
<PackageReference Include="MoonCore" Version="1.5.8" />
<PackageReference Include="MoonCore.Blazor" Version="1.2.1" />
<PackageReference Include="MoonCore.PluginFramework" Version="1.0.0" />
<PackageReference Include="MoonCore.Blazor.Tailwind" Version="1.0.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -25,6 +25,8 @@ public class IdentityService
ApiClient = apiClient;
}
#region Login / Logout
public async Task Check()
{
try
@@ -56,4 +58,42 @@ public class IdentityService
await CookieService.SetValue("token", "", 30);
await Check();
}
#endregion
public bool HasPermission(string requiredPermission)
{
// Check for wildcard permission
if (Permissions.Contains("*"))
return true;
var requiredSegments = requiredPermission.Split('.');
// Check if the user has the exact permission or a wildcard match
foreach (var permission in Permissions)
{
var permissionSegments = permission.Split('.');
// Iterate over the segments of the required permission
for (var i = 0; i < requiredSegments.Length; i++)
{
// If the current segment matches or is a wildcard, continue to the next segment
if (i < permissionSegments.Length && requiredSegments[i] == permissionSegments[i] ||
permissionSegments[i] == "*")
{
// If we've reached the end of the permissionSegments array, it means we've found a match
if (i == permissionSegments.Length - 1)
return true; // Found an exact match or a wildcard match
}
else
{
// If we reach here, it means the segments don't match and we break out of the loop
break;
}
}
}
// No matching permission found
return false;
}
}

View File

@@ -2,7 +2,9 @@
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
<CascadingValue Name="TargetPageType" Value="routeData.PageType">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
</CascadingValue>
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>

View File

@@ -1,11 +1,14 @@
@using MoonCore.Helpers
@using MoonCore.Exceptions
@using MoonCore.Helpers
@using MoonCore.PluginFramework.Services
@using Moonlight.Client.Interfaces
@using Moonlight.Client.Services
@using Moonlight.Client.UI.Partials
@inherits LayoutComponentBase
@inject ImplementationService ImplementationService
@inject IdentityService IdentityService
@inject IServiceProvider ServiceProvider
@inject ILogger<MainLayout> Logger
@@ -29,15 +32,21 @@ else
<div class="lg:pl-72">
<AppHeader Layout="this"/>
<ErrorHandler>
<main class="py-10">
<div class="px-4 sm:px-6 lg:px-8">
<CascadingValue Value="this" IsFixed="true">
@Body
</CascadingValue>
</div>
</main>
</ErrorHandler>
<main class="py-10">
<div class="px-4 sm:px-6 lg:px-8">
<ErrorHandler CustomHandler="HandleException">
<PermissionHandler CheckFunction="CheckPermission">
<CascadingValue Value="this" IsFixed="true">
@Body
</CascadingValue>
</PermissionHandler>
</ErrorHandler>
</div>
</main>
</div>
</div>
}
@@ -127,4 +136,17 @@ else
await InvokeAsync(StateHasChanged);
}
private bool CheckPermission(string permission) => IdentityService.HasPermission(permission);
private Task<bool> HandleException(Exception exception, ErrorHandler handler)
{
if (exception is HttpApiException httpApiException && httpApiException.Status == 401)
{
Task.Run(Load);
return Task.FromResult(true);
}
return Task.FromResult(false);
}
}

View File

@@ -1,9 +1,11 @@
@using MoonCore.PluginFramework.Services
@using Moonlight.Client.Interfaces
@using Moonlight.Client.Models
@using Moonlight.Client.Services
@using Moonlight.Client.UI.Layouts
@inject NavigationManager Navigation
@inject IdentityService IdentityService
@inject ImplementationService ImplementationService
@{
@@ -111,7 +113,7 @@
<li>
@if (!string.IsNullOrEmpty(group.Key))
{
<div class="text-xs font-semibold leading-6 text-gray-400">
<div class="text-xs font-semibold leading-6 text-gray-400 my-2">
@group.Key
</div>
}
@@ -168,7 +170,7 @@
{
Items = ImplementationService.Get<ISidebarItemProvider>()
.SelectMany(x => x.Get())
//.Where(x => x.Permission == null || (x.Permission != null && IdentityService.HasPermission(x.Permission)))
.Where(x => x.Permission == null || (x.Permission != null && IdentityService.HasPermission(x.Permission)))
.GroupBy(x => x.Group ?? "")
.OrderByDescending(x => string.IsNullOrEmpty(x.Key))
.ToDictionary(x => x.Key, x => x.OrderBy(y => y.Priority).ToArray());

View File

@@ -1,11 +1,14 @@
@page "/admin/users"
@using MoonCore.Blazor.Tailwind.Attributes
@using MoonCore.Blazor.Tailwind.Forms.Components
@using MoonCore.Helpers
@using MoonCore.Models
@using Moonlight.Shared.Http.Requests.Admin.Users
@using Moonlight.Shared.Http.Responses.Admin.Users
@attribute [RequirePermission("admin.users.read")]
@inject HttpApiClient HttpApiClient
<Crud TItem="UserDetailResponse"