up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
This commit is contained in:
@@ -3,118 +3,118 @@ using System.Globalization;
|
||||
using System.Text;
|
||||
using StellaOps.Scheduler.Models;
|
||||
using StellaOps.Scheduler.Storage.Postgres.Repositories;
|
||||
|
||||
namespace StellaOps.Scheduler.WebService;
|
||||
|
||||
internal static class SchedulerEndpointHelpers
|
||||
{
|
||||
private const string ActorHeader = "X-Actor-Id";
|
||||
private const string ActorNameHeader = "X-Actor-Name";
|
||||
private const string ActorKindHeader = "X-Actor-Kind";
|
||||
private const string TenantHeader = "X-Tenant-Id";
|
||||
|
||||
public static string GenerateIdentifier(string prefix)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(prefix))
|
||||
{
|
||||
throw new ArgumentException("Prefix must be provided.", nameof(prefix));
|
||||
}
|
||||
|
||||
return $"{prefix.Trim()}_{Guid.NewGuid():N}";
|
||||
}
|
||||
|
||||
public static string ResolveActorId(HttpContext context)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
|
||||
if (context.Request.Headers.TryGetValue(ActorHeader, out var values))
|
||||
{
|
||||
var actor = values.ToString().Trim();
|
||||
if (!string.IsNullOrEmpty(actor))
|
||||
{
|
||||
return actor;
|
||||
}
|
||||
}
|
||||
|
||||
if (context.Request.Headers.TryGetValue(TenantHeader, out var tenant))
|
||||
{
|
||||
var tenantId = tenant.ToString().Trim();
|
||||
if (!string.IsNullOrEmpty(tenantId))
|
||||
{
|
||||
return tenantId;
|
||||
}
|
||||
}
|
||||
|
||||
return "system";
|
||||
}
|
||||
|
||||
public static AuditActor ResolveAuditActor(HttpContext context)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
|
||||
var actorId = context.Request.Headers.TryGetValue(ActorHeader, out var idHeader)
|
||||
? idHeader.ToString().Trim()
|
||||
: null;
|
||||
|
||||
var displayName = context.Request.Headers.TryGetValue(ActorNameHeader, out var nameHeader)
|
||||
? nameHeader.ToString().Trim()
|
||||
: null;
|
||||
|
||||
var kind = context.Request.Headers.TryGetValue(ActorKindHeader, out var kindHeader)
|
||||
? kindHeader.ToString().Trim()
|
||||
: null;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(actorId))
|
||||
{
|
||||
actorId = context.Request.Headers.TryGetValue(TenantHeader, out var tenantHeader)
|
||||
? tenantHeader.ToString().Trim()
|
||||
: "system";
|
||||
}
|
||||
|
||||
displayName = string.IsNullOrWhiteSpace(displayName) ? actorId : displayName;
|
||||
kind = string.IsNullOrWhiteSpace(kind) ? "user" : kind;
|
||||
|
||||
return new AuditActor(actorId!, displayName!, kind!);
|
||||
}
|
||||
|
||||
public static bool TryParseBoolean(string? value)
|
||||
=> !string.IsNullOrWhiteSpace(value) &&
|
||||
(string.Equals(value, "true", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(value, "1", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
public static int? TryParsePositiveInt(string? value)
|
||||
{
|
||||
if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed) && parsed > 0)
|
||||
{
|
||||
return parsed;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
namespace StellaOps.Scheduler.WebService;
|
||||
|
||||
internal static class SchedulerEndpointHelpers
|
||||
{
|
||||
private const string ActorHeader = "X-Actor-Id";
|
||||
private const string ActorNameHeader = "X-Actor-Name";
|
||||
private const string ActorKindHeader = "X-Actor-Kind";
|
||||
private const string TenantHeader = "X-Tenant-Id";
|
||||
|
||||
public static string GenerateIdentifier(string prefix)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(prefix))
|
||||
{
|
||||
throw new ArgumentException("Prefix must be provided.", nameof(prefix));
|
||||
}
|
||||
|
||||
return $"{prefix.Trim()}_{Guid.NewGuid():N}";
|
||||
}
|
||||
|
||||
public static string ResolveActorId(HttpContext context)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
|
||||
if (context.Request.Headers.TryGetValue(ActorHeader, out var values))
|
||||
{
|
||||
var actor = values.ToString().Trim();
|
||||
if (!string.IsNullOrEmpty(actor))
|
||||
{
|
||||
return actor;
|
||||
}
|
||||
}
|
||||
|
||||
if (context.Request.Headers.TryGetValue(TenantHeader, out var tenant))
|
||||
{
|
||||
var tenantId = tenant.ToString().Trim();
|
||||
if (!string.IsNullOrEmpty(tenantId))
|
||||
{
|
||||
return tenantId;
|
||||
}
|
||||
}
|
||||
|
||||
return "system";
|
||||
}
|
||||
|
||||
public static AuditActor ResolveAuditActor(HttpContext context)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
|
||||
var actorId = context.Request.Headers.TryGetValue(ActorHeader, out var idHeader)
|
||||
? idHeader.ToString().Trim()
|
||||
: null;
|
||||
|
||||
var displayName = context.Request.Headers.TryGetValue(ActorNameHeader, out var nameHeader)
|
||||
? nameHeader.ToString().Trim()
|
||||
: null;
|
||||
|
||||
var kind = context.Request.Headers.TryGetValue(ActorKindHeader, out var kindHeader)
|
||||
? kindHeader.ToString().Trim()
|
||||
: null;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(actorId))
|
||||
{
|
||||
actorId = context.Request.Headers.TryGetValue(TenantHeader, out var tenantHeader)
|
||||
? tenantHeader.ToString().Trim()
|
||||
: "system";
|
||||
}
|
||||
|
||||
displayName = string.IsNullOrWhiteSpace(displayName) ? actorId : displayName;
|
||||
kind = string.IsNullOrWhiteSpace(kind) ? "user" : kind;
|
||||
|
||||
return new AuditActor(actorId!, displayName!, kind!);
|
||||
}
|
||||
|
||||
public static bool TryParseBoolean(string? value)
|
||||
=> !string.IsNullOrWhiteSpace(value) &&
|
||||
(string.Equals(value, "true", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(value, "1", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
public static int? TryParsePositiveInt(string? value)
|
||||
{
|
||||
if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed) && parsed > 0)
|
||||
{
|
||||
return parsed;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DateTimeOffset? TryParseDateTimeOffset(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var parsed))
|
||||
{
|
||||
return parsed.ToUniversalTime();
|
||||
}
|
||||
|
||||
throw new ValidationException($"Value '{value}' is not a valid ISO-8601 timestamp.");
|
||||
}
|
||||
|
||||
public static Selector NormalizeSelector(Selector selection, string tenantId)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(selection);
|
||||
if (string.IsNullOrWhiteSpace(tenantId))
|
||||
{
|
||||
throw new ArgumentException("Tenant identifier must be provided.", nameof(tenantId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var parsed))
|
||||
{
|
||||
return parsed.ToUniversalTime();
|
||||
}
|
||||
|
||||
throw new ValidationException($"Value '{value}' is not a valid ISO-8601 timestamp.");
|
||||
}
|
||||
|
||||
public static Selector NormalizeSelector(Selector selection, string tenantId)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(selection);
|
||||
if (string.IsNullOrWhiteSpace(tenantId))
|
||||
{
|
||||
throw new ArgumentException("Tenant identifier must be provided.", nameof(tenantId));
|
||||
}
|
||||
|
||||
return new Selector(
|
||||
selection.Scope,
|
||||
tenantId,
|
||||
|
||||
Reference in New Issue
Block a user