59 lines
2.0 KiB
C#
59 lines
2.0 KiB
C#
using NATS.Server.Auth;
|
|
using NATS.Server.Protocol;
|
|
|
|
namespace NATS.Server.Tests;
|
|
|
|
public class ExternalAuthCalloutTests
|
|
{
|
|
[Fact]
|
|
public void External_callout_authenticator_can_allow_and_deny_with_timeout_and_reason_mapping()
|
|
{
|
|
var authenticator = new ExternalAuthCalloutAuthenticator(
|
|
new FakeExternalAuthClient(),
|
|
TimeSpan.FromMilliseconds(50));
|
|
|
|
var allowed = authenticator.Authenticate(new ClientAuthContext
|
|
{
|
|
Opts = new ClientOptions { Username = "u", Password = "p" },
|
|
Nonce = [],
|
|
});
|
|
allowed.ShouldNotBeNull();
|
|
allowed.Identity.ShouldBe("u");
|
|
|
|
var denied = authenticator.Authenticate(new ClientAuthContext
|
|
{
|
|
Opts = new ClientOptions { Username = "u", Password = "bad" },
|
|
Nonce = [],
|
|
});
|
|
denied.ShouldBeNull();
|
|
|
|
var timeout = new ExternalAuthCalloutAuthenticator(
|
|
new SlowExternalAuthClient(TimeSpan.FromMilliseconds(200)),
|
|
TimeSpan.FromMilliseconds(30));
|
|
timeout.Authenticate(new ClientAuthContext
|
|
{
|
|
Opts = new ClientOptions { Username = "u", Password = "p" },
|
|
Nonce = [],
|
|
}).ShouldBeNull();
|
|
}
|
|
|
|
private sealed class FakeExternalAuthClient : IExternalAuthClient
|
|
{
|
|
public Task<ExternalAuthDecision> AuthorizeAsync(ExternalAuthRequest request, CancellationToken ct)
|
|
{
|
|
if (request is { Username: "u", Password: "p" })
|
|
return Task.FromResult(new ExternalAuthDecision(true, "u", "A"));
|
|
return Task.FromResult(new ExternalAuthDecision(false, Reason: "denied"));
|
|
}
|
|
}
|
|
|
|
private sealed class SlowExternalAuthClient(TimeSpan delay) : IExternalAuthClient
|
|
{
|
|
public async Task<ExternalAuthDecision> AuthorizeAsync(ExternalAuthRequest request, CancellationToken ct)
|
|
{
|
|
await Task.Delay(delay, ct);
|
|
return new ExternalAuthDecision(true, "slow");
|
|
}
|
|
}
|
|
}
|