feat(audit): ExecutionId filter in the CLI and ManagementService

This commit is contained in:
Joseph Doherty
2026-05-21 16:00:09 -04:00
parent 1ba62052d6
commit 24cdfe373c
7 changed files with 103 additions and 0 deletions

View File

@@ -138,6 +138,7 @@ public class AuditExportEndpointsTests
using (host)
{
var correlationId = Guid.NewGuid().ToString();
var executionId = Guid.NewGuid().ToString();
var url =
"/api/centralui/audit/export?" +
"channel=ApiOutbound&" +
@@ -147,6 +148,7 @@ public class AuditExportEndpointsTests
"target=PaymentApi&" +
"actor=apikey-1&" +
$"correlationId={correlationId}&" +
$"executionId={executionId}&" +
"from=2026-05-20T00:00:00Z&" +
"to=2026-05-20T23:59:59Z";
@@ -167,6 +169,7 @@ public class AuditExportEndpointsTests
f.Target == "PaymentApi" &&
f.Actor == "apikey-1" &&
f.CorrelationId == Guid.Parse(correlationId) &&
f.ExecutionId == Guid.Parse(executionId) &&
f.FromUtc == new DateTime(2026, 5, 20, 0, 0, 0, DateTimeKind.Utc) &&
f.ToUtc == new DateTime(2026, 5, 20, 23, 59, 59, DateTimeKind.Utc)),
Arg.Any<AuditLogPaging>(),
@@ -195,6 +198,7 @@ public class AuditExportEndpointsTests
f.Target == null &&
f.Actor == null &&
f.CorrelationId == null &&
f.ExecutionId == null &&
f.FromUtc == null &&
f.ToUtc == null),
Arg.Any<AuditLogPaging>(),
@@ -222,6 +226,25 @@ public class AuditExportEndpointsTests
}
}
[Fact]
public async Task ExportEndpoint_UnparseableExecutionId_SilentlyDropped()
{
// Lax-parse contract: an unparseable executionId is dropped (no 400) —
// mirrors the correlationId parse.
var (client, repo, host) = await BuildHostAsync();
using (host)
{
var response = await client.GetAsync("/api/centralui/audit/export?executionId=not-a-guid");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
_ = await response.Content.ReadAsStringAsync();
await repo.Received().QueryAsync(
Arg.Is<AuditLogQueryFilter>(f => f.ExecutionId == null),
Arg.Any<AuditLogPaging>(),
Arg.Any<CancellationToken>());
}
}
/// <summary>
/// Test-only authentication handler that signs every request in as an Admin.
/// Admin is in <c>AuditExportRoles</c>, so the endpoint's AuditExport policy