Frontend gaps fill work. Testing fixes work. Auditing in progress.

This commit is contained in:
StellaOps Bot
2025-12-30 01:22:58 +02:00
parent 1dc4bcbf10
commit 7a5210e2aa
928 changed files with 183942 additions and 3941 deletions

View File

@@ -0,0 +1,137 @@
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using Serilog;
using StellaOps.VexLens.Api;
using StellaOps.VexLens.Consensus;
using StellaOps.VexLens.Persistence;
using StellaOps.VexLens.Storage;
using StellaOps.VexLens.Trust;
using StellaOps.VexLens.WebService.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Configure Serilog
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Configuration)
.Enrich.FromLogContext()
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")
.CreateLogger();
builder.Host.UseSerilog();
// Configure OpenAPI
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddOpenApi();
// Configure OpenTelemetry
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService("StellaOps.VexLens"))
.WithTracing(tracing =>
{
tracing
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation();
if (builder.Environment.IsDevelopment())
{
tracing.AddConsoleExporter();
}
});
// Configure VexLens services
builder.Services.AddSingleton<IVexConsensusEngine, DefaultVexConsensusEngine>();
builder.Services.AddSingleton<ITrustWeightEngine, DefaultTrustWeightEngine>();
builder.Services.AddSingleton<IConsensusProjectionStore, InMemoryConsensusProjectionStore>();
builder.Services.AddSingleton<IIssuerDirectory, InMemoryIssuerDirectory>();
builder.Services.AddSingleton<IVexStatementProvider, NullVexStatementProvider>();
builder.Services.AddScoped<IVexLensApiService, VexLensApiService>();
// Configure PostgreSQL persistence if configured
var connectionString = builder.Configuration.GetConnectionString("VexLens");
if (!string.IsNullOrEmpty(connectionString))
{
builder.Services.AddSingleton<IConsensusProjectionStore>(sp =>
new PostgresConsensusProjectionStore(connectionString, "vexlens"));
builder.Services.AddSingleton<IIssuerDirectory>(sp =>
new PostgresIssuerDirectory(connectionString, "vexlens"));
}
// Configure health checks
builder.Services.AddHealthChecks();
// Configure rate limiting
builder.Services.AddRateLimiter(options =>
{
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
options.AddFixedWindowLimiter("vexlens", limiterOptions =>
{
limiterOptions.PermitLimit = 100;
limiterOptions.Window = TimeSpan.FromMinutes(1);
});
});
var app = builder.Build();
// Configure request pipeline
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseRateLimiter();
app.UseSerilogRequestLogging();
// Map health check endpoint
app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = async (context, report) =>
{
context.Response.ContentType = "application/json";
var result = new
{
status = report.Status.ToString(),
checks = report.Entries.Select(e => new
{
name = e.Key,
status = e.Value.Status.ToString(),
description = e.Value.Description
})
};
await context.Response.WriteAsJsonAsync(result);
}
});
// Map VexLens API endpoints
app.MapVexLensEndpoints();
// Log startup
Log.Information("VexLens WebService starting on {Urls}", string.Join(", ", app.Urls));
try
{
app.Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "VexLens WebService terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
/// <summary>
/// Null implementation for development without VexHub integration.
/// </summary>
internal sealed class NullVexStatementProvider : IVexStatementProvider
{
public Task<IReadOnlyList<VexStatementWithContext>> GetStatementsAsync(
string vulnerabilityId,
string productKey,
string? tenantId,
CancellationToken cancellationToken = default)
{
return Task.FromResult<IReadOnlyList<VexStatementWithContext>>([]);
}
}