Files
natsdotnet/tests/NATS.Server.Auth.Tests/PermissionIntegrationTests.cs
Joseph Doherty 36b9dfa654 refactor: extract NATS.Server.Auth.Tests project
Move 50 auth/accounts/permissions/JWT/NKey test files from
NATS.Server.Tests into a dedicated NATS.Server.Auth.Tests project.
Update namespaces, replace private GetFreePort/ReadUntilAsync helpers
with TestUtilities calls, replace Task.Delay with TaskCompletionSource
in test doubles, and add InternalsVisibleTo.

690 tests pass.
2026-03-12 15:54:07 -04:00

114 lines
3.4 KiB
C#

using System.Net;
using System.Net.Sockets;
using Microsoft.Extensions.Logging.Abstractions;
using NATS.Client.Core;
using NATS.Server.Auth;
using NATS.Server.TestUtilities;
namespace NATS.Server.Auth.Tests;
public class PermissionIntegrationTests : IAsyncLifetime
{
private NatsServer _server = null!;
private int _port;
private readonly CancellationTokenSource _cts = new();
private Task _serverTask = null!;
public async Task InitializeAsync()
{
_port = TestPortAllocator.GetFreePort();
_server = new NatsServer(new NatsOptions
{
Port = _port,
Users =
[
new User
{
Username = "publisher",
Password = "pass",
Permissions = new Permissions
{
Publish = new SubjectPermission { Allow = ["events.>"] },
Subscribe = new SubjectPermission { Deny = [">"] },
},
},
new User
{
Username = "subscriber",
Password = "pass",
Permissions = new Permissions
{
Publish = new SubjectPermission { Deny = [">"] },
Subscribe = new SubjectPermission { Allow = ["events.>"] },
},
},
new User
{
Username = "admin",
Password = "pass",
// No permissions — full access
},
],
}, NullLoggerFactory.Instance);
_serverTask = _server.StartAsync(_cts.Token);
await _server.WaitForReadyAsync();
}
public async Task DisposeAsync()
{
await _cts.CancelAsync();
_server.Dispose();
}
[Fact]
public async Task Publisher_can_publish_to_allowed_subject()
{
await using var pub = new NatsConnection(new NatsOpts
{
Url = $"nats://publisher:pass@127.0.0.1:{_port}",
});
await using var admin = new NatsConnection(new NatsOpts
{
Url = $"nats://admin:pass@127.0.0.1:{_port}",
});
await pub.ConnectAsync();
await admin.ConnectAsync();
await using var sub = await admin.SubscribeCoreAsync<string>("events.test");
await admin.PingAsync();
await pub.PublishAsync("events.test", "hello");
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var msg = await sub.Msgs.ReadAsync(timeout.Token);
msg.Data.ShouldBe("hello");
}
[Fact]
public async Task Admin_has_full_access()
{
await using var admin1 = new NatsConnection(new NatsOpts
{
Url = $"nats://admin:pass@127.0.0.1:{_port}",
});
await using var admin2 = new NatsConnection(new NatsOpts
{
Url = $"nats://admin:pass@127.0.0.1:{_port}",
});
await admin1.ConnectAsync();
await admin2.ConnectAsync();
await using var sub = await admin2.SubscribeCoreAsync<string>("anything.at.all");
await admin2.PingAsync();
await admin1.PublishAsync("anything.at.all", "data");
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var msg = await sub.Msgs.ReadAsync(timeout.Token);
msg.Data.ShouldBe("data");
}
}