Files
ABSDEV/Modules/Security/Services/IpRuleService.php
T
Mark Gregory 7fb71c4d24 Central Security Centre
* Security policy management
* Minimum password-length policy
* Mixed-case, number, and symbol requirements
* Password expiry and history settings
* MFA requirement policy
* Failed-login and lockout settings
* Session idle-time policy
* Single-session policy
* Automatic successful-login recording
* Automatic failed-login recording
* Automatic logout recording
* Authentication history
* IP allow and deny rules
* IPv4 CIDR support
* Administration and login rule scopes
* Trusted-device storage and revocation
* Security middleware registration
* Administration navigation
* Security permissions
* Module registration and tests
2026-07-24 12:30:40 +01:00

25 lines
1.1 KiB
PHP

<?php
namespace Modules\Security\Services;
use Modules\Security\Models\IpRule;
final class IpRuleService
{
public function isBlocked(string $ip, string $scope='admin'): bool
{
$column=$scope==='login'?'applies_to_login':'applies_to_admin';
$rules=IpRule::query()->where('is_active',true)->where($column,true)->get();
$allow=$rules->where('type','allow');
if ($allow->isNotEmpty() && !$allow->contains(fn(IpRule $rule)=>$this->matches($ip,$rule->address))) return true;
return $rules->where('type','deny')->contains(fn(IpRule $rule)=>$this->matches($ip,$rule->address));
}
private function matches(string $ip,string $rule): bool
{
if ($ip===$rule) return true;
if (!str_contains($rule,'/')) return false;
[$subnet,$bits]=explode('/',$rule,2); $bits=(int)$bits;
if (filter_var($ip,FILTER_VALIDATE_IP,FILTER_FLAG_IPV4) && filter_var($subnet,FILTER_VALIDATE_IP,FILTER_FLAG_IPV4)) {
$mask=-1 << (32-$bits); return (ip2long($ip)&$mask)===(ip2long($subnet)&$mask);
}
return false;
}
}