131 lines
3.3 KiB
PHP
131 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Lib;
|
|
|
|
use App\Lib\Options;
|
|
use Dxw\CIDR\IPAddress;
|
|
use Dxw\CIDR\IPv4Address;
|
|
use Dxw\CIDR\IPv4Range;
|
|
use Dxw\CIDR\IPv6Address;
|
|
use Dxw\CIDR\IPv6Range;
|
|
|
|
abstract class AdminSecure
|
|
{
|
|
/**
|
|
* Private ipV4 CIDR list
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $private_ip_v4_cidr_list = [
|
|
'10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'
|
|
];
|
|
|
|
/**
|
|
* Private ipV4 CIDR loopback
|
|
*
|
|
* @var string
|
|
*/
|
|
private static $private_ip_v4_loopback_cidr = '127.0.0.0/8';
|
|
|
|
/**
|
|
* Private ipV6 CIDR list
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $private_ip_v6_cidr_list = [
|
|
'fd00::/8'
|
|
];
|
|
|
|
/**
|
|
* Private ipV6 CIDR loopback
|
|
*
|
|
* @var string
|
|
*/
|
|
private static $private_ip_v6_loopback_cidr = '::1/128';
|
|
|
|
/**
|
|
* Private options
|
|
*
|
|
* @var \App\Lib\Options|null
|
|
*/
|
|
private static $options = null;
|
|
|
|
/**
|
|
* Check if ip is private
|
|
*
|
|
* @param \Dxw\CIDR\IPv4Address|\Dxw\CIDR\IPv6Address $ip_address
|
|
* @return boolean
|
|
*/
|
|
public static function ipIsPrivate($ip_address): bool
|
|
{
|
|
return \get_class($ip_address) === IPv4Address::class ?
|
|
self::ipV4IsPrivate($ip_address) : self::ipV6IsPrivate($ip_address);
|
|
}
|
|
|
|
/**
|
|
* Fetch client IP
|
|
*
|
|
* @return \Dxw\CIDR\IPv4Address|\Dxw\CIDR\IPv6Address
|
|
* @throws \Exception If the ip is invalid.
|
|
*/
|
|
public static function fetchClientIp()
|
|
{
|
|
// ! REVERSE PROXY HACK.
|
|
$ip = request()->server('HTTP_X_FORWARDED_FOR') ?? request()->getClientIp();
|
|
$ip = IPAddress::Make($ip);
|
|
|
|
if ($ip->isErr()) {
|
|
throw new \Exception(\trans('Client IP not valid ') . $ip->getErr());
|
|
}
|
|
return $ip->unwrap();
|
|
}
|
|
|
|
/**
|
|
* Check if ipV4 is private
|
|
*
|
|
* @param \Dxw\CIDR\IPv4Address $ipv4_address
|
|
* @return boolean
|
|
*/
|
|
private static function ipV4IsPrivate(IPv4Address $ipv4_address): bool
|
|
{
|
|
return \collect(self::$private_ip_v4_cidr_list)
|
|
->concat([self::$private_ip_v4_loopback_cidr])
|
|
->map(function (string $ipv4_cidr) {
|
|
return IPv4Range::Make($ipv4_cidr)->unwrap();
|
|
})
|
|
->reduce(function ($initial, IPv4Range $ipv4_range) use ($ipv4_address) {
|
|
return $initial || $ipv4_range->containsAddress($ipv4_address);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Check if ipV6 is private
|
|
*
|
|
* @param \Dxw\CIDR\IPv6Address $ipv6_address
|
|
* @return boolean
|
|
*/
|
|
private static function ipV6IsPrivate(IPv6Address $ipv6_address): bool
|
|
{
|
|
return \collect(self::$private_ip_v6_cidr_list)
|
|
->concat([self::$private_ip_v6_loopback_cidr])
|
|
->map(function (string $ipv6_cidr) {
|
|
return IPv6Range::Make($ipv6_cidr)->unwrap();
|
|
})
|
|
->reduce(function ($initial, IPv6Range $ipv6_range) use ($ipv6_address) {
|
|
return $initial || $ipv6_range->containsAddress($ipv6_address);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get Admin secure options
|
|
*
|
|
* @return \App\Lib\Options
|
|
*/
|
|
public static function getOptions(): Options
|
|
{
|
|
if (!self::$options) {
|
|
self::$options = new Options(\config('admin-secure'));
|
|
}
|
|
return self::$options;
|
|
}
|
|
}
|