compose and authority fixes. finish sprints.

This commit is contained in:
master
2026-02-17 21:59:47 +02:00
parent fb46a927ad
commit 49cdebe2f1
187 changed files with 23189 additions and 1439 deletions

View File

@@ -78,15 +78,7 @@ if (app.Environment.IsDevelopment())
}
app.UseStellaOpsCors();
var hasHttpsBinding = app.Urls.Any(url => url.StartsWith("https://", StringComparison.OrdinalIgnoreCase));
if (hasHttpsBinding)
{
app.UseHttpsRedirection();
}
else
{
app.Logger.LogInformation("Skipping HTTPS redirection because no HTTPS binding is configured.");
}
// HTTPS redirection removed — the gateway handles TLS termination.
app.UseResolutionRateLimiting();
app.UseAuthorization();
app.MapControllers();

View File

@@ -5,6 +5,9 @@ using StellaOps.BinaryIndex.Cache;
using StellaOps.BinaryIndex.Contracts.Resolution;
using StellaOps.BinaryIndex.Core.Resolution;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
namespace StellaOps.BinaryIndex.WebService.Services;
@@ -19,6 +22,14 @@ public sealed class CachedResolutionService : IResolutionService
private readonly ResolutionServiceOptions _serviceOptions;
private readonly TimeProvider _timeProvider;
private readonly ILogger<CachedResolutionService> _logger;
private static readonly JsonSerializerOptions HybridDigestJsonOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = false
};
private const string HybridSchemaVersion = "1.0.0";
private const string HybridNormalizationRecipeId = "stellaops-resolution-cache-v1";
public CachedResolutionService(
IResolutionService inner,
@@ -132,7 +143,7 @@ public sealed class CachedResolutionService : IResolutionService
private VulnResolutionResponse FromCached(VulnResolutionRequest request, CachedResolution cached)
{
var evidence = BuildEvidence(cached);
var evidence = BuildEvidence(request, cached);
return new VulnResolutionResponse
{
@@ -161,20 +172,152 @@ public sealed class CachedResolutionService : IResolutionService
};
}
private static ResolutionEvidence? BuildEvidence(CachedResolution cached)
private static ResolutionEvidence? BuildEvidence(VulnResolutionRequest request, CachedResolution cached)
{
if (string.IsNullOrWhiteSpace(cached.MatchType) && cached.Confidence <= 0m)
{
return null;
}
return new ResolutionEvidence
var matchType = string.IsNullOrWhiteSpace(cached.MatchType)
? ResolutionMatchTypes.Unknown
: cached.MatchType;
var evidence = new ResolutionEvidence
{
MatchType = string.IsNullOrWhiteSpace(cached.MatchType)
? ResolutionMatchTypes.Unknown
: cached.MatchType,
Confidence = cached.Confidence
MatchType = matchType,
Confidence = cached.Confidence,
FixConfidence = cached.Confidence
};
return evidence with
{
HybridDiff = BuildHybridDiffEvidence(request, matchType, cached.Confidence, cached.Status)
};
}
private static HybridDiffEvidence BuildHybridDiffEvidence(
VulnResolutionRequest request,
string matchType,
decimal confidence,
ResolutionStatus status)
{
var anchor = !string.IsNullOrWhiteSpace(request.CveId)
? $"cve:{request.CveId}"
: $"pkg:{request.Package}";
var identity = request.BuildId
?? request.Hashes?.FileSha256
?? request.Hashes?.TextSha256
?? request.Hashes?.Blake3
?? "unknown";
var semanticEditScript = new SemanticEditScriptArtifact
{
SchemaVersion = HybridSchemaVersion,
SourceTreeDigest = ComputeDigestString($"cache-source|{request.Package}|{identity}|{matchType}"),
Edits =
[
new SemanticEditRecord
{
StableId = ComputeDigestString($"cache-edit|{request.Package}|{anchor}|{status}"),
EditType = "update",
NodeKind = "method",
NodePath = anchor,
Anchor = anchor
}
]
};
var changeType = status switch
{
ResolutionStatus.NotAffected => "removed",
_ => "modified"
};
var preSize = confidence > 0m ? 1L : 0L;
var postSize = status switch
{
ResolutionStatus.Vulnerable => preSize,
ResolutionStatus.NotAffected => 0L,
_ => preSize + 1L
};
var deltaRef = ComputeDigestString($"cache-delta|{request.Package}|{anchor}|{preSize}|{postSize}|{status}");
var preHash = ComputeDigestString($"cache-pre|{request.Package}|{anchor}|{preSize}");
var postHash = ComputeDigestString($"cache-post|{request.Package}|{anchor}|{postSize}");
var symbolPatchPlan = new SymbolPatchPlanArtifact
{
SchemaVersion = HybridSchemaVersion,
BuildIdBefore = $"baseline:{identity}",
BuildIdAfter = identity,
EditsDigest = ComputeDigest(semanticEditScript),
SymbolMapDigestBefore = ComputeDigestString($"cache-symbol-map|old|{identity}|{anchor}"),
SymbolMapDigestAfter = ComputeDigestString($"cache-symbol-map|new|{identity}|{anchor}"),
Changes =
[
new SymbolPatchChange
{
Symbol = anchor,
ChangeType = changeType,
AstAnchors = [anchor],
PreHash = preHash,
PostHash = postHash,
DeltaRef = deltaRef
}
]
};
var patchManifest = new PatchManifestArtifact
{
SchemaVersion = HybridSchemaVersion,
BuildId = identity,
NormalizationRecipeId = HybridNormalizationRecipeId,
TotalDeltaBytes = Math.Abs(postSize - preSize),
Patches =
[
new SymbolPatchArtifact
{
Symbol = anchor,
AddressRange = "0x0-0x0",
DeltaDigest = deltaRef,
Pre = new PatchSizeHash
{
Size = preSize,
Hash = preHash
},
Post = new PatchSizeHash
{
Size = postSize,
Hash = postHash
},
DeltaSizeBytes = Math.Abs(postSize - preSize)
}
]
};
return new HybridDiffEvidence
{
SemanticEditScriptDigest = ComputeDigest(semanticEditScript),
OldSymbolMapDigest = ComputeDigestString($"cache-symbol-map|old-digest|{identity}|{anchor}"),
NewSymbolMapDigest = ComputeDigestString($"cache-symbol-map|new-digest|{identity}|{anchor}"),
SymbolPatchPlanDigest = ComputeDigest(symbolPatchPlan),
PatchManifestDigest = ComputeDigest(patchManifest),
SemanticEditScript = semanticEditScript,
SymbolPatchPlan = symbolPatchPlan,
PatchManifest = patchManifest
};
}
private static string ComputeDigest<T>(T value)
{
var json = JsonSerializer.Serialize(value, HybridDigestJsonOptions);
return ComputeDigestString(json);
}
private static string ComputeDigestString(string input)
{
var bytes = Encoding.UTF8.GetBytes(input);
var hash = SHA256.HashData(bytes);
return $"sha256:{Convert.ToHexString(hash).ToLowerInvariant()}";
}
private TimeSpan GetCacheTtl(ResolutionStatus status)
@@ -188,3 +331,4 @@ public sealed class CachedResolutionService : IResolutionService
};
}
}

View File

@@ -30,3 +30,5 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0129-T | DONE | Test coverage audit for StellaOps.BinaryIndex.WebService; revalidated 2026-01-06. |
| AUDIT-0129-A | TODO | Revalidated 2026-01-06; open findings pending apply. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |
| BHP-05-API-HYBRID-20260217 | DONE | SPRINT_20260216_001: cache wrapper now projects deterministic fallback hybridDiff evidence for cached responses consumed by Web UI. |