The configuration options. */ private $options; /** @var \Symfony\Component\OptionsResolver\OptionsResolver The options resolver. */ private $resolver; /** @var string The cache key where to store config cidr list. */ private static string $cache_config_key = 'uwil_ip_cidr_config_list'; /** * Class constructor. * * @param array $options The configuration options. */ public function __construct(array $options = []) { $this->resolver = new OptionsResolver(); $this->configureOptions($this->resolver); $this->options = $this->resolver->resolve($options); } /** * Get cidr list. * * @return array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range> */ public function getCidrList(): array { return $this->options['cidrList']; } /** * Get cidr project allowed list. * * @return array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range> */ public function getCidrAllowedList(): array { return $this->options['cidrProjectAllowedList']; } /** * Configures the options of the client. * * @param \Symfony\Component\OptionsResolver\OptionsResolver $resolver The resolver for the options. */ private function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'cidrList' => [], 'cidrProjectAllowedList' => [], ]); $resolver->setNormalizer('cidrList', $this->normalizeCidrList(...)); $resolver->setNormalizer('cidrProjectAllowedList', $this->normalizeCidrProjectList(...)); } /** * Normalise Cidr list for cidrList option. * * @return array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range> * * @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed */ private function normalizeCidrList( \Symfony\Component\OptionsResolver\Options $options, ?string $value ): array { // phpcs:enable return $this->doNormalizeCidrList($value, 'cidrList'); } /** * Normalise Cidr list for cidrProjectAllowedList option. * * @return array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range> * * @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. * * @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(',')); /** @var array{list: array<\Dxw\CIDR\IPv4Range|\Dxw\CIDR\IPv6Range>, hash: string}|null $cached */ $cached = Cache::get($cacheConfigKey); // Flush cache if config hash changed if ($cached === null || $cached['hash'] !== $allowed_cidr_config_list_hash) { 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(); Cache::forever($cacheConfigKey, [ 'list' => $allowed_cidr_list, 'hash' => $allowed_cidr_config_list_hash, ]); return $allowed_cidr_list; } return $cached['list']; } }