using Microsoft.AspNetCore.Authorization; using Raven.Client.Documents; using Raven.Client.Documents.Session; namespace The_Metaverse_Engine.Handlers; public class ApiKeyRequirement : IAuthorizationRequirement { } public class ApiKeyHandler : AuthorizationHandler { private readonly IHttpContextAccessor _httpContextAccessor; private readonly ILogger _logger; private readonly IAsyncDocumentSession _session; public ApiKeyHandler(ILogger logger, IHttpContextAccessor httpContextAccessor, IAsyncDocumentSession session) { _logger = logger; _httpContextAccessor = httpContextAccessor; _session = session; } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext ctx, ApiKeyRequirement req) { // string apiKey = _httpContextAccessor?.HttpContext?.Request.Headers[Constants.ApiKeyHeaderName].ToString(); var apiKey = _httpContextAccessor?.HttpContext?.Request.Query["apikey"].ToString(); if (string.IsNullOrWhiteSpace(apiKey)) { ctx.Fail(); return; } try { var res = await _session.Query().Where(k => k.Key == apiKey).SingleOrDefaultAsync(); if (res != null) { ctx.Succeed(req); // Only update every 1 minute to reduce DB load if (res.LastUse + TimeSpan.FromMinutes(1) < DateTime.Now) { res.LastUse = DateTime.Now; await _session.SaveChangesAsync(); } return; } _logger.LogWarning($"Invalid API key: {apiKey}"); } catch (Exception e) { _logger.LogError(e.Message); } ctx.Fail(); } }