Implemented api permission system (backend)
This commit is contained in:
@@ -1,17 +1,20 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
using MoonCore.Abstractions;
|
||||||
using MoonCore.Helpers;
|
|
||||||
using Moonlight.Core.Attributes;
|
using Moonlight.Core.Attributes;
|
||||||
|
using Moonlight.Core.Database.Entities;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Moonlight.Core.Http.Middleware;
|
namespace Moonlight.Core.Http.Middleware;
|
||||||
|
|
||||||
public class ApiPermissionMiddleware
|
public class ApiPermissionMiddleware
|
||||||
{
|
{
|
||||||
private RequestDelegate Next;
|
private RequestDelegate Next;
|
||||||
|
private readonly IServiceProvider Provider;
|
||||||
|
|
||||||
public ApiPermissionMiddleware(RequestDelegate next)
|
public ApiPermissionMiddleware(RequestDelegate next, IServiceProvider provider)
|
||||||
{
|
{
|
||||||
Next = next;
|
Next = next;
|
||||||
|
Provider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Invoke(HttpContext context)
|
public async Task Invoke(HttpContext context)
|
||||||
@@ -39,17 +42,56 @@ public class ApiPermissionMiddleware
|
|||||||
if (metadata == null)
|
if (metadata == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (metadata.ControllerTypeInfo.CustomAttributes
|
var controllerAttrInfo = metadata.ControllerTypeInfo.CustomAttributes
|
||||||
.All(x => x.AttributeType != typeof(ApiControllerAttribute)))
|
.FirstOrDefault(x => x.AttributeType == typeof(ApiPermissionAttribute));
|
||||||
|
|
||||||
|
var methodAttrInfo = metadata.MethodInfo.CustomAttributes
|
||||||
|
.FirstOrDefault(x => x.AttributeType == typeof(ApiPermissionAttribute));
|
||||||
|
|
||||||
|
if (methodAttrInfo == null && controllerAttrInfo == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var permissionAttr =
|
if (!context.Request.Headers.TryGetValue("Authorization", out var apiKeySv))
|
||||||
metadata.ControllerTypeInfo.CustomAttributes.FirstOrDefault(x =>
|
return false;
|
||||||
x.AttributeType == typeof(ApiPermissionAttribute));
|
|
||||||
|
|
||||||
if (permissionAttr == null)
|
// Entity framework won't work with the StringValues type returned by the Headers.TryGetValue method
|
||||||
return true;
|
// 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<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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,5 +14,6 @@ public class CreateApiKeyForm
|
|||||||
public DateTime ExpiresAt { get; set; } = DateTime.UtcNow;
|
public DateTime ExpiresAt { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
[Required(ErrorMessage = "You need to specify what permissions the api key should have")]
|
[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; }
|
public DateTime ExpiresAt { get; set; }
|
||||||
|
|
||||||
[Required(ErrorMessage = "You need to specify what permissions the api key should have")]
|
[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