scope === FirewallRuleObject::SCOPE_SYSTEM ? $this->store->listSystemRules($activeOnly) : $this->store->listRules($scope->tenantId, $activeOnly); } public function blockIp( FirewallRuleScope $scope, string $ipAddress, ?string $reason, ?string $createdBy, ?int $durationSeconds = null ): FirewallRuleObject { $ipAddress = FirewallRuleValidator::ipAddress($ipAddress); FirewallRuleValidator::duration($durationSeconds); $existing = $this->store->findExactIpRule( $scope->tenantId, $ipAddress, FirewallRuleObject::ACTION_BLOCK, $scope->scope ); if ($existing) { return $existing; } $rule = $this->create( $scope, FirewallRuleObject::TYPE_IP, FirewallRuleObject::ACTION_BLOCK, $ipAddress, $reason ?? 'Blocked by administrator', $createdBy, $durationSeconds ); $this->publishIpEvent(SecurityEvent::IP_BLOCKED, $scope, $ipAddress, $reason); return $rule; } public function allowIp( FirewallRuleScope $scope, string $ipAddress, ?string $reason, ?string $createdBy ): FirewallRuleObject { $ipAddress = FirewallRuleValidator::ipAddress($ipAddress); $rule = $this->create( $scope, FirewallRuleObject::TYPE_IP, FirewallRuleObject::ACTION_ALLOW, $ipAddress, $reason ?? 'Allowed by administrator', $createdBy ); $this->publishIpEvent(SecurityEvent::IP_ALLOWED, $scope, $ipAddress, $reason); return $rule; } public function blockIpRange( FirewallRuleScope $scope, string $cidr, ?string $reason, ?string $createdBy ): FirewallRuleObject { return $this->create( $scope, FirewallRuleObject::TYPE_IP_RANGE, FirewallRuleObject::ACTION_BLOCK, FirewallRuleValidator::cidr($cidr), $reason ?? 'Range blocked by administrator', $createdBy ); } public function blockDevice( FirewallRuleScope $scope, string $fingerprint, ?string $reason, ?string $createdBy, ?int $durationSeconds = null ): FirewallRuleObject { FirewallRuleValidator::duration($durationSeconds); $fingerprint = FirewallRuleValidator::deviceFingerprint($fingerprint); $rule = $this->create( $scope, FirewallRuleObject::TYPE_DEVICE, FirewallRuleObject::ACTION_BLOCK, $fingerprint, $reason ?? 'Device blocked by administrator', $createdBy, $durationSeconds ); $event = new SecurityEvent(SecurityEvent::DEVICE_BLOCKED, ['device' => $fingerprint, 'reason' => $reason]); $event->setDeviceFingerprint($fingerprint)->setReason($reason)->setTenantId($scope->tenantId); $this->events->dispatch($event); return $rule; } public function disable(FirewallRuleScope $scope, string $ruleId): bool { $rule = $this->ownedRule($scope, $ruleId); if (!$rule) { return false; } $rule->setEnabled(false); $this->store->depositRule($rule); $this->cache->invalidate(); return true; } public function remove(FirewallRuleScope $scope, string $ruleId): bool { $rule = $this->ownedRule($scope, $ruleId); if (!$rule) { return false; } $this->store->destroyRule($rule); $this->cache->invalidate(); return true; } private function create( FirewallRuleScope $scope, string $type, string $action, string $value, string $reason, ?string $createdBy, ?int $durationSeconds = null ): FirewallRuleObject { $rule = (new FirewallRuleObject()) ->setScope($scope->scope) ->setTenantId($scope->tenantId) ->setType($type) ->setAction($action) ->setValue($value) ->setReason($reason) ->setCreatedBy($createdBy) ->setCreatedAt(new \DateTimeImmutable()) ->setEnabled(true); if ($durationSeconds !== null) { $rule->setExpiresAt((new \DateTimeImmutable())->modify("+{$durationSeconds} seconds")); } $this->store->depositRule($rule); $this->cache->invalidate(); return $rule; } private function ownedRule(FirewallRuleScope $scope, string $ruleId): ?FirewallRuleObject { $rule = $this->store->fetchRule($ruleId); return $rule && $scope->owns($rule) ? $rule : null; } private function publishIpEvent( string $name, FirewallRuleScope $scope, string $ipAddress, ?string $reason ): void { $event = new SecurityEvent($name, ['ip' => $ipAddress, 'reason' => $reason]); $event->setIpAddress($ipAddress)->setReason($reason)->setTenantId($scope->tenantId); $this->events->dispatch($event); } }