Bifrost/tests/Bifrost.Web.Tests/Support/FakeDeskCredential.cs
Heimdall 47db4f83f2 desk: the answer route on credential and door ports (H3a)
POST /api/desk/{mind}/answers behind one pipeline: raw target, bearer, audience,
scope, Active membership, body shape, {mind} lookup, door. Mapped only when the
Desk section exists; a configured desk without its credential and door ports
stops startup. Stale_fork answers carry the current card read through the door.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-10 19:28:52 +00:00

30 lines
1.3 KiB
C#

using Microsoft.AspNetCore.Http;
using System.Text.Json;
using Bifrost.Web.Features.Desk;
namespace Bifrost.Web.Tests.Support;
// A header-driven stand-in for the bearer validation port. X-Test-Desk-Token carries {sub, aud, scopes}; no header
// means no valid token. It validates nothing: the desk's own judgments (audience, scope, membership) are the subject.
public sealed class FakeDeskCredential : IDeskCredential
{
public const string Header = "X-Test-Desk-Token";
public static string Encode(string? subject, string? audience, IEnumerable<string> scopes) =>
JsonSerializer.Serialize(new { sub = subject, aud = audience, scopes });
public ValueTask<DeskToken?> AuthenticateAsync(HttpContext context, CancellationToken cancellationToken)
{
if (!context.Request.Headers.TryGetValue(Header, out var raw))
{
return ValueTask.FromResult<DeskToken?>(null);
}
using var document = JsonDocument.Parse(raw.ToString());
var root = document.RootElement;
return ValueTask.FromResult<DeskToken?>(new DeskToken(
root.GetProperty("sub").GetString(),
root.GetProperty("aud").GetString(),
root.GetProperty("scopes").EnumerateArray().Select(s => s.GetString()!).ToArray()));
}
}