feat: add authenticators, Account, and ClientPermissions (Tasks 3-7, 9)
- Account: per-account SubList and client tracking - IAuthenticator interface, AuthResult, ClientAuthContext - TokenAuthenticator: constant-time token comparison - UserPasswordAuthenticator: multi-user with bcrypt/plain support - SimpleUserPasswordAuthenticator: single user/pass config - NKeyAuthenticator: Ed25519 nonce signature verification - ClientPermissions: SubList-based publish/subscribe authorization
This commit is contained in:
107
tests/NATS.Server.Tests/ClientPermissionsTests.cs
Normal file
107
tests/NATS.Server.Tests/ClientPermissionsTests.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using NATS.Server.Auth;
|
||||
|
||||
namespace NATS.Server.Tests;
|
||||
|
||||
public class ClientPermissionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void No_permissions_allows_everything()
|
||||
{
|
||||
var perms = ClientPermissions.Build(null);
|
||||
perms.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Publish_allow_list_only()
|
||||
{
|
||||
var perms = ClientPermissions.Build(new Permissions
|
||||
{
|
||||
Publish = new SubjectPermission { Allow = ["foo.>", "bar.*"] },
|
||||
});
|
||||
|
||||
perms.ShouldNotBeNull();
|
||||
perms.IsPublishAllowed("foo.bar").ShouldBeTrue();
|
||||
perms.IsPublishAllowed("foo.bar.baz").ShouldBeTrue();
|
||||
perms.IsPublishAllowed("bar.one").ShouldBeTrue();
|
||||
perms.IsPublishAllowed("baz.one").ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Publish_deny_list_only()
|
||||
{
|
||||
var perms = ClientPermissions.Build(new Permissions
|
||||
{
|
||||
Publish = new SubjectPermission { Deny = ["secret.>"] },
|
||||
});
|
||||
|
||||
perms.ShouldNotBeNull();
|
||||
perms.IsPublishAllowed("foo.bar").ShouldBeTrue();
|
||||
perms.IsPublishAllowed("secret.data").ShouldBeFalse();
|
||||
perms.IsPublishAllowed("secret.nested.deep").ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Publish_allow_and_deny()
|
||||
{
|
||||
var perms = ClientPermissions.Build(new Permissions
|
||||
{
|
||||
Publish = new SubjectPermission
|
||||
{
|
||||
Allow = ["events.>"],
|
||||
Deny = ["events.internal.>"],
|
||||
},
|
||||
});
|
||||
|
||||
perms.ShouldNotBeNull();
|
||||
perms.IsPublishAllowed("events.public.data").ShouldBeTrue();
|
||||
perms.IsPublishAllowed("events.internal.secret").ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Subscribe_allow_list()
|
||||
{
|
||||
var perms = ClientPermissions.Build(new Permissions
|
||||
{
|
||||
Subscribe = new SubjectPermission { Allow = ["data.>"] },
|
||||
});
|
||||
|
||||
perms.ShouldNotBeNull();
|
||||
perms.IsSubscribeAllowed("data.updates").ShouldBeTrue();
|
||||
perms.IsSubscribeAllowed("admin.logs").ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Subscribe_deny_list()
|
||||
{
|
||||
var perms = ClientPermissions.Build(new Permissions
|
||||
{
|
||||
Subscribe = new SubjectPermission { Deny = ["admin.>"] },
|
||||
});
|
||||
|
||||
perms.ShouldNotBeNull();
|
||||
perms.IsSubscribeAllowed("data.updates").ShouldBeTrue();
|
||||
perms.IsSubscribeAllowed("admin.logs").ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Publish_cache_returns_same_result()
|
||||
{
|
||||
var perms = ClientPermissions.Build(new Permissions
|
||||
{
|
||||
Publish = new SubjectPermission { Allow = ["foo.>"] },
|
||||
});
|
||||
|
||||
perms.ShouldNotBeNull();
|
||||
perms.IsPublishAllowed("foo.bar").ShouldBeTrue();
|
||||
perms.IsPublishAllowed("foo.bar").ShouldBeTrue();
|
||||
perms.IsPublishAllowed("baz.bar").ShouldBeFalse();
|
||||
perms.IsPublishAllowed("baz.bar").ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Empty_permissions_object_allows_everything()
|
||||
{
|
||||
var perms = ClientPermissions.Build(new Permissions());
|
||||
perms.ShouldBeNull();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user