1
0
mirror of https://github.com/chylex/Minecraft-Phantom-Panel.git synced 2025-04-28 19:15:45 +02:00
Minecraft-Phantom-Panel/Controller/Phantom.Controller.Services/Users/Permissions/PermissionManager.cs

69 lines
2.9 KiB
C#

using System.Collections.Immutable;
using System.Security.Claims;
using Microsoft.EntityFrameworkCore;
using Phantom.Common.Logging;
using Phantom.Controller.Database;
using Phantom.Controller.Database.Entities;
using Phantom.Utils.Collections;
using ILogger = Serilog.ILogger;
namespace Phantom.Controller.Services.Users.Permissions;
public sealed class PermissionManager {
private static readonly ILogger Logger = PhantomLogger.Create<PermissionManager>();
private readonly IDatabaseProvider databaseProvider;
private readonly Dictionary<Guid, IdentityPermissions> userIdsToPermissionIds = new ();
public PermissionManager(IDatabaseProvider databaseProvider) {
this.databaseProvider = databaseProvider;
}
internal async Task Initialize() {
Logger.Information("Adding default permissions to database.");
await using var ctx = databaseProvider.Provide();
var existingPermissionIds = await ctx.Permissions.Select(static p => p.Id).AsAsyncEnumerable().ToImmutableSetAsync();
var missingPermissionIds = GetMissingPermissionsOrdered(Permission.All, existingPermissionIds);
if (!missingPermissionIds.IsEmpty) {
Logger.Information("Adding default permissions: {Permissions}", string.Join(", ", missingPermissionIds));
foreach (var permissionId in missingPermissionIds) {
ctx.Permissions.Add(new PermissionEntity(permissionId));
}
await ctx.SaveChangesAsync();
}
}
internal static ImmutableArray<string> GetMissingPermissionsOrdered(IEnumerable<Permission> allPermissions, ImmutableHashSet<string> existingPermissionIds) {
return allPermissions.Select(static permission => permission.Id).Except(existingPermissionIds).Order().ToImmutableArray();
}
private IdentityPermissions FetchPermissionsForUserId(Guid userId) {
using var ctx = databaseProvider.Provide();
var userPermissions = ctx.UserPermissions.Where(up => up.UserGuid == userId).Select(static up => up.PermissionId);
var rolePermissions = ctx.UserRoles.Where(ur => ur.UserGuid == userId).Join(ctx.RolePermissions, static ur => ur.RoleGuid, static rp => rp.RoleGuid, static (ur, rp) => rp.PermissionId);
return new IdentityPermissions(userPermissions.Union(rolePermissions));
}
private IdentityPermissions GetPermissionsForUserId(Guid userId, bool refreshCache) {
if (!refreshCache && userIdsToPermissionIds.TryGetValue(userId, out var userPermissions)) {
return userPermissions;
}
else {
return userIdsToPermissionIds[userId] = FetchPermissionsForUserId(userId);
}
}
public IdentityPermissions GetPermissions(ClaimsPrincipal user, bool refreshCache = false) {
Guid? userId = UserManager.GetAuthenticatedUserId(user);
return userId == null ? IdentityPermissions.None : GetPermissionsForUserId(userId.Value, refreshCache);
}
public bool CheckPermission(ClaimsPrincipal user, Permission permission, bool refreshCache = false) {
return GetPermissions(user, refreshCache).Check(permission);
}
}