fix(inbound): prune expired ApiMethodCache entries; pin exact-name scopes (review 2026-10-21 05/M3)
This commit is contained in:
@@ -327,6 +327,27 @@ public sealed class EndpointExtensionsTests : IDisposable
|
||||
Assert.Equal(NotApprovedBodyJson, body);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that scopes are exact method names, not prefixes or wildcards.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Theory]
|
||||
[InlineData("*")]
|
||||
[InlineData("sec*")]
|
||||
[InlineData("sec")]
|
||||
public async Task ValidKey_WildcardOrPrefixScope_DoesNotGrantMethod(string scope)
|
||||
{
|
||||
// Review 2026-10-21 05/M3: ApiMethodCache bounds its growth on the invariant that scopes
|
||||
// are exact names; pin it so a future wildcard scope has to revisit the cache.
|
||||
var method = SeedMethod(1, "secured", "return 1;");
|
||||
|
||||
using var host = await BuildHostAsync(method);
|
||||
var token = await SeedKeyAsync(host, "key1", "caller", new[] { scope });
|
||||
var client = host.GetTestClient();
|
||||
|
||||
var response = await client.SendAsync(BuildPost("secured", "{}", token));
|
||||
|
||||
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that an unknown method returns 403 with a body identical to the not-in-scope body.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user