refactor(adminui): omit error key on success cert-audit rows + assert OccurredAtUtc (review)
This commit is contained in:
@@ -28,18 +28,17 @@ public static class CertAuditEvents
|
|||||||
/// <see cref="AuditOutcome.Success" />); otherwise <see langword="false" /> (Outcome
|
/// <see cref="AuditOutcome.Success" />); otherwise <see langword="false" /> (Outcome
|
||||||
/// <see cref="AuditOutcome.Failure" />).</param>
|
/// <see cref="AuditOutcome.Failure" />).</param>
|
||||||
/// <param name="error">On failure, the error text carried in the details payload; ignored on
|
/// <param name="error">On failure, the error text carried in the details payload; ignored on
|
||||||
/// success (the details payload serializes <see langword="null" /> for the error field).</param>
|
/// success (the <c>error</c> field is omitted from the details payload entirely).</param>
|
||||||
/// <returns>A fully populated <see cref="AuditEvent" /> with a fresh <see cref="AuditEvent.EventId" />
|
/// <returns>A fully populated <see cref="AuditEvent" /> with a fresh <see cref="AuditEvent.EventId" />
|
||||||
/// and <see cref="AuditEvent.OccurredAtUtc" /> set to now (UTC).</returns>
|
/// and <see cref="AuditEvent.OccurredAtUtc" /> set to now (UTC).</returns>
|
||||||
public static AuditEvent Build(
|
public static AuditEvent Build(
|
||||||
string action, string store, string thumbprint, string actor, bool success, string? error)
|
string action, string store, string thumbprint, string actor, bool success, string? error)
|
||||||
{
|
{
|
||||||
var detailsJson = JsonSerializer.Serialize(new
|
// On success the error field is omitted entirely (not serialized as null) so the common
|
||||||
{
|
// success-path audit row carries no dead "error" key.
|
||||||
store,
|
var detailsJson = JsonSerializer.Serialize(success
|
||||||
thumbprint,
|
? (object)new { store, thumbprint }
|
||||||
error = success ? null : error,
|
: new { store, thumbprint, error });
|
||||||
});
|
|
||||||
|
|
||||||
return new AuditEvent
|
return new AuditEvent
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public sealed class CertAuditEventsTests
|
|||||||
evt.Actor.ShouldBe("alice");
|
evt.Actor.ShouldBe("alice");
|
||||||
evt.Outcome.ShouldBe(AuditOutcome.Success);
|
evt.Outcome.ShouldBe(AuditOutcome.Success);
|
||||||
evt.EventId.ShouldNotBe(Guid.Empty);
|
evt.EventId.ShouldNotBe(Guid.Empty);
|
||||||
|
evt.OccurredAtUtc.ShouldBeGreaterThan(DateTimeOffset.UtcNow.AddSeconds(-5));
|
||||||
evt.DetailsJson.ShouldNotBeNull();
|
evt.DetailsJson.ShouldNotBeNull();
|
||||||
evt.DetailsJson!.ShouldContain(Thumb);
|
evt.DetailsJson!.ShouldContain(Thumb);
|
||||||
}
|
}
|
||||||
@@ -88,13 +89,14 @@ public sealed class CertAuditEventsTests
|
|||||||
evt.DetailsJson!.ShouldContain("store write failed");
|
evt.DetailsJson!.ShouldContain("store write failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>On success the error text is omitted from the details payload (it serializes null).</summary>
|
/// <summary>On success the error text AND the error key are omitted from the details payload.</summary>
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Build_success_omits_error_text()
|
public void Build_success_omits_error_text()
|
||||||
{
|
{
|
||||||
var evt = CertAuditEvents.Build("Trust", "rejected", Thumb, "alice", success: true, error: "ignored");
|
var evt = CertAuditEvents.Build("Trust", "rejected", Thumb, "alice", success: true, error: "ignored");
|
||||||
|
|
||||||
evt.DetailsJson!.ShouldNotContain("ignored");
|
evt.DetailsJson!.ShouldNotContain("ignored");
|
||||||
|
evt.DetailsJson!.ShouldNotContain("error");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>The public Category constant matches the value stamped onto built events.</summary>
|
/// <summary>The public Category constant matches the value stamped onto built events.</summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user