Implemented api permission system (backend)
This commit is contained in:
@@ -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;
|
||||
|
||||
// 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 (string.IsNullOrEmpty(apiKey))
|
||||
return false;
|
||||
|
||||
using var scope = Provider.CreateScope();
|
||||
var apiKeyRepo = scope.ServiceProvider.GetRequiredService<Repository<ApiKey>>();
|
||||
|
||||
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<string[]>(apiKeyModel.PermissionJson) ?? Array.Empty<string>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (permissionAttr == null)
|
||||
return true;
|
||||
|
||||
if(metadata.)
|
||||
}
|
||||
}
|
||||
@@ -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; } = "[]";
|
||||
}
|
||||
@@ -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; } = "[]";
|
||||
}
|
||||
Reference in New Issue
Block a user