ldc-tregalette/app/Lib/AdminSecure.php

132 lines
3.3 KiB
PHP
Raw Normal View History

<?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 \Uwil\AdminSecure\Laravel\Exceptions\AdminSecureException 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;
}
}