save audit remarks applications progress

This commit is contained in:
StellaOps Bot
2026-01-04 22:49:53 +02:00
parent 8862e112c4
commit eca4e964d3
48 changed files with 1850 additions and 112 deletions

View File

@@ -151,6 +151,7 @@ public static class EpssEndpoints
private static async Task<IResult> GetHistory(
[FromRoute] string cveId,
[FromServices] IEpssProvider epssProvider,
[FromServices] TimeProvider timeProvider,
[FromQuery] string? startDate = null,
[FromQuery] string? endDate = null,
[FromQuery] int days = 30,
@@ -183,7 +184,7 @@ public static class EpssEndpoints
else
{
// Default to last N days
end = DateOnly.FromDateTime(DateTime.UtcNow);
end = DateOnly.FromDateTime(timeProvider.GetUtcNow().UtcDateTime);
start = end.AddDays(-days);
}
@@ -213,6 +214,7 @@ public static class EpssEndpoints
/// </summary>
private static async Task<IResult> GetStatus(
[FromServices] IEpssProvider epssProvider,
[FromServices] TimeProvider timeProvider,
CancellationToken cancellationToken)
{
var isAvailable = await epssProvider.IsAvailableAsync(cancellationToken);
@@ -222,7 +224,7 @@ public static class EpssEndpoints
{
Available = isAvailable,
LatestModelDate = modelDate?.ToString("yyyy-MM-dd"),
LastCheckedUtc = DateTimeOffset.UtcNow
LastCheckedUtc = timeProvider.GetUtcNow()
});
}
}

View File

@@ -60,6 +60,7 @@ internal static class EvidenceEndpoints
string scanId,
string findingId,
IEvidenceCompositionService evidenceService,
TimeProvider timeProvider,
HttpContext context,
CancellationToken cancellationToken)
{
@@ -108,7 +109,7 @@ internal static class EvidenceEndpoints
}
else if (evidence.Freshness.ExpiresAt.HasValue)
{
var timeUntilExpiry = evidence.Freshness.ExpiresAt.Value - DateTimeOffset.UtcNow;
var timeUntilExpiry = evidence.Freshness.ExpiresAt.Value - timeProvider.GetUtcNow();
if (timeUntilExpiry <= TimeSpan.FromDays(1))
{
context.Response.Headers["X-Evidence-Warning"] = "near-expiry";

View File

@@ -270,6 +270,7 @@ internal static class SmartDiffEndpoints
string candidateId,
ReviewRequest request,
IVexCandidateStore store,
TimeProvider timeProvider,
HttpContext httpContext,
CancellationToken ct = default)
{
@@ -282,7 +283,7 @@ internal static class SmartDiffEndpoints
var review = new VexCandidateReview(
Action: action,
Reviewer: reviewer,
ReviewedAt: DateTimeOffset.UtcNow,
ReviewedAt: timeProvider.GetUtcNow(),
Comment: request.Comment);
var success = await store.ReviewCandidateAsync(candidateId, review, ct);

View File

@@ -41,6 +41,7 @@ internal static class ProofBundleEndpoints
private static async Task<IResult> HandleGenerateProofBundleAsync(
[FromBody] ProofBundleRequest request,
[FromServices] IProofBundleGenerator bundleGenerator,
[FromServices] TimeProvider timeProvider,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(bundleGenerator);
@@ -67,7 +68,7 @@ internal static class ProofBundleEndpoints
{
PathId = request.PathId,
Bundle = bundle,
GeneratedAt = DateTimeOffset.UtcNow
GeneratedAt = timeProvider.GetUtcNow()
};
return Results.Ok(response);

View File

@@ -50,6 +50,7 @@ internal static class TriageInboxEndpoints
[FromQuery] string? filter,
[FromServices] IExploitPathGroupingService groupingService,
[FromServices] IFindingQueryService findingService,
[FromServices] TimeProvider timeProvider,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(groupingService);
@@ -77,7 +78,7 @@ internal static class TriageInboxEndpoints
FilteredPaths = filteredPaths.Count,
Filter = filter,
Paths = filteredPaths,
GeneratedAt = DateTimeOffset.UtcNow
GeneratedAt = timeProvider.GetUtcNow()
};
return Results.Ok(response);

View File

@@ -55,6 +55,7 @@ internal static class UnknownsEndpoints
[FromQuery] int? limit,
IUnknownRepository repository,
IUnknownRanker ranker,
TimeProvider timeProvider,
CancellationToken cancellationToken)
{
// Validate and default pagination
@@ -95,9 +96,10 @@ internal static class UnknownsEndpoints
PageSize: pageSize);
var result = await repository.ListUnknownsAsync(query, cancellationToken);
var now = timeProvider.GetUtcNow();
return Results.Ok(new UnknownsListResponse(
Items: result.Items.Select(UnknownItemResponse.FromUnknownItem).ToList(),
Items: result.Items.Select(item => UnknownItemResponse.FromUnknownItem(item, now)).ToList(),
TotalCount: result.TotalCount,
Page: pageNum,
PageSize: pageSize,
@@ -195,7 +197,7 @@ public sealed record UnknownItemResponse(
ContainmentResponse? Containment,
DateTimeOffset CreatedAt)
{
public static UnknownItemResponse FromUnknownItem(UnknownItem item) => new(
public static UnknownItemResponse FromUnknownItem(UnknownItem item, DateTimeOffset now) => new(
Id: Guid.TryParse(item.Id, out var id) ? id : Guid.Empty,
SubjectRef: item.ArtifactPurl ?? item.ArtifactDigest,
Kind: string.Join(",", item.Reasons),
@@ -209,7 +211,7 @@ public sealed record UnknownItemResponse(
Containment: item.Containment != null
? new ContainmentResponse(item.Containment.Seccomp, item.Containment.Fs)
: null,
CreatedAt: DateTimeOffset.UtcNow); // Would come from Unknown.SysFrom
CreatedAt: now); // Would come from Unknown.SysFrom
}
/// <summary>

View File

@@ -120,6 +120,7 @@ internal static class WitnessEndpoints
private static async Task<IResult> HandleVerifyWitnessAsync(
Guid witnessId,
IWitnessRepository repository,
TimeProvider timeProvider,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(repository);
@@ -161,10 +162,11 @@ internal static class WitnessEndpoints
}
// Record verification attempt
var now = timeProvider.GetUtcNow();
await repository.RecordVerificationAsync(new WitnessVerificationRecord
{
WitnessId = witnessId,
VerifiedAt = DateTimeOffset.UtcNow,
VerifiedAt = now,
VerifiedBy = "api",
VerificationStatus = verificationStatus,
VerificationError = verificationError
@@ -176,7 +178,7 @@ internal static class WitnessEndpoints
WitnessHash = witness.WitnessHash,
Status = verificationStatus,
Error = verificationError,
VerifiedAt = DateTimeOffset.UtcNow,
VerifiedAt = now,
IsSigned = !string.IsNullOrEmpty(witness.DsseEnvelope)
});
}