up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-25 22:09:44 +02:00
parent 6bee1fdcf5
commit 9f6e6f7fb3
116 changed files with 4495 additions and 730 deletions

View File

@@ -1,28 +1,36 @@
using System.Collections.Generic;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Globalization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using StellaOps.VulnExplorer.Api.Data;
using StellaOps.VulnExplorer.Api.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddOpenApi();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "StellaOps Vuln Explorer API",
Version = "v1",
Description = "Deterministic vulnerability listing/detail endpoints"
});
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();
app.MapGet("/v1/vulns", (
HttpRequest request,
[AsParameters] VulnFilter filter) =>
app.MapGet("/v1/vulns", ([AsParameters] VulnFilter filter) =>
{
var tenant = request.Headers["x-stella-tenant"].ToString();
if (string.IsNullOrWhiteSpace(tenant))
if (string.IsNullOrWhiteSpace(filter.Tenant))
{
return Results.BadRequest(new { error = "x-stella-tenant required" });
}
@@ -40,9 +48,8 @@ app.MapGet("/v1/vulns", (
})
.WithOpenApi();
app.MapGet("/v1/vulns/{id}", (HttpRequest request, string id) =>
app.MapGet("/v1/vulns/{id}", ([FromHeader(Name = "x-stella-tenant")] string? tenant, string id) =>
{
var tenant = request.Headers["x-stella-tenant"].ToString();
if (string.IsNullOrWhiteSpace(tenant))
{
return Results.BadRequest(new { error = "x-stella-tenant required" });
@@ -63,19 +70,19 @@ static IReadOnlyList<VulnSummary> ApplyFilter(IReadOnlyList<VulnSummary> source,
{
IEnumerable<VulnSummary> query = source;
if (filter.Cve?.Count > 0)
if (filter.Cve is { Length: > 0 })
{
var set = filter.Cve.ToHashSet(StringComparer.OrdinalIgnoreCase);
query = query.Where(v => v.CveIds.Any(set.Contains));
}
if (filter.Purl?.Count > 0)
if (filter.Purl is { Length: > 0 })
{
var set = filter.Purl.ToHashSet(StringComparer.OrdinalIgnoreCase);
query = query.Where(v => v.Purls.Any(set.Contains));
}
if (filter.Severity?.Count > 0)
if (filter.Severity is { Length: > 0 })
{
var set = filter.Severity.ToHashSet(StringComparer.OrdinalIgnoreCase);
query = query.Where(v => set.Contains(v.Severity));
@@ -100,13 +107,13 @@ static IReadOnlyList<VulnSummary> ApplyFilter(IReadOnlyList<VulnSummary> source,
}
public record VulnFilter(
[FromHeader(Name = "x-stella-tenant")] string Tenant,
[FromHeader(Name = "x-stella-tenant")] string? Tenant,
[FromQuery(Name = "policyVersion")] string? PolicyVersion,
[FromQuery(Name = "pageSize")] int? PageSize,
[FromQuery(Name = "pageToken")] string? PageToken,
[FromQuery(Name = "cve")] IReadOnlyList<string>? Cve,
[FromQuery(Name = "purl")] IReadOnlyList<string>? Purl,
[FromQuery(Name = "severity")] IReadOnlyList<string>? Severity,
[FromQuery(Name = "cve")] string[]? Cve,
[FromQuery(Name = "purl")] string[]? Purl,
[FromQuery(Name = "severity")] string[]? Severity,
[FromQuery(Name = "exploitability")] string? Exploitability,
[FromQuery(Name = "fixAvailable")] bool? FixAvailable);