Initial commit (history squashed)
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Build Test Deploy / authority-container (push) Has been cancelled
				
			
		
			
				
	
				Build Test Deploy / docs (push) Has been cancelled
				
			
		
			
				
	
				Build Test Deploy / deploy (push) Has been cancelled
				
			
		
			
				
	
				Build Test Deploy / build-test (push) Has been cancelled
				
			
		
			
				
	
				Docs CI / lint-and-preview (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Build Test Deploy / authority-container (push) Has been cancelled
				
			Build Test Deploy / docs (push) Has been cancelled
				
			Build Test Deploy / deploy (push) Has been cancelled
				
			Build Test Deploy / build-test (push) Has been cancelled
				
			Docs CI / lint-and-preview (push) Has been cancelled
				
			This commit is contained in:
		
							
								
								
									
										19
									
								
								tools/FixtureUpdater/FixtureUpdater.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tools/FixtureUpdater/FixtureUpdater.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <OutputType>Exe</OutputType> | ||||
|     <TargetFramework>net10.0</TargetFramework> | ||||
|     <ImplicitUsings>enable</ImplicitUsings> | ||||
|     <Nullable>enable</Nullable> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="../../src/StellaOps.Feedser.Source.Osv/StellaOps.Feedser.Source.Osv.csproj" /> | ||||
|     <ProjectReference Include="../../src/StellaOps.Feedser.Source.Ghsa/StellaOps.Feedser.Source.Ghsa.csproj" /> | ||||
|     <ProjectReference Include="../../src/StellaOps.Feedser.Source.Common/StellaOps.Feedser.Source.Common.csproj" /> | ||||
|     <ProjectReference Include="../../src/StellaOps.Feedser.Storage.Mongo/StellaOps.Feedser.Storage.Mongo.csproj" /> | ||||
|     <ProjectReference Include="../../src/StellaOps.Feedser.Models/StellaOps.Feedser.Models.csproj" /> | ||||
|     <ProjectReference Include="../../src/StellaOps.Feedser.Testing/StellaOps.Feedser.Testing.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
							
								
								
									
										231
									
								
								tools/FixtureUpdater/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								tools/FixtureUpdater/Program.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,231 @@ | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
| using MongoDB.Bson; | ||||
| using StellaOps.Feedser.Models; | ||||
| using StellaOps.Feedser.Source.Ghsa; | ||||
| using StellaOps.Feedser.Source.Common; | ||||
| using StellaOps.Feedser.Source.Ghsa.Internal; | ||||
| using StellaOps.Feedser.Source.Osv.Internal; | ||||
| using StellaOps.Feedser.Source.Osv; | ||||
| using StellaOps.Feedser.Storage.Mongo.Documents; | ||||
| using StellaOps.Feedser.Storage.Mongo.Dtos; | ||||
|  | ||||
| var serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web) | ||||
| { | ||||
|     DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, | ||||
| }; | ||||
|  | ||||
| var projectRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "..")); | ||||
|  | ||||
| var fixturesPath = Path.Combine(projectRoot, "src", "StellaOps.Feedser.Source.Osv.Tests", "Fixtures"); | ||||
|  | ||||
| RewriteOsvFixtures(fixturesPath); | ||||
| RewriteSnapshotFixtures(fixturesPath); | ||||
| RewriteGhsaFixtures(fixturesPath); | ||||
| return; | ||||
|  | ||||
| void RewriteOsvFixtures(string fixturesPath) | ||||
| { | ||||
|     var rawPath = Path.Combine(fixturesPath, "osv-ghsa.raw-osv.json"); | ||||
|     if (!File.Exists(rawPath)) | ||||
|     { | ||||
|         Console.WriteLine($"[FixtureUpdater] OSV raw fixture missing: {rawPath}"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     using var document = JsonDocument.Parse(File.ReadAllText(rawPath)); | ||||
|     var advisories = new List<Advisory>(); | ||||
|     foreach (var element in document.RootElement.EnumerateArray()) | ||||
|     { | ||||
|         var dto = JsonSerializer.Deserialize<OsvVulnerabilityDto>(element.GetRawText(), serializerOptions); | ||||
|         if (dto is null) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         var ecosystem = dto.Affected?.FirstOrDefault()?.Package?.Ecosystem ?? "unknown"; | ||||
|         var uri = new Uri($"https://osv.dev/vulnerability/{dto.Id}"); | ||||
|         var documentRecord = new DocumentRecord( | ||||
|             Guid.NewGuid(), | ||||
|             OsvConnectorPlugin.SourceName, | ||||
|             uri.ToString(), | ||||
|             DateTimeOffset.UtcNow, | ||||
|             "fixture-sha", | ||||
|             DocumentStatuses.PendingMap, | ||||
|             "application/json", | ||||
|             null, | ||||
|             new Dictionary<string, string>(StringComparer.Ordinal) | ||||
|             { | ||||
|                 ["osv.ecosystem"] = ecosystem, | ||||
|             }, | ||||
|             null, | ||||
|             DateTimeOffset.UtcNow, | ||||
|             null, | ||||
|             null); | ||||
|  | ||||
|         var payload = BsonDocument.Parse(element.GetRawText()); | ||||
|         var dtoRecord = new DtoRecord( | ||||
|             Guid.NewGuid(), | ||||
|             documentRecord.Id, | ||||
|             OsvConnectorPlugin.SourceName, | ||||
|             "osv.v1", | ||||
|             payload, | ||||
|             DateTimeOffset.UtcNow); | ||||
|  | ||||
|         var advisory = OsvMapper.Map(dto, documentRecord, dtoRecord, ecosystem); | ||||
|         advisories.Add(advisory); | ||||
|     } | ||||
|  | ||||
|     advisories.Sort((left, right) => string.Compare(left.AdvisoryKey, right.AdvisoryKey, StringComparison.Ordinal)); | ||||
|     var snapshot = SnapshotSerializer.ToSnapshot(advisories); | ||||
|     File.WriteAllText(Path.Combine(fixturesPath, "osv-ghsa.osv.json"), snapshot); | ||||
|     Console.WriteLine($"[FixtureUpdater] Updated {Path.Combine(fixturesPath, "osv-ghsa.osv.json")}"); | ||||
| } | ||||
|  | ||||
| void RewriteSnapshotFixtures(string fixturesPath) | ||||
| { | ||||
|     var baselinePublished = new DateTimeOffset(2025, 1, 5, 12, 0, 0, TimeSpan.Zero); | ||||
|     var baselineModified = new DateTimeOffset(2025, 1, 8, 6, 30, 0, TimeSpan.Zero); | ||||
|     var baselineFetched = new DateTimeOffset(2025, 1, 8, 7, 0, 0, TimeSpan.Zero); | ||||
|  | ||||
|     var cases = new (string Ecosystem, string Purl, string PackageName, string SnapshotFile)[] | ||||
|     { | ||||
|         ("npm", "pkg:npm/%40scope%2Fleft-pad", "@scope/left-pad", "osv-npm.snapshot.json"), | ||||
|         ("PyPI", "pkg:pypi/requests", "requests", "osv-pypi.snapshot.json"), | ||||
|     }; | ||||
|  | ||||
|     foreach (var (ecosystem, purl, packageName, snapshotFile) in cases) | ||||
|     { | ||||
|         var dto = new OsvVulnerabilityDto | ||||
|         { | ||||
|             Id = $"OSV-2025-{ecosystem}-0001", | ||||
|             Summary = $"{ecosystem} package vulnerability", | ||||
|             Details = $"Detailed description for {ecosystem} package {packageName}.", | ||||
|             Published = baselinePublished, | ||||
|             Modified = baselineModified, | ||||
|             Aliases = new[] { $"CVE-2025-11{ecosystem.Length}", $"GHSA-{ecosystem.Length}abc-{ecosystem.Length}def-{ecosystem.Length}ghi" }, | ||||
|             Related = new[] { $"OSV-RELATED-{ecosystem}-42" }, | ||||
|             References = new[] | ||||
|             { | ||||
|                 new OsvReferenceDto { Url = $"https://example.com/{ecosystem}/advisory", Type = "ADVISORY" }, | ||||
|                 new OsvReferenceDto { Url = $"https://example.com/{ecosystem}/fix", Type = "FIX" }, | ||||
|             }, | ||||
|             Severity = new[] | ||||
|             { | ||||
|                 new OsvSeverityDto { Type = "CVSS_V3", Score = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, | ||||
|             }, | ||||
|             Affected = new[] | ||||
|             { | ||||
|                 new OsvAffectedPackageDto | ||||
|                 { | ||||
|                     Package = new OsvPackageDto | ||||
|                     { | ||||
|                         Ecosystem = ecosystem, | ||||
|                         Name = packageName, | ||||
|                         Purl = purl, | ||||
|                     }, | ||||
|                     Ranges = new[] | ||||
|                     { | ||||
|                         new OsvRangeDto | ||||
|                         { | ||||
|                             Type = "SEMVER", | ||||
|                             Events = new[] | ||||
|                             { | ||||
|                                 new OsvEventDto { Introduced = "0" }, | ||||
|                                 new OsvEventDto { Fixed = "2.0.0" }, | ||||
|                             }, | ||||
|                         }, | ||||
|                     }, | ||||
|                     Versions = new[] { "1.0.0", "1.5.0" }, | ||||
|                     EcosystemSpecific = JsonDocument.Parse("{\"severity\":\"high\"}").RootElement.Clone(), | ||||
|                 }, | ||||
|             }, | ||||
|             DatabaseSpecific = JsonDocument.Parse("{\"source\":\"osv.dev\"}").RootElement.Clone(), | ||||
|         }; | ||||
|  | ||||
|         var document = new DocumentRecord( | ||||
|             Guid.NewGuid(), | ||||
|             OsvConnectorPlugin.SourceName, | ||||
|             $"https://osv.dev/vulnerability/{dto.Id}", | ||||
|             baselineFetched, | ||||
|             "fixture-sha", | ||||
|             DocumentStatuses.PendingParse, | ||||
|             "application/json", | ||||
|             null, | ||||
|             new Dictionary<string, string>(StringComparer.Ordinal) { ["osv.ecosystem"] = ecosystem }, | ||||
|             null, | ||||
|             baselineModified, | ||||
|             null); | ||||
|  | ||||
|         var payload = BsonDocument.Parse(JsonSerializer.Serialize(dto, serializerOptions)); | ||||
|         var dtoRecord = new DtoRecord(Guid.NewGuid(), document.Id, OsvConnectorPlugin.SourceName, "osv.v1", payload, baselineModified); | ||||
|  | ||||
|         var advisory = OsvMapper.Map(dto, document, dtoRecord, ecosystem); | ||||
|         var snapshot = SnapshotSerializer.ToSnapshot(advisory); | ||||
|         File.WriteAllText(Path.Combine(fixturesPath, snapshotFile), snapshot); | ||||
|         Console.WriteLine($"[FixtureUpdater] Updated {Path.Combine(fixturesPath, snapshotFile)}"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void RewriteGhsaFixtures(string fixturesPath) | ||||
| { | ||||
|     var rawPath = Path.Combine(fixturesPath, "osv-ghsa.raw-ghsa.json"); | ||||
|     if (!File.Exists(rawPath)) | ||||
|     { | ||||
|         Console.WriteLine($"[FixtureUpdater] GHSA raw fixture missing: {rawPath}"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     JsonDocument document; | ||||
|     try | ||||
|     { | ||||
|         document = JsonDocument.Parse(File.ReadAllText(rawPath)); | ||||
|     } | ||||
|     catch (JsonException ex) | ||||
|     { | ||||
|         Console.WriteLine($"[FixtureUpdater] Failed to parse GHSA raw fixture '{rawPath}': {ex.Message}"); | ||||
|         return; | ||||
|     } | ||||
|     using (document) | ||||
|     { | ||||
|     var advisories = new List<Advisory>(); | ||||
|     foreach (var element in document.RootElement.EnumerateArray()) | ||||
|     { | ||||
|         GhsaRecordDto dto; | ||||
|         try | ||||
|         { | ||||
|             dto = GhsaRecordParser.Parse(Encoding.UTF8.GetBytes(element.GetRawText())); | ||||
|         } | ||||
|         catch (JsonException) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         var uri = new Uri($"https://github.com/advisories/{dto.GhsaId}"); | ||||
|         var documentRecord = new DocumentRecord( | ||||
|             Guid.NewGuid(), | ||||
|             GhsaConnectorPlugin.SourceName, | ||||
|             uri.ToString(), | ||||
|             DateTimeOffset.UtcNow, | ||||
|             "fixture-sha", | ||||
|             DocumentStatuses.PendingMap, | ||||
|             "application/json", | ||||
|             null, | ||||
|             new Dictionary<string, string>(StringComparer.Ordinal), | ||||
|             null, | ||||
|             DateTimeOffset.UtcNow, | ||||
|             null, | ||||
|             null); | ||||
|  | ||||
|         var advisory = GhsaMapper.Map(dto, documentRecord, DateTimeOffset.UtcNow); | ||||
|         advisories.Add(advisory); | ||||
|     } | ||||
|  | ||||
|         advisories.Sort((left, right) => string.Compare(left.AdvisoryKey, right.AdvisoryKey, StringComparison.Ordinal)); | ||||
|         var snapshot = SnapshotSerializer.ToSnapshot(advisories); | ||||
|         File.WriteAllText(Path.Combine(fixturesPath, "osv-ghsa.ghsa.json"), snapshot); | ||||
|         Console.WriteLine($"[FixtureUpdater] Updated {Path.Combine(fixturesPath, "osv-ghsa.ghsa.json")}"); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user