Refactored project to module structure

This commit is contained in:
2026-03-12 22:50:15 +01:00
parent 93de9c5d00
commit 1257e8b950
219 changed files with 1231 additions and 1259 deletions

View File

@@ -0,0 +1,29 @@
using Microsoft.AspNetCore.Authorization;
using Moonlight.Shared;
namespace Moonlight.Frontend.Infrastructure.Implementations;
public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
PermissionRequirement requirement)
{
var permissionClaim = context.User.FindFirst(x =>
x.Type.Equals(Permissions.ClaimType, StringComparison.OrdinalIgnoreCase) &&
x.Value.Equals(requirement.Identifier, StringComparison.OrdinalIgnoreCase)
);
if (permissionClaim == null)
{
context.Fail(new AuthorizationFailureReason(
this,
$"User does not have the requested permission '{requirement.Identifier}'"
));
return Task.CompletedTask;
}
context.Succeed(requirement);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,46 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Moonlight.Shared;
namespace Moonlight.Frontend.Infrastructure.Implementations;
public class PermissionPolicyProvider : IAuthorizationPolicyProvider
{
private readonly DefaultAuthorizationPolicyProvider FallbackProvider;
public PermissionPolicyProvider(IOptions<AuthorizationOptions> options)
{
FallbackProvider = new DefaultAuthorizationPolicyProvider(options);
}
public async Task<AuthorizationPolicy?> GetPolicyAsync(string policyName)
{
if (!policyName.StartsWith(Permissions.Prefix, StringComparison.OrdinalIgnoreCase))
return await FallbackProvider.GetPolicyAsync(policyName);
var policy = new AuthorizationPolicyBuilder();
policy.AddRequirements(new PermissionRequirement(policyName));
return policy.Build();
}
public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
return FallbackProvider.GetDefaultPolicyAsync();
}
public Task<AuthorizationPolicy?> GetFallbackPolicyAsync()
{
return FallbackProvider.GetFallbackPolicyAsync();
}
}
public class PermissionRequirement : IAuthorizationRequirement
{
public PermissionRequirement(string identifier)
{
Identifier = identifier;
}
public string Identifier { get; }
}

View File

@@ -0,0 +1,49 @@
using LucideBlazor;
using Moonlight.Frontend.Admin.Users.Shared;
using Moonlight.Frontend.Infrastructure.Hooks;
using Moonlight.Shared;
namespace Moonlight.Frontend.Infrastructure.Implementations;
public sealed class PermissionProvider : IPermissionProvider
{
public Task<PermissionCategory[]> GetPermissionsAsync()
{
return Task.FromResult<PermissionCategory[]>([
new PermissionCategory("Users", typeof(UserRoundIcon), [
new Permission(Permissions.Users.Create, "Create", "Create new users"),
new Permission(Permissions.Users.View, "View", "View all users"),
new Permission(Permissions.Users.Edit, "Edit", "Edit user details"),
new Permission(Permissions.Users.Delete, "Delete", "Delete user accounts"),
new Permission(Permissions.Users.Logout, "Logout", "Logout user accounts")
]),
new PermissionCategory("Roles", typeof(UsersRoundIcon), [
new Permission(Permissions.Roles.Create, "Create", "Create new roles"),
new Permission(Permissions.Roles.View, "View", "View all roles"),
new Permission(Permissions.Roles.Edit, "Edit", "Edit role details"),
new Permission(Permissions.Roles.Delete, "Delete", "Delete role accounts"),
new Permission(Permissions.Roles.Members, "Members", "Manage role members")
]),
new PermissionCategory("System", typeof(CogIcon), [
new Permission(Permissions.System.Info, "Info", "View system info"),
new Permission(Permissions.System.Diagnose, "Diagnose", "Run diagnostics"),
new Permission(Permissions.System.Versions, "Versions", "Look at the available versions"),
new Permission(Permissions.System.Instance, "Instance",
"Update the moonlight instance and add plugins"),
new Permission(Permissions.System.Settings, "Settings", "Change settings of the instance")
]),
new PermissionCategory("API Keys", typeof(KeyIcon), [
new Permission(Permissions.ApiKeys.Create, "Create", "Create new API keys"),
new Permission(Permissions.ApiKeys.View, "View", "View all API keys"),
new Permission(Permissions.ApiKeys.Edit, "Edit", "Edit API key details"),
new Permission(Permissions.ApiKeys.Delete, "Delete", "Delete API keys")
]),
new PermissionCategory("Themes", typeof(PaintRollerIcon), [
new Permission(Permissions.Themes.Create, "Create", "Create new theme"),
new Permission(Permissions.Themes.View, "View", "View all themes"),
new Permission(Permissions.Themes.Edit, "Edit", "Edit themes"),
new Permission(Permissions.Themes.Delete, "Delete", "Delete themes")
])
]);
}
}

View File

@@ -0,0 +1,53 @@
using LucideBlazor;
using Moonlight.Frontend.Infrastructure.Hooks;
using Moonlight.Frontend.Infrastructure.Models;
using Moonlight.Shared;
namespace Moonlight.Frontend.Infrastructure.Implementations;
public sealed class SidebarProvider : ISidebarProvider
{
public Task<SidebarItem[]> GetItemsAsync()
{
return Task.FromResult<SidebarItem[]>([
new SidebarItem
{
Name = "Overview",
IconType = typeof(LayoutDashboardIcon),
Path = "/",
IsExactPath = true,
Order = 0
},
new SidebarItem
{
Name = "Overview",
IconType = typeof(LayoutDashboardIcon),
Path = "/admin",
IsExactPath = true,
Group = "Admin",
Order = 0,
Policy = Permissions.System.Info
},
new SidebarItem
{
Name = "Users",
IconType = typeof(UsersRoundIcon),
Path = "/admin/users",
IsExactPath = false,
Group = "Admin",
Order = 10,
Policy = Permissions.Users.View
},
new SidebarItem
{
Name = "System",
IconType = typeof(SettingsIcon),
Path = "/admin/system",
IsExactPath = false,
Group = "Admin",
Order = 20,
Policy = Permissions.System.Info
}
]);
}
}