feat: add response permission tracking for dynamic reply subject authorization

This commit is contained in:
Joseph Doherty
2026-02-23 00:59:15 -05:00
parent 7a897c1087
commit f0b5edd7c6
4 changed files with 154 additions and 3 deletions

View File

@@ -0,0 +1,51 @@
using NATS.Server.Auth;
namespace NATS.Server.Tests;
public class ResponseTrackerTests
{
[Fact]
public void Allows_reply_subject_after_registration()
{
var tracker = new ResponseTracker(maxMsgs: 1, expires: TimeSpan.FromMinutes(5));
tracker.RegisterReply("_INBOX.abc123");
tracker.IsReplyAllowed("_INBOX.abc123").ShouldBeTrue();
}
[Fact]
public void Denies_unknown_reply_subject()
{
var tracker = new ResponseTracker(maxMsgs: 1, expires: TimeSpan.FromMinutes(5));
tracker.IsReplyAllowed("_INBOX.unknown").ShouldBeFalse();
}
[Fact]
public void Enforces_max_messages()
{
var tracker = new ResponseTracker(maxMsgs: 2, expires: TimeSpan.FromMinutes(5));
tracker.RegisterReply("_INBOX.abc");
tracker.IsReplyAllowed("_INBOX.abc").ShouldBeTrue();
tracker.IsReplyAllowed("_INBOX.abc").ShouldBeTrue();
tracker.IsReplyAllowed("_INBOX.abc").ShouldBeFalse(); // exceeded
}
[Fact]
public void Enforces_expiry()
{
var tracker = new ResponseTracker(maxMsgs: 0, expires: TimeSpan.FromMilliseconds(1));
tracker.RegisterReply("_INBOX.abc");
Thread.Sleep(50);
tracker.IsReplyAllowed("_INBOX.abc").ShouldBeFalse();
}
[Fact]
public void Prune_removes_expired()
{
var tracker = new ResponseTracker(maxMsgs: 0, expires: TimeSpan.FromMilliseconds(1));
tracker.RegisterReply("_INBOX.a");
tracker.RegisterReply("_INBOX.b");
Thread.Sleep(50);
tracker.Prune();
tracker.Count.ShouldBe(0);
}
}