work
This commit is contained in:
@@ -32,7 +32,6 @@ using StellaOps.Excititor.WebService.Extensions;
|
||||
using StellaOps.Excititor.WebService.Options;
|
||||
using StellaOps.Excititor.WebService.Services;
|
||||
using StellaOps.Excititor.Core.Aoc;
|
||||
using StellaOps.Excititor.WebService.Contracts;
|
||||
using StellaOps.Excititor.WebService.Telemetry;
|
||||
using MongoDB.Driver;
|
||||
using MongoDB.Bson;
|
||||
@@ -170,14 +169,14 @@ app.MapPost("/airgap/v1/vex/import", async (
|
||||
|
||||
if (!trustService.Validate(request, out var trustCode, out var trustMessage))
|
||||
{
|
||||
return Results.StatusCode(StatusCodes.Status403Forbidden, new
|
||||
return Results.Json(new
|
||||
{
|
||||
error = new
|
||||
{
|
||||
code = trustCode,
|
||||
message = trustMessage
|
||||
}
|
||||
});
|
||||
}, statusCode: StatusCodes.Status403Forbidden);
|
||||
}
|
||||
|
||||
var record = new AirgapImportRecord
|
||||
@@ -344,13 +343,26 @@ app.MapGet("/console/vex", async (
|
||||
}
|
||||
|
||||
var query = context.Request.Query;
|
||||
var purls = query["purl"].Where(static v => !string.IsNullOrWhiteSpace(v)).Select(static v => v.Trim()).ToArray();
|
||||
var advisories = query["advisoryId"].Where(static v => !string.IsNullOrWhiteSpace(v)).Select(static v => v.Trim()).ToArray();
|
||||
static string[] NormalizeValues(StringValues values) =>
|
||||
values.Where(static v => !string.IsNullOrWhiteSpace(v))
|
||||
.Select(static v => v!.Trim())
|
||||
.ToArray();
|
||||
|
||||
var purls = query.TryGetValue("purl", out var purlValues)
|
||||
? NormalizeValues(purlValues)
|
||||
: Array.Empty<string>();
|
||||
var advisories = query.TryGetValue("advisoryId", out var advisoryValues)
|
||||
? NormalizeValues(advisoryValues)
|
||||
: Array.Empty<string>();
|
||||
var statuses = new List<VexClaimStatus>();
|
||||
if (query.TryGetValue("status", out var statusValues))
|
||||
{
|
||||
foreach (var statusValue in statusValues)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(statusValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (Enum.TryParse<VexClaimStatus>(statusValue, ignoreCase: true, out var parsed))
|
||||
{
|
||||
statuses.Add(parsed);
|
||||
@@ -377,17 +389,17 @@ app.MapGet("/console/vex", async (
|
||||
}
|
||||
telemetry.CacheMisses.Add(1);
|
||||
|
||||
var options = new VexObservationQueryOptions(
|
||||
tenant,
|
||||
observationIds: null,
|
||||
vulnerabilityIds: advisories,
|
||||
productKeys: null,
|
||||
purls: purls,
|
||||
cpes: null,
|
||||
providerIds: null,
|
||||
statuses: statuses,
|
||||
cursor: cursor,
|
||||
limit: limit);
|
||||
var options = new VexObservationQueryOptions(
|
||||
tenant,
|
||||
observationIds: null,
|
||||
vulnerabilityIds: advisories,
|
||||
productKeys: null,
|
||||
purls: purls,
|
||||
cpes: null,
|
||||
providerIds: null,
|
||||
statuses: statuses,
|
||||
limit: limit,
|
||||
cursor: cursor);
|
||||
|
||||
VexObservationQueryResult result;
|
||||
try
|
||||
@@ -399,22 +411,24 @@ app.MapGet("/console/vex", async (
|
||||
return Results.BadRequest(ex.Message);
|
||||
}
|
||||
|
||||
var statements = result.Observations
|
||||
.SelectMany(obs => obs.Statements.Select(stmt => new VexConsoleStatementDto(
|
||||
AdvisoryId: stmt.VulnerabilityId,
|
||||
ProductKey: stmt.ProductKey,
|
||||
Purl: stmt.Purl ?? obs.Linkset.Purls.FirstOrDefault(),
|
||||
Status: stmt.Status.ToString().ToLowerInvariant(),
|
||||
Justification: stmt.Justification?.ToString(),
|
||||
ProviderId: obs.ProviderId,
|
||||
ObservationId: obs.ObservationId,
|
||||
CreatedAtUtc: obs.CreatedAt,
|
||||
Attributes: obs.Attributes)))
|
||||
.ToList();
|
||||
var statements = result.Observations
|
||||
.SelectMany(obs => obs.Statements.Select(stmt => new VexConsoleStatementDto(
|
||||
AdvisoryId: stmt.VulnerabilityId,
|
||||
ProductKey: stmt.ProductKey,
|
||||
Purl: stmt.Purl
|
||||
?? (obs.Linkset is { } linkset ? linkset.Purls.FirstOrDefault() : null)
|
||||
?? string.Empty,
|
||||
Status: stmt.Status.ToString().ToLowerInvariant(),
|
||||
Justification: stmt.Justification?.ToString(),
|
||||
ProviderId: obs.ProviderId,
|
||||
ObservationId: obs.ObservationId,
|
||||
CreatedAtUtc: obs.CreatedAt,
|
||||
Attributes: obs.Attributes ?? ImmutableDictionary<string, string>.Empty)))
|
||||
.ToList();
|
||||
|
||||
var statusCounts = result.Observations
|
||||
.GroupBy(o => o.Status.ToString().ToLowerInvariant())
|
||||
.ToDictionary(g => g.Key, g => g.Count(), StringComparer.OrdinalIgnoreCase);
|
||||
var statusCounts = statements
|
||||
.GroupBy(o => o.Status)
|
||||
.ToDictionary(g => g.Key, g => g.Count(), StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var response = new VexConsolePage(
|
||||
Items: statements,
|
||||
@@ -455,12 +469,10 @@ app.MapPost("/internal/graph/linkouts", async (
|
||||
return Results.BadRequest("purls are required (1-500).");
|
||||
}
|
||||
|
||||
var options = new VexObservationQueryOptions(
|
||||
request.Tenant.Trim(),
|
||||
purls: normalizedPurls,
|
||||
includeJustifications: request.IncludeJustifications,
|
||||
includeProvenance: request.IncludeProvenance,
|
||||
limit: 200);
|
||||
var options = new VexObservationQueryOptions(
|
||||
request.Tenant.Trim(),
|
||||
purls: normalizedPurls,
|
||||
limit: 200);
|
||||
|
||||
VexObservationQueryResult result;
|
||||
try
|
||||
@@ -495,31 +507,18 @@ app.MapPost("/internal/graph/linkouts", async (
|
||||
Status: stmt.Status.ToString().ToLowerInvariant(),
|
||||
Justification: request.IncludeJustifications ? stmt.Justification?.ToString() : null,
|
||||
ModifiedAt: obs.CreatedAt,
|
||||
EvidenceHash: obs.Linkset.ReferenceHash,
|
||||
EvidenceHash: string.Empty,
|
||||
ConnectorId: obs.ProviderId,
|
||||
DsseEnvelopeHash: request.IncludeProvenance ? obs.Linkset.ReferenceHash : null)))
|
||||
DsseEnvelopeHash: request.IncludeProvenance ? string.Empty : null)))
|
||||
.OrderBy(a => a.AdvisoryId, StringComparer.Ordinal)
|
||||
.ThenBy(a => a.Source, StringComparer.Ordinal)
|
||||
.Take(200)
|
||||
.ToList();
|
||||
|
||||
var conflicts = obsForPurl
|
||||
.Where(obs => obs.Statements.Any(s => s.Status == VexClaimStatus.Conflict))
|
||||
.SelectMany(obs => obs.Statements
|
||||
.Where(s => s.Status == VexClaimStatus.Conflict)
|
||||
.Select(stmt => new GraphLinkoutConflict(
|
||||
Source: obs.ProviderId,
|
||||
Status: stmt.Status.ToString().ToLowerInvariant(),
|
||||
Justification: request.IncludeJustifications ? stmt.Justification?.ToString() : null,
|
||||
ObservedAt: obs.CreatedAt,
|
||||
EvidenceHash: obs.Linkset.ReferenceHash)))
|
||||
.OrderBy(c => c.Source, StringComparer.Ordinal)
|
||||
.ToList();
|
||||
|
||||
items.Add(new GraphLinkoutItem(
|
||||
Purl: inputPurl,
|
||||
Advisories: advisories,
|
||||
Conflicts: conflicts,
|
||||
Conflicts: Array.Empty<GraphLinkoutConflict>(),
|
||||
Truncated: advisories.Count >= 200,
|
||||
NextCursor: advisories.Count >= 200 ? $"{advisories[^1].AdvisoryId}:{advisories[^1].Source}" : null));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user