feat: ✨ Remove LDC Web API dependency
This commit is contained in:
parent
26f818b6b9
commit
a4e0fafa16
11 changed files with 82 additions and 260 deletions
|
|
@ -6,6 +6,12 @@ All notable changes to `admin-secure-laravel` will be documented in this file.
|
||||||
- This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
- This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
||||||
- Commits respect [Conventionnal commits](https://www.conventionalcommits.org/en/v1.0.0/) & use [Gitmoji](https://gitmoji.dev/).
|
- Commits respect [Conventionnal commits](https://www.conventionalcommits.org/en/v1.0.0/) & use [Gitmoji](https://gitmoji.dev/).
|
||||||
|
|
||||||
|
## **[v5.0.0] - 09/01/2026**
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- feat: ✨ Remove LDC Web API dependency
|
||||||
|
|
||||||
## **[v4.0.0] - 07/04/2025**
|
## **[v4.0.0] - 07/04/2025**
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
27
README.md
27
README.md
|
|
@ -7,36 +7,19 @@ composer req uwil/admin-secure-laravel
|
||||||
.env.example :
|
.env.example :
|
||||||
|
|
||||||
```dotenv
|
```dotenv
|
||||||
# ADMIN SECURE
|
# UWIL ADMIN SECURE
|
||||||
# - API ENDPOINT (Optional)
|
# - LIST SEPARATED WITH ',' (Required)
|
||||||
LDC_WEB_API_ENDPOINT="https://ldc-web.ldc.fr/api/ldc-networks"
|
UWIL_ADMIN_SECURE_CIDR_LIST=""
|
||||||
# - API KEY
|
|
||||||
LDC_WEB_API_KEY=""
|
|
||||||
# - LIST SEPARATED WITH ',' (Optional)
|
# - LIST SEPARATED WITH ',' (Optional)
|
||||||
LDC_WEB_CIDR_MANUAL_ALLOWED_LIST=""
|
UWIL_ADMIN_SECURE_CIDR_PROJECT_ALLOWED_LIST=""
|
||||||
```
|
```
|
||||||
|
|
||||||
README.md :
|
|
||||||
```
|
|
||||||
Put every min in PROD :
|
|
||||||
php artisan schedule:run
|
|
||||||
```
|
|
||||||
|
|
||||||
## Available Commands
|
|
||||||
```
|
|
||||||
uwil:admin-secure:sync
|
|
||||||
```
|
|
||||||
## Usage
|
## Usage
|
||||||
Put 'admin-secure' middleware on route to protect it.
|
Put 'admin-secure' middleware on route to protect it.
|
||||||
## Cron configure
|
|
||||||
|
|
||||||
Nothing to do command is already configureed to run everyday.
|
|
||||||
You just need to install this package.
|
|
||||||
**!! Runs only in production !!**
|
|
||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
Latest version v4.0.0.
|
Latest version v5.0.0.
|
||||||
|
|
||||||
See the [CHANGELOG.md](CHANGELOG.md) file for details.
|
See the [CHANGELOG.md](CHANGELOG.md) file for details.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
"name": "uwil/admin-secure-laravel",
|
"name": "uwil/admin-secure-laravel",
|
||||||
"description": "Restrict access to LDC Network",
|
"description": "Restrict access to LDC Network",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"version": "4.0.0",
|
"version": "5.0.0",
|
||||||
"readme": "https://lab.s-web.fr/ldc-web/projets/ldc-web-admin-secure-laravel/-/blob/main/README.md",
|
"readme": "https://lab.s-web.fr/ldc-web/projets/ldc-web-admin-secure-laravel/-/blob/main/README.md",
|
||||||
"support": {
|
"support": {
|
||||||
"email": "equipe.web@ldc.fr",
|
"email": "digital@ldc.fr",
|
||||||
"issues": "https://lab.s-web.fr/ldc-web/projets/ldc-web-admin-secure-laravel/-/issues"
|
"issues": "https://lab.s-web.fr/ldc-web/projets/ldc-web-admin-secure-laravel/-/issues"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'endpoint' => env('LDC_WEB_API_ENDPOINT', 'https://ldc-web.ldc.fr/api/ldc-networks'),
|
'cidrList' => env('UWIL_ADMIN_SECURE_CIDR_LIST'),
|
||||||
'apiKey' => env('LDC_WEB_API_KEY'),
|
'cidrProjectAllowedList' => env('UWIL_ADMIN_SECURE_CIDR_PROJECT_ALLOWED_LIST')
|
||||||
'cidrManualAllowedList' => env('LDC_WEB_CIDR_MANUAL_ALLOWED_LIST')
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2022 LDC Service Web
|
Copyright (c) 2022 LDC Digital
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
||||||
|
|
@ -7,29 +7,10 @@ use Dxw\CIDR\IPv4Address;
|
||||||
use Dxw\CIDR\IPv4Range;
|
use Dxw\CIDR\IPv4Range;
|
||||||
use Dxw\CIDR\IPv6Address;
|
use Dxw\CIDR\IPv6Address;
|
||||||
use Dxw\CIDR\IPv6Range;
|
use Dxw\CIDR\IPv6Range;
|
||||||
use Illuminate\Http\Client\Response;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
|
||||||
use Illuminate\Support\Facades\Http;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Uwil\AdminSecure\Laravel\Exceptions\AdminSecureException;
|
use Uwil\AdminSecure\Laravel\Exceptions\AdminSecureException;
|
||||||
use Uwil\AdminSecure\Laravel\Exceptions\AdminSecureInvalidAdressException;
|
|
||||||
|
|
||||||
abstract class AdminSecure
|
abstract class AdminSecure
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The cache key where to store ip list.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private static string $cache_key = 'ldcweb_ip_list';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The cache time to live.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private static string $cache_ttl = '180 minutes';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private ipV4 CIDR list
|
* Private ipV4 CIDR list
|
||||||
*
|
*
|
||||||
|
|
@ -89,7 +70,7 @@ abstract class AdminSecure
|
||||||
*/
|
*/
|
||||||
public static function fetchClientIp(): IPv4Address|IPv6Address
|
public static function fetchClientIp(): IPv4Address|IPv6Address
|
||||||
{
|
{
|
||||||
// ! HA PROXY HACK.
|
// ! REVERSE PROXY HACK.
|
||||||
$ip = request()->server('HTTP_X_FORWARDED_FOR') ?? request()->getClientIp();
|
$ip = request()->server('HTTP_X_FORWARDED_FOR') ?? request()->getClientIp();
|
||||||
$ip = IPAddress::Make($ip);
|
$ip = IPAddress::Make($ip);
|
||||||
|
|
||||||
|
|
@ -99,64 +80,6 @@ abstract class AdminSecure
|
||||||
return $ip->unwrap();
|
return $ip->unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get ip list from cache
|
|
||||||
*
|
|
||||||
* @return array<\Dxw\CIDR\IPv4Address|\Dxw\CIDR\IPv6Address>
|
|
||||||
*/
|
|
||||||
public static function getCacheList(): array
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
/** @var array<\Dxw\CIDR\IPv4Address|\Dxw\CIDR\IPv6Address>|null $ip_list */
|
|
||||||
$ip_list = Cache::get(self::$cache_key);
|
|
||||||
if (!$ip_list) {
|
|
||||||
$ip_list = self::fetchIpList();
|
|
||||||
self::validateIpList($ip_list);
|
|
||||||
self::setCacheList($ip_list);
|
|
||||||
return $ip_list;
|
|
||||||
}
|
|
||||||
return $ip_list;
|
|
||||||
} catch (AdminSecureInvalidAdressException) {
|
|
||||||
$ip_list = self::fetchIpList();
|
|
||||||
self::validateIpList($ip_list);
|
|
||||||
self::setCacheList($ip_list);
|
|
||||||
return $ip_list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set ip list to cache
|
|
||||||
*
|
|
||||||
* @param array<\Dxw\CIDR\IPv4Address|\Dxw\CIDR\IPv6Address> $ip_list
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function setCacheList(array $ip_list): void
|
|
||||||
{
|
|
||||||
Cache::put(self::$cache_key, $ip_list, \DateInterval::createFromDateString(self::$cache_ttl));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch Ip Adress list from Uwil Web
|
|
||||||
*
|
|
||||||
* @return array<\Dxw\CIDR\IPv4Address|\Dxw\CIDR\IPv6Address>
|
|
||||||
* @throws \Uwil\AdminSecure\Laravel\Exceptions\AdminSecureException If Wrong env value.
|
|
||||||
* @throws \Illuminate\Http\Client\RequestException If calling admin secure fails.
|
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
|
||||||
*/
|
|
||||||
public static function fetchIpList(): array
|
|
||||||
{
|
|
||||||
// phpcs:enable
|
|
||||||
$endpoint = self::getOptions()->getEndpoint();
|
|
||||||
$key = self::getOptions()->getApiKey();
|
|
||||||
|
|
||||||
$response = Http::get($endpoint, ['token' => $key])->throw();
|
|
||||||
$adresses = self::parseAdresses($response);
|
|
||||||
|
|
||||||
Log::info(\sprintf('ADMINSECURE : Fetched %d ip(s) from LDC WEB', \count($adresses)));
|
|
||||||
|
|
||||||
return $adresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if ipV4 is private
|
* Check if ipV4 is private
|
||||||
*
|
*
|
||||||
|
|
@ -187,34 +110,6 @@ abstract class AdminSecure
|
||||||
$initial || $ipv6_range->containsAddress($ipv6_address));
|
$initial || $ipv6_range->containsAddress($ipv6_address));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate ip list
|
|
||||||
*
|
|
||||||
* @param array $ip_list
|
|
||||||
* @return void
|
|
||||||
* @throws \Uwil\AdminSecure\Laravel\Exceptions\AdminSecureInvalidAdressException If an IP is invalid.
|
|
||||||
*/
|
|
||||||
private static function validateIpList(array $ip_list): void
|
|
||||||
{
|
|
||||||
\collect($ip_list)->each(function ($ip) {
|
|
||||||
if (!\is_object($ip) or !\in_array(\get_class($ip), [IPv4Address::class, IPv6Address::class])) {
|
|
||||||
throw new AdminSecureInvalidAdressException('Invalid adresse ' . \strval(\json_encode($ip)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse adresses
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Client\Response $response
|
|
||||||
* @return array<\Dxw\CIDR\IPv4Address|\Dxw\CIDR\IPv6Address>
|
|
||||||
*/
|
|
||||||
private static function parseAdresses(Response $response): array
|
|
||||||
{
|
|
||||||
return \collect($response->json())
|
|
||||||
->map(fn (string $ip) => IPAddress::Make($ip)->unwrap())->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Admin secure options
|
* Get Admin secure options
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,9 @@
|
||||||
|
|
||||||
namespace Uwil\AdminSecure\Laravel;
|
namespace Uwil\AdminSecure\Laravel;
|
||||||
|
|
||||||
use Illuminate\Console\Scheduling\Schedule;
|
|
||||||
use Illuminate\Contracts\Foundation\Application;
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Illuminate\Routing\Router;
|
use Illuminate\Routing\Router;
|
||||||
use Uwil\AdminSecure\Laravel\Console\SyncFromLdcWeb;
|
|
||||||
use Uwil\AdminSecure\Laravel\Http\Middleware\AdminSecureMiddleware;
|
use Uwil\AdminSecure\Laravel\Http\Middleware\AdminSecureMiddleware;
|
||||||
|
|
||||||
class AdminSecureServiceProvider extends ServiceProvider
|
class AdminSecureServiceProvider extends ServiceProvider
|
||||||
|
|
@ -22,21 +20,9 @@ class AdminSecureServiceProvider extends ServiceProvider
|
||||||
__DIR__ . '/../config' => config_path(),
|
__DIR__ . '/../config' => config_path(),
|
||||||
], 'config');
|
], 'config');
|
||||||
|
|
||||||
// * Register the command if we are using the application via the CLI .
|
|
||||||
$this->commands([SyncFromLdcWeb::class]);
|
|
||||||
|
|
||||||
// * Set filter condition
|
// * Set filter condition
|
||||||
$this->app->singleton('hasToFilterIp', fn (Application $app) => $app->environment('production', 'staging'));
|
$this->app->singleton('hasToFilterIp', fn (Application $app) => $app->environment('production', 'staging'));
|
||||||
|
|
||||||
// * Cron Report everyday
|
|
||||||
$this->app->booted(function () {
|
|
||||||
if ($this->app->make('hasToFilterIp')) {
|
|
||||||
/** @var \Illuminate\Console\Scheduling\Schedule */
|
|
||||||
$schedule = $this->app->make(Schedule::class);
|
|
||||||
$schedule->command('uwil:admin-secure:sync')->daily();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/** @var \Illuminate\Routing\Router */
|
/** @var \Illuminate\Routing\Router */
|
||||||
$router = $this->app->make(Router::class);
|
$router = $this->app->make(Router::class);
|
||||||
$router->aliasMiddleware('admin-secure', AdminSecureMiddleware::class);
|
$router->aliasMiddleware('admin-secure', AdminSecureMiddleware::class);
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Uwil\AdminSecure\Laravel\Console;
|
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Uwil\AdminSecure\Laravel\AdminSecure;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send Report Status To LDC Web.
|
|
||||||
*
|
|
||||||
* @author Vincent BRIDIER <vincent.bridier@ldc.fr>
|
|
||||||
*/
|
|
||||||
class SyncFromLdcWeb extends Command
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The name and signature of the console command.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $signature = 'uwil:admin-secure:sync';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The console command description.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $description = 'Sync IP list from LDC Web';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the console command.
|
|
||||||
*
|
|
||||||
* @return integer
|
|
||||||
* @throws \Uwil\AdminSecure\Laravel\Exceptions\AdminSecureException If missing LDC_WEB_API_KEY key.
|
|
||||||
*/
|
|
||||||
public function handle(): int
|
|
||||||
{
|
|
||||||
$this->info($this->description);
|
|
||||||
AdminSecure::setCacheList(AdminSecure::fetchIpList());
|
|
||||||
$this->info('Done.');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Uwil\AdminSecure\Laravel\Exceptions;
|
|
||||||
|
|
||||||
class AdminSecureInvalidAdressException extends AdminSecureException
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
@ -4,9 +4,7 @@ namespace Uwil\AdminSecure\Laravel\Http\Middleware;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Dxw\CIDR\IP;
|
use Dxw\CIDR\IP;
|
||||||
use Dxw\CIDR\IPv4Address;
|
|
||||||
use Dxw\CIDR\IPv4Range;
|
use Dxw\CIDR\IPv4Range;
|
||||||
use Dxw\CIDR\IPv6Address;
|
|
||||||
use Dxw\CIDR\IPv6Range;
|
use Dxw\CIDR\IPv6Range;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Uwil\AdminSecure\Laravel\AdminSecure;
|
use Uwil\AdminSecure\Laravel\AdminSecure;
|
||||||
|
|
@ -27,9 +25,10 @@ class AdminSecureMiddleware
|
||||||
}
|
}
|
||||||
|
|
||||||
$client_ip = AdminSecure::fetchClientIp();
|
$client_ip = AdminSecure::fetchClientIp();
|
||||||
$ip_is_allowed = \collect(AdminSecure::getCacheList())
|
|
||||||
->reduce(fn (null|bool $initial, IPv4Address|IPv6Address $ip_address) => $initial || IP::contains(
|
$ip_is_allowed = \collect(AdminSecure::getOptions()->getCidrList())
|
||||||
$ip_address,
|
->reduce(fn (null|bool $initial, IPv4Range|IPv6Range $ip_range) => $initial || IP::contains(
|
||||||
|
$ip_range,
|
||||||
$client_ip
|
$client_ip
|
||||||
)->unwrap());
|
)->unwrap());
|
||||||
|
|
||||||
|
|
|
||||||
118
src/Options.php
118
src/Options.php
|
|
@ -30,7 +30,7 @@ final class Options
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static string $cache_config_key = 'ldcweb_ip_cidr_config_list';
|
private static string $cache_config_key = 'uwil_ip_cidr_config_list';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class constructor.
|
* Class constructor.
|
||||||
|
|
@ -47,33 +47,23 @@ final class Options
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get end point url
|
* Get cidr list
|
||||||
*
|
*
|
||||||
* @return string
|
* @return array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range>
|
||||||
*/
|
*/
|
||||||
public function getEndpoint(): string
|
public function getCidrList(): array
|
||||||
{
|
{
|
||||||
return $this->options['endpoint'];
|
return $this->options['cidrList'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get api key
|
* Get cidr project allowed list
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getApiKey(): string
|
|
||||||
{
|
|
||||||
return $this->options['apiKey'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get cidr allowed list
|
|
||||||
*
|
*
|
||||||
* @return array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range>
|
* @return array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range>
|
||||||
*/
|
*/
|
||||||
public function getCidrAllowedList(): array
|
public function getCidrAllowedList(): array
|
||||||
{
|
{
|
||||||
return $this->options['cidrManualAllowedList'];
|
return $this->options['cidrProjectAllowedList'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -85,34 +75,19 @@ final class Options
|
||||||
private function configureOptions(OptionsResolver $resolver): void
|
private function configureOptions(OptionsResolver $resolver): void
|
||||||
{
|
{
|
||||||
$resolver->setDefaults([
|
$resolver->setDefaults([
|
||||||
'endpoint' => '',
|
'cidrList' => [],
|
||||||
'apiKey' => '',
|
'cidrProjectAllowedList' => []
|
||||||
'cidrManualAllowedList' => []
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$resolver->setAllowedTypes('endpoint', [
|
$resolver->setNormalizer('cidrList', \Closure::fromCallable([$this, 'normalizeCidrList']));
|
||||||
'string', \Closure::fromCallable([$this, 'validateEndpoint'])
|
$resolver->setNormalizer('cidrProjectAllowedList', \Closure::fromCallable([$this, 'normalizeCidrProjectList']));
|
||||||
]);
|
|
||||||
$resolver->setAllowedTypes('apiKey', 'string');
|
|
||||||
$resolver->setNormalizer('cidrManualAllowedList', \Closure::fromCallable([$this, 'normalizeCidrList']));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate endpoint
|
* Normalise Cidr list for cidrList option
|
||||||
*
|
|
||||||
* @param null|string $value
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
private function validateEndpoint(?string $value): bool
|
|
||||||
{
|
|
||||||
return !(!$value or !\filter_var($value, \FILTER_VALIDATE_URL));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalise Cidr list
|
|
||||||
*
|
*
|
||||||
* @param \Symfony\Component\OptionsResolver\Options $options
|
* @param \Symfony\Component\OptionsResolver\Options $options
|
||||||
* @param string $value
|
* @param string|null $value
|
||||||
* @return array
|
* @return array
|
||||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
*/
|
*/
|
||||||
|
|
@ -121,31 +96,60 @@ final class Options
|
||||||
?string $value
|
?string $value
|
||||||
): array {
|
): array {
|
||||||
// phpcs:enable
|
// phpcs:enable
|
||||||
|
return $this->doNormalizeCidrList($value, 'cidrList');
|
||||||
|
}
|
||||||
|
|
||||||
$allowed_cidr_config_list = collect(explode(',', strval($value)))->filter();
|
/**
|
||||||
|
* Normalise Cidr list for cidrProjectAllowedList option
|
||||||
|
*
|
||||||
|
* @param \Symfony\Component\OptionsResolver\Options $options
|
||||||
|
* @param string|null $value
|
||||||
|
* @return array
|
||||||
|
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
|
*/
|
||||||
|
private function normalizeCidrProjectList(
|
||||||
|
\Symfony\Component\OptionsResolver\Options $options,
|
||||||
|
?string $value
|
||||||
|
): array {
|
||||||
|
// phpcs:enable
|
||||||
|
return $this->doNormalizeCidrList($value, 'cidrProjectAllowedList');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize CIDR list with specific cache key.
|
||||||
|
*
|
||||||
|
* @param string|null $value
|
||||||
|
* @param string $optionName
|
||||||
|
* @return array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range>
|
||||||
|
*/
|
||||||
|
private function doNormalizeCidrList(?string $value, string $optionName): array
|
||||||
|
{
|
||||||
|
$cacheConfigKey = self::$cache_config_key . '_' . $optionName;
|
||||||
|
$allowed_cidr_config_list = collect(explode(',', strval($value)))->filter();
|
||||||
$allowed_cidr_config_list_hash = \md5($allowed_cidr_config_list->implode(','));
|
$allowed_cidr_config_list_hash = \md5($allowed_cidr_config_list->implode(','));
|
||||||
/** @var array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range> $allowed_cidr_list */
|
|
||||||
$allowed_cidr_list = $allowed_cidr_config_list
|
|
||||||
->map(function (string $cidr) {
|
|
||||||
$ip_range = !IPv4Range::Make($cidr)->isErr() ? IPv4Range::Make($cidr) : IPv6Range::Make($cidr);
|
|
||||||
if ($ip_range->isErr()) {
|
|
||||||
throw new AdminSecureException(\trans(
|
|
||||||
'LDC_WEB_CIDR_MANUAL_ALLOWED_LIST not valid (ipv4 or ipv6 cidr) :cidr',
|
|
||||||
[
|
|
||||||
'cidr' => $cidr
|
|
||||||
]
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return $ip_range->unwrap();
|
|
||||||
})->all();
|
|
||||||
|
|
||||||
// * Flush cache if hash config hash changed
|
// Flush cache if config hash changed
|
||||||
if ($allowed_cidr_config_list_hash !== \collect(Cache::get(self::$cache_config_key))->get('hash')) {
|
if ($allowed_cidr_config_list_hash !== \collect(Cache::get($cacheConfigKey))->get('hash')) {
|
||||||
Cache::forget(self::$cache_config_key);
|
Cache::forget($cacheConfigKey);
|
||||||
|
|
||||||
|
/** @var array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range> $allowed_cidr_list */
|
||||||
|
$allowed_cidr_list = $allowed_cidr_config_list
|
||||||
|
->map(function (string $cidr) {
|
||||||
|
$ip_range = !IPv4Range::Make($cidr)->isErr() ? IPv4Range::Make($cidr) : IPv6Range::Make($cidr);
|
||||||
|
if ($ip_range->isErr()) {
|
||||||
|
throw new AdminSecureException(\trans(
|
||||||
|
'CIDR LIST not valid (ipv4 or ipv6 cidr) :cidr',
|
||||||
|
[
|
||||||
|
'cidr' => $cidr
|
||||||
|
]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return $ip_range->unwrap();
|
||||||
|
})->all();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range> $allowed_cidr_list */
|
/** @var array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range> $allowed_cidr_list */
|
||||||
return \collect(Cache::rememberForever(self::$cache_config_key, fn () => [
|
return \collect(Cache::rememberForever($cacheConfigKey, fn() => [
|
||||||
'list' => $allowed_cidr_list,
|
'list' => $allowed_cidr_list,
|
||||||
'hash' => $allowed_cidr_config_list_hash
|
'hash' => $allowed_cidr_config_list_hash
|
||||||
]))->get('list');
|
]))->get('list');
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue