feat(inbound): register AuditWriteMiddleware in pipeline (#23 M4)

This commit is contained in:
Joseph Doherty
2026-05-20 16:35:13 -04:00
parent 3c3f7770c1
commit 1c862989b4
3 changed files with 257 additions and 0 deletions

View File

@@ -12,6 +12,7 @@ using ScadaLink.Host;
using ScadaLink.Host.Actors;
using ScadaLink.Host.Health;
using ScadaLink.InboundAPI;
using ScadaLink.InboundAPI.Middleware;
using ScadaLink.ManagementService;
using ScadaLink.NotificationOutbox;
using ScadaLink.NotificationService;
@@ -162,6 +163,18 @@ try
app.UseAuthorization();
app.UseAntiforgery();
// Audit Log #23 (M4 Bundle D, T8): emit one InboundRequest/InboundAuthFailure
// audit row per call into the inbound API. Placed AFTER UseAuthentication/
// UseAuthorization so any HttpContext.User the framework populates is in
// place, and scoped to the /api/ prefix so it never observes the Central UI,
// Management API, SignalR hubs, or health endpoints. The endpoint handler
// is responsible for stashing the resolved API key name on
// HttpContext.Items (see AuditWriteMiddleware.AuditActorItemKey) AFTER its
// in-handler API key validation succeeds.
app.UseWhen(
ctx => ctx.Request.Path.StartsWithSegments("/api"),
branch => branch.UseAuditWriteMiddleware());
// WP-12: Map readiness endpoint — returns 503 until ready, 200 when ready.
// REQ-HOST-4a defines readiness as cluster membership + DB connectivity,
// explicitly NOT cluster leadership. The leader-only "active-node" check is

View File

@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ScadaLink.InboundAPI.Middleware;
namespace ScadaLink.InboundAPI;
@@ -53,6 +54,13 @@ public static class EndpointExtensions
var method = validationResult.Method!;
// Audit Log (#23 M4 Bundle D): publish the resolved API key name so
// AuditWriteMiddleware can populate AuditEvent.Actor in its finally
// block. Done AFTER validation succeeded — auth failures leave the
// slot empty and the middleware records the row with Actor=null.
httpContext.Items[AuditWriteMiddleware.AuditActorItemKey] =
validationResult.ApiKey!.Name;
// WP-2: Deserialize and validate parameters
JsonElement? body = null;
try