Refactor code structure for improved readability and maintainability; optimize performance in key functions.

This commit is contained in:
master
2025-12-22 19:06:31 +02:00
parent dfaa2079aa
commit 4602ccc3a3
1444 changed files with 109919 additions and 8058 deletions

View File

@@ -0,0 +1,164 @@
using System.Collections.Immutable;
using System.Text.Json;
using StellaOps.Attestor.ProofChain.Predicates;
using StellaOps.Attestor.ProofChain.Statements;
using StellaOps.Scanner.SmartDiff.Detection;
namespace StellaOps.Scanner.SmartDiff.Attestation;
/// <summary>
/// Build request for delta verdict attestations.
/// </summary>
public sealed record DeltaVerdictBuildRequest
{
public required string BeforeRevisionId { get; init; }
public required string AfterRevisionId { get; init; }
public required string BeforeImageDigest { get; init; }
public required string AfterImageDigest { get; init; }
public required IReadOnlyList<MaterialRiskChangeResult> Changes { get; init; }
public DateTimeOffset? ComparedAt { get; init; }
public string? BeforeVerdictDigest { get; init; }
public string? AfterVerdictDigest { get; init; }
public AttestationReference? BeforeProofSpine { get; init; }
public AttestationReference? AfterProofSpine { get; init; }
public string? BeforeGraphRevisionId { get; init; }
public string? AfterGraphRevisionId { get; init; }
public string? BeforeImageName { get; init; }
public string? AfterImageName { get; init; }
}
/// <summary>
/// Builds delta verdict predicate and statement payloads.
/// </summary>
public sealed class DeltaVerdictBuilder
{
private readonly TimeProvider _timeProvider;
public DeltaVerdictBuilder(TimeProvider? timeProvider = null)
{
_timeProvider = timeProvider ?? TimeProvider.System;
}
public DeltaVerdictPredicate BuildPredicate(DeltaVerdictBuildRequest request)
{
ArgumentNullException.ThrowIfNull(request);
ArgumentNullException.ThrowIfNull(request.Changes);
ArgumentException.ThrowIfNullOrWhiteSpace(request.BeforeRevisionId);
ArgumentException.ThrowIfNullOrWhiteSpace(request.AfterRevisionId);
var comparedAt = request.ComparedAt ?? _timeProvider.GetUtcNow();
var changeEntries = BuildChangeEntries(request.Changes);
var hasMaterialChange = request.Changes.Any(c => c.HasMaterialChange);
var priorityScore = request.Changes
.Where(c => c.HasMaterialChange)
.Sum(c => c.PriorityScore);
return new DeltaVerdictPredicate
{
BeforeRevisionId = request.BeforeRevisionId,
AfterRevisionId = request.AfterRevisionId,
HasMaterialChange = hasMaterialChange,
PriorityScore = priorityScore,
Changes = changeEntries,
BeforeVerdictDigest = request.BeforeVerdictDigest,
AfterVerdictDigest = request.AfterVerdictDigest,
BeforeProofSpine = request.BeforeProofSpine,
AfterProofSpine = request.AfterProofSpine,
BeforeGraphRevisionId = request.BeforeGraphRevisionId,
AfterGraphRevisionId = request.AfterGraphRevisionId,
ComparedAt = comparedAt
};
}
public DeltaVerdictStatement BuildStatement(DeltaVerdictBuildRequest request)
{
ArgumentNullException.ThrowIfNull(request);
ArgumentException.ThrowIfNullOrWhiteSpace(request.BeforeImageDigest);
ArgumentException.ThrowIfNullOrWhiteSpace(request.AfterImageDigest);
var predicate = BuildPredicate(request);
return new DeltaVerdictStatement
{
Subject =
[
BuildSubject(request.BeforeImageDigest, request.BeforeImageName),
BuildSubject(request.AfterImageDigest, request.AfterImageName)
],
Predicate = predicate
};
}
private static ImmutableArray<DeltaVerdictChange> BuildChangeEntries(IReadOnlyList<MaterialRiskChangeResult> changes)
{
if (changes.Count == 0)
{
return [];
}
var entries = new List<DeltaVerdictChange>();
foreach (var change in changes)
{
if (!change.HasMaterialChange || change.Changes.IsDefaultOrEmpty)
{
continue;
}
foreach (var detail in change.Changes)
{
entries.Add(new DeltaVerdictChange
{
Rule = ToJsonEnum(detail.Rule),
FindingKey = new DeltaFindingKey
{
VulnId = change.FindingKey.VulnId,
Purl = change.FindingKey.ComponentPurl
},
Direction = ToJsonEnum(detail.Direction),
ChangeType = ToJsonEnum(detail.ChangeType),
Reason = detail.Reason,
PreviousValue = detail.PreviousValue,
CurrentValue = detail.CurrentValue,
Weight = detail.Weight
});
}
}
return entries
.OrderBy(e => e.FindingKey.VulnId, StringComparer.Ordinal)
.ThenBy(e => e.FindingKey.Purl, StringComparer.Ordinal)
.ThenBy(e => e.Rule, StringComparer.Ordinal)
.ThenBy(e => e.ChangeType, StringComparer.Ordinal)
.ThenBy(e => e.Direction, StringComparer.Ordinal)
.ThenBy(e => e.Reason, StringComparer.Ordinal)
.ToImmutableArray();
}
private static Subject BuildSubject(string digest, string? name)
{
var (algorithm, value) = SplitDigest(digest);
return new Subject
{
Name = name ?? digest,
Digest = new Dictionary<string, string> { [algorithm] = value }
};
}
private static (string Algorithm, string Value) SplitDigest(string digest)
{
var colonIndex = digest.IndexOf(':');
if (colonIndex <= 0 || colonIndex == digest.Length - 1)
{
return ("sha256", digest);
}
return (digest[..colonIndex], digest[(colonIndex + 1)..]);
}
private static string ToJsonEnum<TEnum>(TEnum value) where TEnum : struct, Enum
{
var json = JsonSerializer.Serialize(value);
return json.Trim('"');
}
}

View File

@@ -0,0 +1,61 @@
using StellaOps.Attestor.ProofChain.Predicates;
using StellaOps.Scanner.Storage.Oci;
namespace StellaOps.Scanner.SmartDiff.Attestation;
public sealed record DeltaVerdictOciPublishRequest
{
public required string Reference { get; init; }
public required string BeforeImageDigest { get; init; }
public required string AfterImageDigest { get; init; }
public required byte[] DsseEnvelopeBytes { get; init; }
public string? AttestationDigest { get; init; }
}
public sealed class DeltaVerdictOciPublisher
{
private readonly OciArtifactPusher _pusher;
public DeltaVerdictOciPublisher(OciArtifactPusher pusher)
{
_pusher = pusher ?? throw new ArgumentNullException(nameof(pusher));
}
public Task<OciArtifactPushResult> PushAsync(
DeltaVerdictOciPublishRequest request,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
var annotations = new Dictionary<string, string>(StringComparer.Ordinal)
{
[OciAnnotations.StellaPredicateType] = DeltaVerdictPredicate.PredicateType,
[OciAnnotations.BaseDigest] = request.BeforeImageDigest,
[OciAnnotations.StellaBeforeDigest] = request.BeforeImageDigest,
[OciAnnotations.StellaAfterDigest] = request.AfterImageDigest
};
if (!string.IsNullOrWhiteSpace(request.AttestationDigest))
{
annotations[OciAnnotations.StellaAttestationDigest] = request.AttestationDigest!;
}
var pushRequest = new OciArtifactPushRequest
{
Reference = request.Reference,
ArtifactType = OciMediaTypes.DeltaVerdictPredicate,
SubjectDigest = request.AfterImageDigest,
Layers =
[
new OciLayerContent
{
Content = request.DsseEnvelopeBytes,
MediaType = OciMediaTypes.DsseEnvelope
}
],
Annotations = annotations
};
return _pusher.PushAsync(pushRequest, cancellationToken);
}
}

View File

@@ -46,7 +46,8 @@ public sealed record SmartDiffSarifInput(
IReadOnlyList<HardeningRegression> HardeningRegressions,
IReadOnlyList<VexCandidate> VexCandidates,
IReadOnlyList<ReachabilityChange> ReachabilityChanges,
VcsInfo? VcsInfo = null);
VcsInfo? VcsInfo = null,
string? DeltaVerdictReference = null);
/// <summary>
/// VCS information for SARIF provenance.
@@ -244,7 +245,7 @@ public sealed class SarifOutputGenerator
// Material risk changes
foreach (var change in input.MaterialChanges)
{
results.Add(CreateMaterialChangeResult(change));
results.Add(CreateMaterialChangeResult(change, input.DeltaVerdictReference));
}
// Hardening regressions
@@ -277,7 +278,7 @@ public sealed class SarifOutputGenerator
return [.. results];
}
private static SarifResult CreateMaterialChangeResult(MaterialRiskChange change)
private static SarifResult CreateMaterialChangeResult(MaterialRiskChange change, string? deltaVerdictReference)
{
var level = change.Direction == RiskDirection.Increased ? SarifLevel.Warning : SarifLevel.Note;
var message = $"Material risk change for {change.VulnId} in {change.ComponentPurl}: {change.Reason}";
@@ -288,6 +289,13 @@ public sealed class SarifOutputGenerator
ArtifactLocation: new SarifArtifactLocation(Uri: change.FilePath))))
: (ImmutableArray<SarifLocation>?)null;
var properties = deltaVerdictReference is null
? null
: ImmutableSortedDictionary.CreateRange(StringComparer.Ordinal, new[]
{
KeyValuePair.Create("deltaVerdictRef", (object)deltaVerdictReference)
});
return new SarifResult(
RuleId: "SDIFF001",
Level: level,
@@ -297,7 +305,8 @@ public sealed class SarifOutputGenerator
{
KeyValuePair.Create("purl", change.ComponentPurl),
KeyValuePair.Create("vulnId", change.VulnId),
}));
}),
Properties: properties);
}
private static SarifResult CreateHardeningRegressionResult(HardeningRegression regression)

View File

@@ -5,4 +5,9 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\\..\\..\\Attestor\\__Libraries\\StellaOps.Attestor.ProofChain\\StellaOps.Attestor.ProofChain.csproj" />
<ProjectReference Include="..\\StellaOps.Scanner.Storage.Oci\\StellaOps.Scanner.Storage.Oci.csproj" />
</ItemGroup>
</Project>