feat: Add CVSS receipt management endpoints and related functionality
- Introduced new API endpoints for creating, retrieving, amending, and listing CVSS receipts. - Updated IPolicyEngineClient interface to include methods for CVSS receipt operations. - Implemented PolicyEngineClient to handle CVSS receipt requests. - Enhanced Program.cs to map new CVSS receipt routes with appropriate authorization. - Added necessary models and contracts for CVSS receipt requests and responses. - Integrated Postgres document store for managing CVSS receipts and related data. - Updated database schema with new migrations for source documents and payload storage. - Refactored existing components to support new CVSS functionality.
This commit is contained in:
@@ -1,118 +1,118 @@
|
||||
using System.Text.Json;
|
||||
using MongoDB.Bson;
|
||||
using StellaOps.Concelier.Models;
|
||||
using StellaOps.Concelier.Connector.Osv.Internal;
|
||||
using StellaOps.Concelier.Storage.Mongo.Documents;
|
||||
using StellaOps.Concelier.Storage.Mongo.Dtos;
|
||||
|
||||
namespace StellaOps.Concelier.Connector.Osv.Tests;
|
||||
|
||||
public sealed class OsvConflictFixtureTests
|
||||
{
|
||||
[Fact]
|
||||
public void ConflictFixture_MatchesSnapshot()
|
||||
{
|
||||
using var databaseSpecificDoc = JsonDocument.Parse("""{"severity":"medium"}""");
|
||||
|
||||
var dto = new OsvVulnerabilityDto
|
||||
{
|
||||
Id = "OSV-2025-4242",
|
||||
Summary = "Container escape for conflict-package",
|
||||
Details = "OSV captures the latest container escape details including patched version metadata.",
|
||||
Aliases = new[] { "CVE-2025-4242", "GHSA-qqqq-wwww-eeee" },
|
||||
Published = new DateTimeOffset(2025, 2, 28, 0, 0, 0, TimeSpan.Zero),
|
||||
Modified = new DateTimeOffset(2025, 3, 6, 12, 0, 0, TimeSpan.Zero),
|
||||
Severity = new[]
|
||||
{
|
||||
new OsvSeverityDto
|
||||
{
|
||||
Type = "CVSS_V3",
|
||||
Score = "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:L"
|
||||
}
|
||||
},
|
||||
References = new[]
|
||||
{
|
||||
new OsvReferenceDto
|
||||
{
|
||||
Type = "ADVISORY",
|
||||
Url = "https://osv.dev/vulnerability/OSV-2025-4242"
|
||||
},
|
||||
new OsvReferenceDto
|
||||
{
|
||||
Type = "FIX",
|
||||
Url = "https://github.com/conflict/package/commit/abcdef1234567890"
|
||||
}
|
||||
},
|
||||
Credits = new[]
|
||||
{
|
||||
new OsvCreditDto
|
||||
{
|
||||
Name = "osv-reporter",
|
||||
Type = "reporter",
|
||||
Contact = new[] { "mailto:osv-reporter@example.com" }
|
||||
}
|
||||
},
|
||||
Affected = new[]
|
||||
{
|
||||
new OsvAffectedPackageDto
|
||||
{
|
||||
Package = new OsvPackageDto
|
||||
{
|
||||
Ecosystem = "npm",
|
||||
Name = "conflict/package"
|
||||
},
|
||||
Ranges = new[]
|
||||
{
|
||||
new OsvRangeDto
|
||||
{
|
||||
Type = "SEMVER",
|
||||
Events = new[]
|
||||
{
|
||||
new OsvEventDto { Introduced = "1.0.0" },
|
||||
new OsvEventDto { LastAffected = "1.4.2" },
|
||||
new OsvEventDto { Fixed = "1.5.0" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
DatabaseSpecific = databaseSpecificDoc.RootElement.Clone()
|
||||
};
|
||||
|
||||
var document = new DocumentRecord(
|
||||
Id: Guid.Parse("8dd2b0fe-a5f5-4b3b-9f5c-0f3aad6fb6ce"),
|
||||
SourceName: OsvConnectorPlugin.SourceName,
|
||||
Uri: "https://api.osv.dev/v1/vulns/OSV-2025-4242",
|
||||
FetchedAt: new DateTimeOffset(2025, 3, 6, 11, 30, 0, TimeSpan.Zero),
|
||||
Sha256: "sha256-osv-conflict-fixture",
|
||||
Status: "completed",
|
||||
ContentType: "application/json",
|
||||
Headers: null,
|
||||
Metadata: null,
|
||||
Etag: "\"etag-osv-conflict\"",
|
||||
LastModified: new DateTimeOffset(2025, 3, 6, 12, 0, 0, TimeSpan.Zero),
|
||||
GridFsId: null);
|
||||
|
||||
var dtoRecord = new DtoRecord(
|
||||
Id: Guid.Parse("6f7d5ce7-cb47-40a5-8b41-8ad022b5fd5c"),
|
||||
DocumentId: document.Id,
|
||||
SourceName: OsvConnectorPlugin.SourceName,
|
||||
SchemaVersion: "osv.v1",
|
||||
Payload: new BsonDocument("id", dto.Id),
|
||||
ValidatedAt: new DateTimeOffset(2025, 3, 6, 12, 5, 0, TimeSpan.Zero));
|
||||
|
||||
var advisory = OsvMapper.Map(dto, document, dtoRecord, "npm");
|
||||
var snapshot = SnapshotSerializer.ToSnapshot(advisory).Replace("\r\n", "\n").TrimEnd();
|
||||
|
||||
var expectedPath = Path.Combine(AppContext.BaseDirectory, "Fixtures", "conflict-osv.canonical.json");
|
||||
var expected = File.ReadAllText(expectedPath).Replace("\r\n", "\n").TrimEnd();
|
||||
|
||||
if (!string.Equals(expected, snapshot, StringComparison.Ordinal))
|
||||
{
|
||||
var actualPath = Path.Combine(AppContext.BaseDirectory, "Fixtures", "conflict-osv.canonical.actual.json");
|
||||
File.WriteAllText(actualPath, snapshot);
|
||||
}
|
||||
|
||||
Assert.Equal(expected, snapshot);
|
||||
}
|
||||
}
|
||||
using System.Text.Json;
|
||||
using MongoDB.Bson;
|
||||
using StellaOps.Concelier.Models;
|
||||
using StellaOps.Concelier.Connector.Osv.Internal;
|
||||
using StellaOps.Concelier.Storage.Mongo.Documents;
|
||||
using StellaOps.Concelier.Storage.Mongo.Dtos;
|
||||
|
||||
namespace StellaOps.Concelier.Connector.Osv.Tests;
|
||||
|
||||
public sealed class OsvConflictFixtureTests
|
||||
{
|
||||
[Fact]
|
||||
public void ConflictFixture_MatchesSnapshot()
|
||||
{
|
||||
using var databaseSpecificDoc = JsonDocument.Parse("""{"severity":"medium"}""");
|
||||
|
||||
var dto = new OsvVulnerabilityDto
|
||||
{
|
||||
Id = "OSV-2025-4242",
|
||||
Summary = "Container escape for conflict-package",
|
||||
Details = "OSV captures the latest container escape details including patched version metadata.",
|
||||
Aliases = new[] { "CVE-2025-4242", "GHSA-qqqq-wwww-eeee" },
|
||||
Published = new DateTimeOffset(2025, 2, 28, 0, 0, 0, TimeSpan.Zero),
|
||||
Modified = new DateTimeOffset(2025, 3, 6, 12, 0, 0, TimeSpan.Zero),
|
||||
Severity = new[]
|
||||
{
|
||||
new OsvSeverityDto
|
||||
{
|
||||
Type = "CVSS_V3",
|
||||
Score = "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:L"
|
||||
}
|
||||
},
|
||||
References = new[]
|
||||
{
|
||||
new OsvReferenceDto
|
||||
{
|
||||
Type = "ADVISORY",
|
||||
Url = "https://osv.dev/vulnerability/OSV-2025-4242"
|
||||
},
|
||||
new OsvReferenceDto
|
||||
{
|
||||
Type = "FIX",
|
||||
Url = "https://github.com/conflict/package/commit/abcdef1234567890"
|
||||
}
|
||||
},
|
||||
Credits = new[]
|
||||
{
|
||||
new OsvCreditDto
|
||||
{
|
||||
Name = "osv-reporter",
|
||||
Type = "reporter",
|
||||
Contact = new[] { "mailto:osv-reporter@example.com" }
|
||||
}
|
||||
},
|
||||
Affected = new[]
|
||||
{
|
||||
new OsvAffectedPackageDto
|
||||
{
|
||||
Package = new OsvPackageDto
|
||||
{
|
||||
Ecosystem = "npm",
|
||||
Name = "conflict/package"
|
||||
},
|
||||
Ranges = new[]
|
||||
{
|
||||
new OsvRangeDto
|
||||
{
|
||||
Type = "SEMVER",
|
||||
Events = new[]
|
||||
{
|
||||
new OsvEventDto { Introduced = "1.0.0" },
|
||||
new OsvEventDto { LastAffected = "1.4.2" },
|
||||
new OsvEventDto { Fixed = "1.5.0" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
DatabaseSpecific = databaseSpecificDoc.RootElement.Clone()
|
||||
};
|
||||
|
||||
var document = new DocumentRecord(
|
||||
Id: Guid.Parse("8dd2b0fe-a5f5-4b3b-9f5c-0f3aad6fb6ce"),
|
||||
SourceName: OsvConnectorPlugin.SourceName,
|
||||
Uri: "https://api.osv.dev/v1/vulns/OSV-2025-4242",
|
||||
FetchedAt: new DateTimeOffset(2025, 3, 6, 11, 30, 0, TimeSpan.Zero),
|
||||
Sha256: "sha256-osv-conflict-fixture",
|
||||
Status: "completed",
|
||||
ContentType: "application/json",
|
||||
Headers: null,
|
||||
Metadata: null,
|
||||
Etag: "\"etag-osv-conflict\"",
|
||||
LastModified: new DateTimeOffset(2025, 3, 6, 12, 0, 0, TimeSpan.Zero),
|
||||
PayloadId: null);
|
||||
|
||||
var dtoRecord = new DtoRecord(
|
||||
Id: Guid.Parse("6f7d5ce7-cb47-40a5-8b41-8ad022b5fd5c"),
|
||||
DocumentId: document.Id,
|
||||
SourceName: OsvConnectorPlugin.SourceName,
|
||||
SchemaVersion: "osv.v1",
|
||||
Payload: new BsonDocument("id", dto.Id),
|
||||
ValidatedAt: new DateTimeOffset(2025, 3, 6, 12, 5, 0, TimeSpan.Zero));
|
||||
|
||||
var advisory = OsvMapper.Map(dto, document, dtoRecord, "npm");
|
||||
var snapshot = SnapshotSerializer.ToSnapshot(advisory).Replace("\r\n", "\n").TrimEnd();
|
||||
|
||||
var expectedPath = Path.Combine(AppContext.BaseDirectory, "Fixtures", "conflict-osv.canonical.json");
|
||||
var expected = File.ReadAllText(expectedPath).Replace("\r\n", "\n").TrimEnd();
|
||||
|
||||
if (!string.Equals(expected, snapshot, StringComparison.Ordinal))
|
||||
{
|
||||
var actualPath = Path.Combine(AppContext.BaseDirectory, "Fixtures", "conflict-osv.canonical.actual.json");
|
||||
File.WriteAllText(actualPath, snapshot);
|
||||
}
|
||||
|
||||
Assert.Equal(expected, snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user