using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; namespace StellaOps.Excititor.Core; public sealed record VexQuietProvenance { public VexQuietProvenance(string vulnerabilityId, string productKey, IEnumerable statements) { if (string.IsNullOrWhiteSpace(vulnerabilityId)) { throw new ArgumentException("Vulnerability id must be provided.", nameof(vulnerabilityId)); } if (string.IsNullOrWhiteSpace(productKey)) { throw new ArgumentException("Product key must be provided.", nameof(productKey)); } VulnerabilityId = vulnerabilityId.Trim(); ProductKey = productKey.Trim(); Statements = NormalizeStatements(statements); } public string VulnerabilityId { get; } public string ProductKey { get; } public ImmutableArray Statements { get; } private static ImmutableArray NormalizeStatements(IEnumerable statements) { if (statements is null) { throw new ArgumentNullException(nameof(statements)); } return statements .OrderBy(static s => s.ProviderId, StringComparer.Ordinal) .ThenBy(static s => s.StatementId, StringComparer.Ordinal) .ToImmutableArray(); } } public sealed record VexQuietStatement { public VexQuietStatement( string providerId, string statementId, VexJustification? justification, VexSignatureMetadata? signature) { if (string.IsNullOrWhiteSpace(providerId)) { throw new ArgumentException("Provider id must be provided.", nameof(providerId)); } if (string.IsNullOrWhiteSpace(statementId)) { throw new ArgumentException("Statement id must be provided.", nameof(statementId)); } ProviderId = providerId.Trim(); StatementId = statementId.Trim(); Justification = justification; Signature = signature; } public string ProviderId { get; } public string StatementId { get; } public VexJustification? Justification { get; } public VexSignatureMetadata? Signature { get; } }