refactor(security): type firewall rule lifecycle events

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-08-05 23:51:40 -04:00
parent a5be782c51
commit 2494cef02f
16 changed files with 383 additions and 73 deletions
@@ -11,7 +11,11 @@ use KTXC\Service\FirewallRuleManager;
use KTXC\Service\FirewallRuleScope;
use KTXC\Stores\FirewallStore;
use KTXF\Event\EventDispatcherInterface;
use KTXC\Security\Event\SecurityEvent;
use KTXC\Security\Event\FirewallRuleCreatedEvent;
use KTXC\Security\Event\FirewallRuleDisabledEvent;
use KTXC\Security\Event\FirewallRuleEnabledEvent;
use KTXC\Security\Event\FirewallRuleExtendedEvent;
use KTXC\Security\Event\FirewallRuleRemovedEvent;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\MockObject\MockObject;
@@ -41,7 +45,10 @@ class FirewallRuleManagerTest extends TestCase
$this->store->method('findExactIpRule')->willReturn(null);
$this->store->expects($this->exactly(2))
->method('depositRule')
->willReturnArgument(0);
->willReturnCallback(static function (FirewallRuleObject $rule): FirewallRuleObject {
static $sequence = 0;
return $rule->setId('rule-' . ++$sequence);
});
$tenant = $this->manager->blockIp(
FirewallRuleScope::tenant('tenant-a'), '203.0.113.10', null, 'admin-a'
@@ -135,7 +142,11 @@ class FirewallRuleManagerTest extends TestCase
public function testConfirmedCurrentIpBlock(): void
{
$this->store->method('findExactIpRule')->willReturn(null);
$this->store->expects(self::once())->method('depositRule')->willReturnArgument(0);
$this->store->expects(self::once())
->method('depositRule')
->willReturnCallback(static fn(FirewallRuleObject $rule): FirewallRuleObject =>
$rule->setId('rule-confirmed')
);
$rule = $this->manager->createManualRule(
FirewallRuleScope::tenant('tenant-a'),
@@ -249,7 +260,9 @@ class FirewallRuleManagerTest extends TestCase
$cache = new FirewallRuleCache($this->store);
$manager = new FirewallRuleManager($this->store, $cache, $this->events);
$this->store->method('findExactIpRule')->willReturn(null);
$this->store->method('depositRule')->willReturnArgument(0);
$this->store->method('depositRule')->willReturnCallback(
static fn(FirewallRuleObject $rule): FirewallRuleObject => $rule->setId('rule-cache')
);
self::assertSame([], $cache->tenant('tenant-a'));
$manager->blockIp(FirewallRuleScope::tenant('tenant-a'), '203.0.113.10', null, 'admin');
@@ -280,7 +293,7 @@ class FirewallRuleManagerTest extends TestCase
300
);
$audit = $events[SecurityEvent::FIREWALL_RULE_CREATED];
$audit = $events[FirewallRuleCreatedEvent::class];
self::assertSame('rule-123', $audit->get('ruleId'));
self::assertSame(FirewallRuleObject::SCOPE_TENANT, $audit->get('ruleScope'));
self::assertSame(FirewallRuleObject::TYPE_IP, $audit->get('ruleType'));
@@ -329,10 +342,10 @@ class FirewallRuleManagerTest extends TestCase
self::assertGreaterThan($originalExpiry, $extended->getExpiresAt());
self::assertCount(1, $extended->getMetadata()['extensions']);
self::assertSame([
SecurityEvent::FIREWALL_RULE_DISABLED,
SecurityEvent::FIREWALL_RULE_ENABLED,
SecurityEvent::FIREWALL_RULE_EXTENDED,
SecurityEvent::FIREWALL_RULE_REMOVED,
FirewallRuleDisabledEvent::class,
FirewallRuleEnabledEvent::class,
FirewallRuleExtendedEvent::class,
FirewallRuleRemovedEvent::class,
], array_map(static fn($event): string => $event->getName(), $audits));
self::assertSame(
['Investigation', 'Threat confirmed', 'Continue monitoring', 'Case closed'],
@@ -401,7 +414,7 @@ class FirewallRuleManagerTest extends TestCase
$this->events->expects(self::once())
->method('dispatch')
->with(self::callback(static fn(\KTXF\Event\Event $event): bool =>
$event->getName() === SecurityEvent::FIREWALL_RULE_EXTENDED
$event instanceof FirewallRuleExtendedEvent
&& $event->get('lastFailureCount') === 8
));