feat(firewall): add scoped rule administration reads

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-08-03 22:05:00 -04:00
parent 4ee91a7918
commit 74696bbeb3
9 changed files with 486 additions and 0 deletions
@@ -91,6 +91,59 @@ class FirewallRuleManagerTest extends TestCase
self::assertFalse($this->manager->remove(FirewallRuleScope::tenant('tenant-b'), 'tenant-rule'));
}
#[TestDox('Rule queries retain scope, filters, and bounded pagination')]
public function testRuleQuery(): void
{
$result = ['items' => [], 'total' => 0, 'limit' => 25, 'offset' => 50];
$this->store->expects(self::once())
->method('queryRules')
->with(
FirewallRuleObject::SCOPE_TENANT,
'tenant-a',
'disabled',
FirewallRuleObject::TYPE_IP,
FirewallRuleObject::ACTION_BLOCK,
25,
50
)
->willReturn($result);
self::assertSame($result, $this->manager->query(
FirewallRuleScope::tenant('tenant-a'),
'disabled',
FirewallRuleObject::TYPE_IP,
FirewallRuleObject::ACTION_BLOCK,
25,
50
));
}
#[TestDox('Rule queries reject invalid filters and excessive pages')]
public function testRuleQueryValidation(): void
{
$this->store->expects(self::never())->method('queryRules');
$this->expectException(\InvalidArgumentException::class);
$this->manager->query(FirewallRuleScope::system(), 'active', null, null, 101);
}
#[TestDox('Effective policy keeps system and tenant rule sets distinct')]
public function testEffectivePolicy(): void
{
$system = (new FirewallRuleObject())->setScope(FirewallRuleObject::SCOPE_SYSTEM);
$tenant = (new FirewallRuleObject())
->setScope(FirewallRuleObject::SCOPE_TENANT)
->setTenantId('tenant-a');
$this->store->method('listSystemRules')->willReturn([$system]);
$this->store->method('listRules')->with('tenant-a')->willReturn([$tenant]);
$policy = $this->manager->effectivePolicy('tenant-a');
self::assertSame([$system], $policy['system']);
self::assertSame([$tenant], $policy['tenant']);
self::assertSame('system_block', $policy['precedence'][0]);
}
#[TestDox('Rule mutations invalidate the shared enforcement cache')]
public function testCacheInvalidation(): void
{