feat: Add MongoIdempotencyStoreOptions for MongoDB configuration
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
feat: Implement BsonJsonConverter for converting BsonDocument and BsonArray to JSON fix: Update project file to include MongoDB.Bson package test: Add GraphOverlayExporterTests to validate NDJSON export functionality refactor: Refactor Program.cs in Attestation Tool for improved argument parsing and error handling docs: Update README for stella-forensic-verify with usage instructions and exit codes feat: Enhance HmacVerifier with clock skew and not-after checks feat: Add MerkleRootVerifier and ChainOfCustodyVerifier for additional verification methods fix: Update DenoRuntimeShim to correctly handle file paths feat: Introduce ComposerAutoloadData and related parsing in ComposerLockReader test: Add tests for Deno runtime execution and verification test: Enhance PHP package tests to include autoload data verification test: Add unit tests for HmacVerifier and verification logic
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Excititor.Core.Observations;
|
||||
|
||||
/// <summary>
|
||||
/// Minimal observation reference used in linkset updates while preserving Aggregation-Only semantics.
|
||||
/// </summary>
|
||||
public sealed record VexLinksetObservationRefCore(
|
||||
string ObservationId,
|
||||
string ProviderId,
|
||||
string Status,
|
||||
double? Confidence,
|
||||
ImmutableDictionary<string, string> Attributes)
|
||||
{
|
||||
public static VexLinksetObservationRefCore Create(
|
||||
string observationId,
|
||||
string providerId,
|
||||
string status,
|
||||
double? confidence,
|
||||
ImmutableDictionary<string, string>? attributes = null)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(observationId);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(providerId);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(status);
|
||||
|
||||
return new VexLinksetObservationRefCore(
|
||||
observationId.Trim(),
|
||||
providerId.Trim(),
|
||||
status.Trim(),
|
||||
confidence,
|
||||
attributes ?? ImmutableDictionary<string, string>.Empty);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,13 @@ using System.Linq;
|
||||
|
||||
namespace StellaOps.Excititor.Core.Observations;
|
||||
|
||||
public sealed record VexLinksetObservationRefCore(
|
||||
string ObservationId,
|
||||
string ProviderId,
|
||||
string Status,
|
||||
double? Confidence,
|
||||
ImmutableDictionary<string, string> Attributes);
|
||||
|
||||
public static class VexLinksetUpdatedEventFactory
|
||||
{
|
||||
public const string EventType = "vex.linkset.updated";
|
||||
@@ -26,10 +33,11 @@ public static class VexLinksetUpdatedEventFactory
|
||||
var observationRefs = (observations ?? Enumerable.Empty<VexObservation>())
|
||||
.Where(obs => obs is not null)
|
||||
.SelectMany(obs => obs.Statements.Select(statement => new VexLinksetObservationRefCore(
|
||||
observationId: obs.ObservationId,
|
||||
providerId: obs.ProviderId,
|
||||
status: statement.Status.ToString().ToLowerInvariant(),
|
||||
confidence: statement.Signals?.Severity?.Score)))
|
||||
ObservationId: obs.ObservationId,
|
||||
ProviderId: obs.ProviderId,
|
||||
Status: statement.Status.ToString().ToLowerInvariant(),
|
||||
Confidence: null,
|
||||
Attributes: obs.Attributes)))
|
||||
.Distinct(VexLinksetObservationRefComparer.Instance)
|
||||
.OrderBy(refItem => refItem.ProviderId, StringComparer.OrdinalIgnoreCase)
|
||||
.ThenBy(refItem => refItem.ObservationId, StringComparer.Ordinal)
|
||||
|
||||
@@ -491,7 +491,7 @@ public sealed record VexObservationLinkset
|
||||
}
|
||||
|
||||
var normalizedJustification = VexObservation.TrimToNull(disagreement.Justification);
|
||||
var clampedConfidence = disagreement.Confidence is null
|
||||
double? clampedConfidence = disagreement.Confidence is null
|
||||
? null
|
||||
: Math.Clamp(disagreement.Confidence.Value, 0.0, 1.0);
|
||||
|
||||
@@ -529,7 +529,7 @@ public sealed record VexObservationLinkset
|
||||
continue;
|
||||
}
|
||||
|
||||
var clamped = item.Confidence is null ? null : Math.Clamp(item.Confidence.Value, 0.0, 1.0);
|
||||
double? clamped = item.Confidence is null ? null : Math.Clamp(item.Confidence.Value, 0.0, 1.0);
|
||||
set.Add(new VexLinksetObservationRefModel(obsId, provider, status, clamped));
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ internal sealed class MongoVexObservationLookup : IVexObservationLookup
|
||||
if (cursor is not null)
|
||||
{
|
||||
var cursorFilter = Builders<VexObservationRecord>.Filter.Or(
|
||||
Builders<VexObservationRecord>.Filter.Lt(r => r.CreatedAt, cursor.CreatedAtUtc.UtcDateTime),
|
||||
Builders<VexObservationRecord>.Filter.Lt(r => r.CreatedAt, cursor.CreatedAt.UtcDateTime),
|
||||
Builders<VexObservationRecord>.Filter.And(
|
||||
Builders<VexObservationRecord>.Filter.Eq(r => r.CreatedAt, cursor.CreatedAtUtc.UtcDateTime),
|
||||
Builders<VexObservationRecord>.Filter.Eq(r => r.CreatedAt, cursor.CreatedAt.UtcDateTime),
|
||||
Builders<VexObservationRecord>.Filter.Lt(r => r.ObservationId, cursor.ObservationId)));
|
||||
filters.Add(cursorFilter);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ internal sealed class MongoVexObservationLookup : IVexObservationLookup
|
||||
record.Upstream.Signature.Present,
|
||||
record.Upstream.Signature.Subject,
|
||||
record.Upstream.Signature.Issuer,
|
||||
record.Upstream.Signature.VerifiedAt);
|
||||
signature: null);
|
||||
|
||||
var upstream = record.Upstream is null
|
||||
? new VexObservationUpstream(
|
||||
@@ -141,7 +141,7 @@ internal sealed class MongoVexObservationLookup : IVexObservationLookup
|
||||
record.Document.Signature.Present,
|
||||
record.Document.Signature.Subject,
|
||||
record.Document.Signature.Issuer,
|
||||
record.Document.Signature.VerifiedAt);
|
||||
signature: null);
|
||||
|
||||
var content = record.Content is null
|
||||
? new VexObservationContent("unknown", null, new JsonObject())
|
||||
@@ -182,17 +182,10 @@ internal sealed class MongoVexObservationLookup : IVexObservationLookup
|
||||
justification: justification,
|
||||
introducedVersion: record.IntroducedVersion,
|
||||
fixedVersion: record.FixedVersion,
|
||||
detail: record.Detail,
|
||||
signals: new VexSignalSnapshot(
|
||||
severity: record.ScopeScore.HasValue ? new VexSeveritySignal("scope", record.ScopeScore, "n/a", null) : null,
|
||||
Kev: record.Kev,
|
||||
Epss: record.Epss),
|
||||
confidence: null,
|
||||
metadata: ImmutableDictionary<string, string>.Empty,
|
||||
purl: null,
|
||||
cpe: null,
|
||||
evidence: null,
|
||||
anchors: VexObservationAnchors.Empty,
|
||||
additionalMetadata: ImmutableDictionary<string, string>.Empty,
|
||||
signature: null);
|
||||
metadata: ImmutableDictionary<string, string>.Empty);
|
||||
}
|
||||
|
||||
private static VexObservationDisagreement MapDisagreement(VexLinksetDisagreementRecord record)
|
||||
@@ -206,11 +199,11 @@ internal sealed class MongoVexObservationLookup : IVexObservationLookup
|
||||
var references = record?.References?.Select(r => new VexObservationReference(r.Type, r.Url)).ToImmutableArray() ?? ImmutableArray<VexObservationReference>.Empty;
|
||||
var reconciledFrom = record?.ReconciledFrom?.Where(NotNullOrWhiteSpace).Select(r => r.Trim()).ToImmutableArray() ?? ImmutableArray<string>.Empty;
|
||||
var disagreements = record?.Disagreements?.Select(MapDisagreement).ToImmutableArray() ?? ImmutableArray<VexObservationDisagreement>.Empty;
|
||||
var observationRefs = record?.Observations?.Select(o => new VexLinksetObservationRef(
|
||||
var observationRefs = record?.Observations?.Select(o => new VexLinksetObservationRefModel(
|
||||
o.ObservationId,
|
||||
o.ProviderId,
|
||||
o.Status,
|
||||
o.Confidence)).ToImmutableArray() ?? ImmutableArray<VexLinksetObservationRef>.Empty;
|
||||
o.Confidence)).ToImmutableArray() ?? ImmutableArray<VexLinksetObservationRefModel>.Empty;
|
||||
|
||||
return new VexObservationLinkset(aliases, purls, cpes, references, reconciledFrom, disagreements, observationRefs);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using StellaOps.Excititor.Core;
|
||||
using StellaOps.Excititor.Storage.Mongo.Migrations;
|
||||
using StellaOps.Excititor.Storage.Mongo.Migrations;
|
||||
using StellaOps.Excititor.Core.Observations;
|
||||
|
||||
namespace StellaOps.Excititor.Storage.Mongo;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user