diff --git a/Moonlight/Core/Http/Middleware/ApiPermissionMiddleware.cs b/Moonlight/Core/Http/Middleware/ApiPermissionMiddleware.cs index 176586a1..2a43d52d 100644 --- a/Moonlight/Core/Http/Middleware/ApiPermissionMiddleware.cs +++ b/Moonlight/Core/Http/Middleware/ApiPermissionMiddleware.cs @@ -1,17 +1,20 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Controllers; -using MoonCore.Helpers; +using Microsoft.AspNetCore.Mvc.Controllers; +using MoonCore.Abstractions; using Moonlight.Core.Attributes; +using Moonlight.Core.Database.Entities; +using Newtonsoft.Json; namespace Moonlight.Core.Http.Middleware; public class ApiPermissionMiddleware { private RequestDelegate Next; + private readonly IServiceProvider Provider; - public ApiPermissionMiddleware(RequestDelegate next) + public ApiPermissionMiddleware(RequestDelegate next, IServiceProvider provider) { Next = next; + Provider = provider; } public async Task Invoke(HttpContext context) @@ -39,17 +42,56 @@ public class ApiPermissionMiddleware if (metadata == null) return true; - if (metadata.ControllerTypeInfo.CustomAttributes - .All(x => x.AttributeType != typeof(ApiControllerAttribute))) + var controllerAttrInfo = metadata.ControllerTypeInfo.CustomAttributes + .FirstOrDefault(x => x.AttributeType == typeof(ApiPermissionAttribute)); + + var methodAttrInfo = metadata.MethodInfo.CustomAttributes + .FirstOrDefault(x => x.AttributeType == typeof(ApiPermissionAttribute)); + + if (methodAttrInfo == null && controllerAttrInfo == null) return true; - var permissionAttr = - metadata.ControllerTypeInfo.CustomAttributes.FirstOrDefault(x => - x.AttributeType == typeof(ApiPermissionAttribute)); + if (!context.Request.Headers.TryGetValue("Authorization", out var apiKeySv)) + return false; - if (permissionAttr == null) - return true; + // Entity framework won't work with the StringValues type returned by the Headers.TryGetValue method + // that's why we convert that to a regular string here + var apiKey = apiKeySv.ToString(); - if(metadata.) + if (string.IsNullOrEmpty(apiKey)) + return false; + + using var scope = Provider.CreateScope(); + var apiKeyRepo = scope.ServiceProvider.GetRequiredService>(); + + var apiKeyModel = apiKeyRepo + .Get() + .FirstOrDefault(x => x.Key == apiKey); + + if (apiKeyModel == null) + return false; + + if (apiKeyModel.ExpiresAt < DateTime.UtcNow) + return false; + + var permissions = JsonConvert.DeserializeObject(apiKeyModel.PermissionJson) ?? Array.Empty(); + + if (controllerAttrInfo != null) + { + var permissionToLookFor = controllerAttrInfo.ConstructorArguments.First().Value as string; + + if (permissionToLookFor != null && !permissions.Contains(permissionToLookFor)) + return false; + } + + if (methodAttrInfo != null) + { + var permissionToLookFor = methodAttrInfo.ConstructorArguments.First().Value as string; + + if (permissionToLookFor != null && !permissions.Contains(permissionToLookFor)) + return false; + } + + return true; } } \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/ApiKeys/CreateApiKeyForm.cs b/Moonlight/Core/Models/Forms/ApiKeys/CreateApiKeyForm.cs index 1ba1a765..9ed8f6eb 100644 --- a/Moonlight/Core/Models/Forms/ApiKeys/CreateApiKeyForm.cs +++ b/Moonlight/Core/Models/Forms/ApiKeys/CreateApiKeyForm.cs @@ -14,5 +14,6 @@ public class CreateApiKeyForm public DateTime ExpiresAt { get; set; } = DateTime.UtcNow; [Required(ErrorMessage = "You need to specify what permissions the api key should have")] - public string Permissions { get; set; } = "[]"; + [DisplayName("Permissions")] + public string PermissionJson { get; set; } = "[]"; } \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/ApiKeys/UpdateApiKeyForm.cs b/Moonlight/Core/Models/Forms/ApiKeys/UpdateApiKeyForm.cs index 1ce3d059..912494f2 100644 --- a/Moonlight/Core/Models/Forms/ApiKeys/UpdateApiKeyForm.cs +++ b/Moonlight/Core/Models/Forms/ApiKeys/UpdateApiKeyForm.cs @@ -14,5 +14,6 @@ public class UpdateApiKeyForm public DateTime ExpiresAt { get; set; } [Required(ErrorMessage = "You need to specify what permissions the api key should have")] - public string Permissions { get; set; } = "[]"; + [DisplayName("Permissions")] + public string PermissionJson { get; set; } = "[]"; } \ No newline at end of file