(refactor): implement agent authorization filter

This commit is contained in:
Maksym Sadovnychyy 2024-06-09 00:02:10 +02:00
parent 9a11bbca10
commit 094acf925b
6 changed files with 50 additions and 25 deletions

View File

@ -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<Configuration> 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;
}
}
}

View File

@ -1,15 +1,14 @@
 using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using MaksIT.Models.Agent.Requests; using MaksIT.Models.Agent.Requests;
using MaksIT.Agent.AuthorizationFilters;
namespace MaksIT.Agent.Controllers; namespace MaksIT.Agent.Controllers;
[ApiController] [ApiController]
[Route("[controller]")] [Route("[controller]")]
[ServiceFilter(typeof(ApiKeyAuthorizationFilter))]
public class CertsController : ControllerBase { public class CertsController : ControllerBase {
private readonly Configuration _appSettings; private readonly Configuration _appSettings;
@ -22,20 +21,10 @@ public class CertsController : ControllerBase {
[HttpPost("[action]")] [HttpPost("[action]")]
public IActionResult Upload([FromBody] CertsUploadRequest requestData) { 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) { foreach (var (fileName, fileContent) in requestData.Certs) {
System.IO.File.WriteAllText(Path.Combine(_appSettings.CertsPath, fileName), fileContent); System.IO.File.WriteAllText(Path.Combine(_appSettings.CertsPath, fileName), fileContent);
} }
return Ok("Certificates uploaded successfully"); return Ok("Certificates uploaded successfully");
} }
} }

View File

@ -1,9 +1,12 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MaksIT.Agent.AuthorizationFilters;
namespace Agent.Controllers { namespace Agent.Controllers {
[ApiController] [ApiController]
[Route("[controller]")] [Route("[controller]")]
[ServiceFilter(typeof(ApiKeyAuthorizationFilter))]
public class HelloWorldController : ControllerBase { public class HelloWorldController : ControllerBase {
[HttpGet] [HttpGet]

View File

@ -1,12 +1,16 @@
using System.Diagnostics; using System.Diagnostics;
using MaksIT.Models.Agent.Requests;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using MaksIT.Agent.AuthorizationFilters;
using MaksIT.Models.Agent.Requests;
namespace MaksIT.Agent.Controllers; namespace MaksIT.Agent.Controllers;
[ApiController] [ApiController]
[Route("[controller]")] [Route("[controller]")]
[ServiceFilter(typeof(ApiKeyAuthorizationFilter))]
public class ServiceController : ControllerBase { public class ServiceController : ControllerBase {
private readonly Configuration _appSettings; private readonly Configuration _appSettings;
@ -21,14 +25,6 @@ public class ServiceController : ControllerBase {
public IActionResult Reload([FromBody] ServiceReloadRequest requestData) { public IActionResult Reload([FromBody] ServiceReloadRequest requestData) {
var serviceName = requestData.ServiceName; 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 { try {
var processStartInfo = new ProcessStartInfo { var processStartInfo = new ProcessStartInfo {
FileName = "/bin/systemctl", FileName = "/bin/systemctl",

View File

@ -1,4 +1,5 @@
using MaksIT.Agent; using MaksIT.Agent;
using MaksIT.Agent.AuthorizationFilters;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -19,6 +20,8 @@ builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddSwaggerGen();
builder.Services.AddScoped<ApiKeyAuthorizationFilter>();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.

View File

@ -52,8 +52,14 @@ namespace MaksIT.LetsEncryptServer.BackgroundServices {
} }
var hostnames = cache.GetHostsWithUpcomingSslExpiry(); var hostnames = cache.GetHostsWithUpcomingSslExpiry();
if (hostnames == null || !hostnames.Any()) { if (hostnames == null) {
_logger.LogError("No hosts found with upcoming SSL expiry"); _logger.LogError("Unexpected hostnames null");
return IDomainResult.Success();
}
if (!hostnames.Any()) {
_logger.LogInformation("No hosts found with upcoming SSL expiry");
return IDomainResult.Success(); return IDomainResult.Success();
} }