Move APIKeys to file and allow read vs read/write
This commit is contained in:
@@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace TodoApi.Helpers;
|
||||
|
||||
public class ApiKeyAttribute : ActionFilterAttribute
|
||||
public class ApiKeyCanReadAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
@@ -14,7 +14,7 @@ public class ApiKeyAttribute : ActionFilterAttribute
|
||||
var apiKey = context.HttpContext.Request.Headers["X-API-KEY"];
|
||||
|
||||
// Validate the API key using the IApiKeyValidator service
|
||||
if (string.IsNullOrEmpty(apiKey) || !apiKeyValidator.Validate(apiKey))
|
||||
if (string.IsNullOrEmpty(apiKey) || !apiKeyValidator.CanRead(apiKey))
|
||||
{
|
||||
// If the API key is invalid, set the response status code to 401 Unauthorized
|
||||
context.Result = new UnauthorizedResult();
|
||||
27
Helpers/ApiKeyCanWriteAttribute.cs
Normal file
27
Helpers/ApiKeyCanWriteAttribute.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace TodoApi.Helpers;
|
||||
|
||||
public class ApiKeyCanWriteAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
// Get the required service to validate the API key
|
||||
var apiKeyValidator = context.HttpContext.RequestServices.GetRequiredService<IApiKeyValidator>();
|
||||
|
||||
// Get the API key from the X-API-KEY header
|
||||
var apiKey = context.HttpContext.Request.Headers["X-API-KEY"];
|
||||
|
||||
// Validate the API key using the IApiKeyValidator service
|
||||
if (string.IsNullOrEmpty(apiKey) || !apiKeyValidator.CanWrite(apiKey))
|
||||
{
|
||||
// If the API key is invalid, set the response status code to 401 Unauthorized
|
||||
context.Result = new UnauthorizedResult();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the API key is valid, continue with the action execution
|
||||
base.OnActionExecuting(context);
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,29 @@ namespace TodoApi.Helpers
|
||||
{
|
||||
public interface IApiKeyValidator
|
||||
{
|
||||
bool Validate(string? apiKey);
|
||||
bool CanRead(string? apiKey);
|
||||
bool CanWrite(string? apiKey);
|
||||
}
|
||||
|
||||
public class ApiKeyValidator(List<string>? apiKeys) : IApiKeyValidator
|
||||
public class ApiKeyValidator(ApiKeys? apiKeys) : IApiKeyValidator
|
||||
{
|
||||
private readonly List<string>? _apiKeys = apiKeys;
|
||||
private readonly ApiKeys _apiKeys = apiKeys ?? new ApiKeys();
|
||||
|
||||
public bool Validate(string? apiKey)
|
||||
public bool CanRead(string? apiKey)
|
||||
{
|
||||
if (_apiKeys == null) return false;
|
||||
if (apiKey == null) return false;
|
||||
|
||||
// Verify the provided apiKey is in our configuration
|
||||
return _apiKeys.Contains(apiKey!.ToLower());
|
||||
return _apiKeys.ReadOnly.Contains(apiKey, StringComparison.OrdinalIgnoreCase) ||
|
||||
_apiKeys.ReadWrite.Contains(apiKey, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public bool CanWrite(string? apiKey)
|
||||
{
|
||||
if (apiKey == null) return false;
|
||||
|
||||
// Verify the provided apiKey is in our configuration
|
||||
return _apiKeys.ReadWrite.Contains(apiKey, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
Helpers/ApiKeys.cs
Normal file
12
Helpers/ApiKeys.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace TodoApi.Helpers;
|
||||
|
||||
public class ApiKeys
|
||||
{
|
||||
[JsonProperty("read_only")]
|
||||
public List<string> ReadOnly { get; set; } = [];
|
||||
|
||||
[JsonProperty("read_write")]
|
||||
public List<string> ReadWrite { get; set; } = [];
|
||||
}
|
||||
12
Helpers/ExtensionMethods.cs
Normal file
12
Helpers/ExtensionMethods.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace TodoApi;
|
||||
|
||||
public static class ExtensionMethods
|
||||
{
|
||||
public static bool Contains(this IEnumerable<string> source, string toCheck, StringComparison comp)
|
||||
{
|
||||
return
|
||||
source != null &&
|
||||
!string.IsNullOrEmpty(toCheck) &&
|
||||
source.Any(x => string.Compare(x, toCheck, comp) == 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user