From 094acf925bcd535fb215f02302514e8b311724b2 Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Sun, 9 Jun 2024 00:02:10 +0200 Subject: [PATCH] (refactor): implement agent authorization filter --- .../ApiKeyAuthorizationFilter.cs | 28 +++++++++++++++++++ src/Agent/Controllers/CertsController.cs | 17 ++--------- src/Agent/Controllers/HelloWorldController.cs | 3 ++ src/Agent/Controllers/ServiceController.cs | 14 ++++------ src/Agent/Program.cs | 3 ++ .../BackgroundServices/AutoRenewal.cs | 10 +++++-- 6 files changed, 50 insertions(+), 25 deletions(-) create mode 100644 src/Agent/AuthorizationFilters/ApiKeyAuthorizationFilter.cs diff --git a/src/Agent/AuthorizationFilters/ApiKeyAuthorizationFilter.cs b/src/Agent/AuthorizationFilters/ApiKeyAuthorizationFilter.cs new file mode 100644 index 0000000..e934df1 --- /dev/null +++ b/src/Agent/AuthorizationFilters/ApiKeyAuthorizationFilter.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; + +namespace MaksIT.Agent.AuthorizationFilters; + +public class ApiKeyAuthorizationFilter : IAuthorizationFilter { + + private readonly Configuration _appSettings; + + public ApiKeyAuthorizationFilter( + IOptions appSettings + ) { + _appSettings = appSettings.Value; + } + + public void OnAuthorization(AuthorizationFilterContext context) { + if (!context.HttpContext.Request.Headers.TryGetValue("X-API-KEY", out var extractedApiKey)) { + context.Result = new UnauthorizedResult(); + return; + } + + if (!_appSettings.ApiKey.Equals(extractedApiKey)) { + context.Result = new UnauthorizedResult(); + return; + } + } +} \ No newline at end of file diff --git a/src/Agent/Controllers/CertsController.cs b/src/Agent/Controllers/CertsController.cs index 5578991..2d07061 100644 --- a/src/Agent/Controllers/CertsController.cs +++ b/src/Agent/Controllers/CertsController.cs @@ -1,15 +1,14 @@ - -using System.Diagnostics; - -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using MaksIT.Models.Agent.Requests; +using MaksIT.Agent.AuthorizationFilters; namespace MaksIT.Agent.Controllers; [ApiController] [Route("[controller]")] +[ServiceFilter(typeof(ApiKeyAuthorizationFilter))] public class CertsController : ControllerBase { private readonly Configuration _appSettings; @@ -22,20 +21,10 @@ public class CertsController : ControllerBase { [HttpPost("[action]")] public IActionResult Upload([FromBody] CertsUploadRequest requestData) { - if (!Request.Headers.TryGetValue("X-API-KEY", out var extractedApiKey)) { - return Unauthorized("API Key is missing"); - } - - if (!_appSettings.ApiKey.Equals(extractedApiKey)) { - return Unauthorized("Unauthorized client"); - } - foreach (var (fileName, fileContent) in requestData.Certs) { System.IO.File.WriteAllText(Path.Combine(_appSettings.CertsPath, fileName), fileContent); } return Ok("Certificates uploaded successfully"); } - } - diff --git a/src/Agent/Controllers/HelloWorldController.cs b/src/Agent/Controllers/HelloWorldController.cs index d3d3dc0..e3611e2 100644 --- a/src/Agent/Controllers/HelloWorldController.cs +++ b/src/Agent/Controllers/HelloWorldController.cs @@ -1,9 +1,12 @@ using Microsoft.AspNetCore.Mvc; +using MaksIT.Agent.AuthorizationFilters; + namespace Agent.Controllers { [ApiController] [Route("[controller]")] + [ServiceFilter(typeof(ApiKeyAuthorizationFilter))] public class HelloWorldController : ControllerBase { [HttpGet] diff --git a/src/Agent/Controllers/ServiceController.cs b/src/Agent/Controllers/ServiceController.cs index d849b6a..0abdd96 100644 --- a/src/Agent/Controllers/ServiceController.cs +++ b/src/Agent/Controllers/ServiceController.cs @@ -1,12 +1,16 @@ using System.Diagnostics; -using MaksIT.Models.Agent.Requests; + using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; +using MaksIT.Agent.AuthorizationFilters; +using MaksIT.Models.Agent.Requests; + namespace MaksIT.Agent.Controllers; [ApiController] [Route("[controller]")] +[ServiceFilter(typeof(ApiKeyAuthorizationFilter))] public class ServiceController : ControllerBase { private readonly Configuration _appSettings; @@ -21,14 +25,6 @@ public class ServiceController : ControllerBase { public IActionResult Reload([FromBody] ServiceReloadRequest requestData) { var serviceName = requestData.ServiceName; - if (!Request.Headers.TryGetValue("X-API-KEY", out var extractedApiKey)) { - return Unauthorized("API Key is missing"); - } - - if (!_appSettings.ApiKey.Equals(extractedApiKey)) { - return Unauthorized("Unauthorized client"); - } - try { var processStartInfo = new ProcessStartInfo { FileName = "/bin/systemctl", diff --git a/src/Agent/Program.cs b/src/Agent/Program.cs index af450c9..a1f3cd5 100644 --- a/src/Agent/Program.cs +++ b/src/Agent/Program.cs @@ -1,4 +1,5 @@ using MaksIT.Agent; +using MaksIT.Agent.AuthorizationFilters; var builder = WebApplication.CreateBuilder(args); @@ -19,6 +20,8 @@ builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.AddScoped(); + var app = builder.Build(); // Configure the HTTP request pipeline. diff --git a/src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs b/src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs index 3035f81..5e7532d 100644 --- a/src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs +++ b/src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs @@ -52,8 +52,14 @@ namespace MaksIT.LetsEncryptServer.BackgroundServices { } var hostnames = cache.GetHostsWithUpcomingSslExpiry(); - if (hostnames == null || !hostnames.Any()) { - _logger.LogError("No hosts found with upcoming SSL expiry"); + if (hostnames == null) { + _logger.LogError("Unexpected hostnames null"); + return IDomainResult.Success(); + } + + + if (!hostnames.Any()) { + _logger.LogInformation("No hosts found with upcoming SSL expiry"); return IDomainResult.Success(); }