using Foxchat.Core; using Foxchat.Identity.Database; using NodaTime; namespace Foxchat.Identity.Middleware; public class AuthorizationMiddleware( IdentityContext db, IClock clock ) : IMiddleware { public async Task InvokeAsync(HttpContext ctx, RequestDelegate next) { var endpoint = ctx.GetEndpoint(); var attribute = endpoint?.Metadata.GetMetadata(); if (attribute == null) { await next(ctx); return; } var token = ctx.GetToken(); if (token == null || token.Expires > clock.GetCurrentInstant()) throw new ApiError.Unauthorized("This endpoint requires an authenticated user."); if (attribute.Scopes.Length > 0 && attribute.Scopes.Except(token.Scopes).Any()) throw new ApiError.Forbidden("This endpoint requires ungranted scopes.", attribute.Scopes.Except(token.Scopes)); await next(ctx); } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class AuthorizeAttribute(params string[] scopes) : Attribute { public readonly string[] Scopes = scopes; }