Gaps fill up, fixes, ui restructuring

This commit is contained in:
master
2026-02-19 22:10:54 +02:00
parent b5829dce5c
commit 04cacdca8a
331 changed files with 42859 additions and 2174 deletions

View File

@@ -0,0 +1,106 @@
using System.Collections.Concurrent;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
namespace StellaOps.Telemetry.Federation.Consent;
public sealed class ConsentManager : IConsentManager
{
private readonly ConcurrentDictionary<string, ConsentEntry> _consents = new();
private readonly TimeProvider _timeProvider;
public ConsentManager(TimeProvider? timeProvider = null)
{
_timeProvider = timeProvider ?? TimeProvider.System;
}
public Task<ConsentState> GetConsentStateAsync(string tenantId, CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
if (!_consents.TryGetValue(tenantId, out var entry))
{
return Task.FromResult(new ConsentState(
Granted: false,
GrantedBy: null,
GrantedAt: null,
ExpiresAt: null,
DsseDigest: null));
}
var now = _timeProvider.GetUtcNow();
if (entry.ExpiresAt.HasValue && now >= entry.ExpiresAt.Value)
{
_consents.TryRemove(tenantId, out _);
return Task.FromResult(new ConsentState(
Granted: false,
GrantedBy: null,
GrantedAt: null,
ExpiresAt: null,
DsseDigest: null));
}
return Task.FromResult(new ConsentState(
Granted: true,
GrantedBy: entry.GrantedBy,
GrantedAt: entry.GrantedAt,
ExpiresAt: entry.ExpiresAt,
DsseDigest: entry.DsseDigest));
}
public Task<ConsentProof> GrantConsentAsync(
string tenantId,
string grantedBy,
TimeSpan? ttl = null,
CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
var now = _timeProvider.GetUtcNow();
var expiresAt = ttl.HasValue ? now + ttl.Value : (DateTimeOffset?)null;
var payload = JsonSerializer.SerializeToUtf8Bytes(new
{
tenantId,
grantedBy,
grantedAt = now,
expiresAt,
type = "stella.ops/federatedConsent@v1"
});
var digest = ComputeDigest(payload);
var envelope = payload; // Placeholder: real DSSE envelope wraps with signature
var entry = new ConsentEntry(tenantId, grantedBy, now, expiresAt, digest);
_consents[tenantId] = entry;
return Task.FromResult(new ConsentProof(
TenantId: tenantId,
GrantedBy: grantedBy,
GrantedAt: now,
ExpiresAt: expiresAt,
DsseDigest: digest,
Envelope: envelope));
}
public Task RevokeConsentAsync(string tenantId, string revokedBy, CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
_consents.TryRemove(tenantId, out _);
return Task.CompletedTask;
}
private static string ComputeDigest(byte[] payload)
{
var hash = SHA256.HashData(payload);
return $"sha256:{Convert.ToHexStringLower(hash)}";
}
private sealed record ConsentEntry(
string TenantId,
string GrantedBy,
DateTimeOffset GrantedAt,
DateTimeOffset? ExpiresAt,
string DsseDigest);
}

View File

@@ -0,0 +1,23 @@
namespace StellaOps.Telemetry.Federation.Consent;
public interface IConsentManager
{
Task<ConsentState> GetConsentStateAsync(string tenantId, CancellationToken ct = default);
Task<ConsentProof> GrantConsentAsync(string tenantId, string grantedBy, TimeSpan? ttl = null, CancellationToken ct = default);
Task RevokeConsentAsync(string tenantId, string revokedBy, CancellationToken ct = default);
}
public sealed record ConsentState(
bool Granted,
string? GrantedBy,
DateTimeOffset? GrantedAt,
DateTimeOffset? ExpiresAt,
string? DsseDigest);
public sealed record ConsentProof(
string TenantId,
string GrantedBy,
DateTimeOffset GrantedAt,
DateTimeOffset? ExpiresAt,
string DsseDigest,
byte[] Envelope);