Source of file IpAccess.php
Size: 4,429 Bytes - Last Modified: 2022-01-13T10:01:01+00:00
/var/www/docs.ssmods.com/process/src/code/model/IpAccess.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 | <?php /** * Check Access based on remote IP address. * * @Example entries : * 192.168.178.8 * 192.168.178.0/24 * 192.168.178.0-50 * 192.168.178.* * 192.168.* * * @return false || string : entry the ip address was matched against */ class IpAccess extends Object { /** * @var array */ public $allowedIps = []; /** * @config * * @var array */ private static $allowed_ips = []; /** * @var string */ private $ip = ''; /** * IpAccess constructor. * * @param string $ip * @param array $allowedIps */ public function __construct($ip = '', $allowedIps = []) { parent::__construct(); $this->ip = $ip; self::config()->allowed_ips = $allowedIps; } /** * @param $ip */ public function setIp($ip) { $this->ip = $ip; } /** * @return array */ public function getAllowedIps() { if (!empty($this->allowedIps)) { Deprecation::notice('1.1', 'Use the "IpAccess.allowed_ips" config setting instead'); self::config()->allowed_ips = $this->allowedIps; } return self::$allowed_ips ? self::$allowed_ips : (array) self::config()->allowed_ips; } /** * @return bool */ public function isEnabled() { return (bool) Config::inst()->get('IpAccess', 'enabled'); } /** * @return bool */ public function hasAccess() { if (!$this->isEnabled() || !(bool) $this->getAllowedIps()) { return true; } return $this->matchIp(); } /** * @return bool */ public function matchIp() { return $this->matchExact() || $this->matchRange() || $this->matchCIDR() || $this->matchWildCard(); } /** * @param Controller $controller * * @throws SS_HTTPResponse_Exception */ public function respondNoAccess(Controller $controller) { $response = null; if (class_exists('ErrorPage', true)) { $response = ErrorPage::response_for(403); } $controller->httpError(403, $response ? $response : 'The requested page could not be found.'); } /** * @return string */ public function matchExact() { return in_array($this->ip, $this->getAllowedIps()) ? $this->ip : ''; } /** * Try to match against a ip range * Example : 192.168.1.50-100. * * @return string */ public function matchRange() { $ranges = array_filter($this->getAllowedIps(), function ($ip) { return strstr($ip, '-'); }); $ip = $this->ip; $matches = array_filter($ranges, function ($range) use ($ip) { $ipFirstPart = substr($ip, 0, strrpos($ip, '.') + 1); $ipLastPart = substr(strrchr($ip, '.'), 1); $rangeFirstPart = substr($range, 0, strrpos($range, '.') + 1); list($start, $end) = explode('-', substr(strrchr($range, '.'), 1)); return $ipFirstPart === $rangeFirstPart && $ipLastPart >= $start && $ipLastPart <= $end; }); return array_shift($matches); } /** * Try to match cidr range * Example : 192.168.1.0/24. * * @return string */ public function matchCIDR() { $ranges = array_filter($this->getAllowedIps(), function ($ip) { return strstr($ip, '/'); }); if (!empty($ranges)) { foreach ($ranges as $range) { list($net, $mask) = explode('/', $range); if ((ip2long($this->ip) & ~((1 << (32 - $mask)) - 1)) == ip2long($net)) { return $range; } } } return ''; } /** * Try to match against a range that ends with a wildcard * * Example : 192.168.1.* * Example : 192.168.*. * * @return string */ public function matchWildCard() { $ranges = array_filter($this->getAllowedIps(), function ($ip) { return substr($ip, -1) === '*'; }); if (!empty($ranges)) { foreach ($ranges as $range) { if (substr($this->ip, 0, strlen(substr($range, 0, -1))) === substr($range, 0, -1)) { return $range; } } } return ''; } } |