80 lines
2.7 KiB
C#
80 lines
2.7 KiB
C#
using ClaudeDo.Worker.Config;
|
|
using ClaudeDo.Worker.External;
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
namespace ClaudeDo.Worker.Tests.External;
|
|
|
|
public sealed class ExternalMcpAuthMiddlewareTests
|
|
{
|
|
private const int RemotePort = 47_823;
|
|
|
|
private static async Task<(int Status, bool Passed)> Run(WorkerConfig cfg, RemoteSessionTokenRegistry tokens,
|
|
int localPort, string? remoteToken = null, string? apiKey = null)
|
|
{
|
|
var passed = false;
|
|
var mw = new ExternalMcpAuthMiddleware(_ => { passed = true; return Task.CompletedTask; });
|
|
var ctx = new DefaultHttpContext();
|
|
ctx.Connection.LocalPort = localPort;
|
|
if (remoteToken is not null) ctx.Request.Headers[ExternalMcpAuthMiddleware.RemoteTokenHeader] = remoteToken;
|
|
if (apiKey is not null) ctx.Request.Headers["X-ClaudeDo-Key"] = apiKey;
|
|
await mw.InvokeAsync(ctx, cfg, tokens);
|
|
return (ctx.Response.StatusCode, passed);
|
|
}
|
|
|
|
private static WorkerConfig Cfg(string? key = null) =>
|
|
new() { ExternalMcpPort = 47_822, RemoteMcpPort = RemotePort, ExternalMcpApiKey = key };
|
|
|
|
[Fact]
|
|
public async Task RemotePort_WithoutToken_Is401()
|
|
{
|
|
var (status, passed) = await Run(Cfg(), new RemoteSessionTokenRegistry(), RemotePort);
|
|
Assert.Equal(401, status);
|
|
Assert.False(passed);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RemotePort_WithUnknownToken_Is401()
|
|
{
|
|
var (status, passed) = await Run(Cfg(), new RemoteSessionTokenRegistry(), RemotePort, remoteToken: "nope");
|
|
Assert.Equal(401, status);
|
|
Assert.False(passed);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RemotePort_WithIssuedToken_PassesEvenWhenApiKeyConfigured()
|
|
{
|
|
var tokens = new RemoteSessionTokenRegistry();
|
|
var token = tokens.Issue();
|
|
var (_, passed) = await Run(Cfg(key: "secret"), tokens, RemotePort, remoteToken: token);
|
|
Assert.True(passed);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RemotePort_ApiKeyAlone_DoesNotPass()
|
|
{
|
|
var (status, passed) = await Run(Cfg(key: "secret"), new RemoteSessionTokenRegistry(), RemotePort, apiKey: "secret");
|
|
Assert.Equal(401, status);
|
|
Assert.False(passed);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task NormalPort_WithoutKeyConfigured_StillPasses()
|
|
{
|
|
var (_, passed) = await Run(Cfg(), new RemoteSessionTokenRegistry(), 47_822);
|
|
Assert.True(passed);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Issue_ReturnsDistinct64HexTokens()
|
|
{
|
|
var tokens = new RemoteSessionTokenRegistry();
|
|
var a = tokens.Issue();
|
|
var b = tokens.Issue();
|
|
Assert.NotEqual(a, b);
|
|
Assert.Matches("^[0-9A-F]{64}$", a);
|
|
Assert.True(tokens.IsValid(a));
|
|
Assert.False(tokens.IsValid(""));
|
|
await Task.CompletedTask;
|
|
}
|
|
}
|