81 lines
2.6 KiB
C#
81 lines
2.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.Json;
|
|
|
|
namespace StellaOps.Provenance;
|
|
|
|
public static partial class ProvenanceJsonParser
|
|
{
|
|
private static DsseProvenance ParseDsse(JsonElement root)
|
|
{
|
|
if (!root.TryGetProperty("dsse", out var dsseElement) || dsseElement.ValueKind != JsonValueKind.Object)
|
|
{
|
|
throw new InvalidOperationException("Provenance metadata missing dsse block.");
|
|
}
|
|
|
|
var keyElement = GetRequiredProperty(dsseElement, "key");
|
|
var dsse = new DsseProvenance
|
|
{
|
|
EnvelopeDigest = GetRequiredString(dsseElement, "envelopeDigest"),
|
|
PayloadType = GetRequiredString(dsseElement, "payloadType"),
|
|
Key = new DsseKeyInfo
|
|
{
|
|
KeyId = GetRequiredString(keyElement, "keyId"),
|
|
Issuer = GetOptionalString(keyElement, "issuer"),
|
|
Algo = GetOptionalString(keyElement, "algo"),
|
|
},
|
|
Chain = ParseChain(dsseElement)
|
|
};
|
|
|
|
if (dsseElement.TryGetProperty("rekor", out var rekorElement) && rekorElement.ValueKind == JsonValueKind.Object)
|
|
{
|
|
dsse.Rekor = new DsseRekorInfo
|
|
{
|
|
LogIndex = GetInt64(rekorElement, "logIndex"),
|
|
Uuid = GetRequiredString(rekorElement, "uuid"),
|
|
IntegratedTime = GetOptionalInt64(rekorElement, "integratedTime"),
|
|
MirrorSeq = GetOptionalInt64(rekorElement, "mirrorSeq")
|
|
};
|
|
}
|
|
|
|
return dsse;
|
|
}
|
|
|
|
private static IReadOnlyCollection<DsseChainLink>? ParseChain(JsonElement dsseElement)
|
|
{
|
|
if (!dsseElement.TryGetProperty("chain", out var chainElement)
|
|
|| chainElement.ValueKind != JsonValueKind.Array
|
|
|| chainElement.GetArrayLength() == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var links = new List<DsseChainLink>(chainElement.GetArrayLength());
|
|
foreach (var entry in chainElement.EnumerateArray())
|
|
{
|
|
if (entry.ValueKind != JsonValueKind.Object)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var type = GetOptionalString(entry, "type");
|
|
var id = GetOptionalString(entry, "id");
|
|
var digest = GetOptionalString(entry, "digest");
|
|
|
|
if (string.IsNullOrEmpty(type) || string.IsNullOrEmpty(id) || string.IsNullOrEmpty(digest))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
links.Add(new DsseChainLink
|
|
{
|
|
Type = type,
|
|
Id = id,
|
|
Digest = digest
|
|
});
|
|
}
|
|
|
|
return links.Count == 0 ? null : links;
|
|
}
|
|
}
|