Files
Swarm/DysonNetwork.Sphere/Permission/PermissionMiddleware.cs

60 lines
1.9 KiB
C#

namespace DysonNetwork.Sphere.Permission;
using System;
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class RequiredPermissionAttribute(string area, string key) : Attribute
{
public string Area { get; set; } = area;
public string Key { get; } = key;
}
public class PermissionMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(HttpContext httpContext, PermissionService pm)
{
var endpoint = httpContext.GetEndpoint();
var attr = endpoint?.Metadata
.OfType<RequiredPermissionAttribute>()
.FirstOrDefault();
if (attr != null)
{
if (httpContext.User.Identity?.IsAuthenticated != true)
{
httpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
await httpContext.Response.WriteAsync("Unauthorized");
return;
}
var currentUserId = httpContext.User.GetUserId();
if (currentUserId == Guid.Empty)
{
httpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
await httpContext.Response.WriteAsync("Unauthorized");
return;
}
// TODO: Check for superuser from PassClient
// if (currentUser.IsSuperuser)
// {
// // Bypass the permission check for performance
// await next(httpContext);
// return;
// }
var actor = $"user:{currentUserId}";
var permNode = await pm.GetPermissionAsync<bool>(actor, attr.Area, attr.Key);
if (!permNode)
{
httpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
await httpContext.Response.WriteAsync($"Permission {attr.Area}/{attr.Key} = {true} was required.");
return;
}
}
await next(httpContext);
}
}