diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2daa8a5b2d9e725a9252658d557d12cc33fb2241..2ab312e04a25c65347969cbbb81f2b96d31bcc1e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,91 +1,34 @@ ################ -# DrupalCI GitLabCI template +# GitLabCI template for Drupal projects. # -# Gitlab-ci.yml to replicate DrupalCI testing for Contrib -# -# With thanks to: -# * The GitLab Acceleration Initiative participants -# * DrupalSpoons -################ - -################ -# Guidelines -# -# This template is designed to give any Contrib maintainer everything they need to test, without requiring modification. It is also designed to keep up to date with Core Development automatically through the use of include files that can be centrally maintained. -# -# However, you can modify this template if you have additional needs for your project. -################ - -################ -# Includes -# -# Additional configuration can be provided through includes. -# One advantage of include files is that if they are updated upstream, the changes affect all pipelines using that include. -# -# Includes can be overridden by re-declaring anything provided in an include, here in gitlab-ci.yml -# https://docs.gitlab.com/ee/ci/yaml/includes.html#override-included-configuration-values +# This template is designed to give any Contrib maintainer everything they need to test, without requiring modification. +# It is also designed to keep up to date with Core Development automatically through the use of include files that can be centrally maintained. +# As long as you include the project, ref and three files below, any future updates added by the Drupal Association will be used in your +# pipelines automatically. However, you can modify this template if you have additional needs for your project. +# The full documentation is on https://project.pages.drupalcode.org/gitlab_templates/ ################ +# For information on alternative values for 'ref' see https://project.pages.drupalcode.org/gitlab_templates/info/templates-version/ +# To test a Drupal 7 project, change the first include filename from .main.yml to .main-d7.yml include: - ################ - # DrupalCI includes: - # As long as you include this, any future includes added by the Drupal Association will be accessible to your pipelines automatically. - # View these include files at https://git.drupalcode.org/project/gitlab_templates/ - ################ - project: $_GITLAB_TEMPLATES_REPO ref: $_GITLAB_TEMPLATES_REF file: - '/includes/include.drupalci.main.yml' - '/includes/include.drupalci.variables.yml' - '/includes/include.drupalci.workflows.yml' - -################ -# Pipeline configuration variables # -# These are the variables provided to the Run Pipeline form that a user may want to override. -# -# Docs at https://git.drupalcode.org/project/gitlab_templates/-/blob/1.0.x/includes/include.drupalci.variables.yml ################ -variables: - # Disabling the default phpunit job in favor of the d9/10 variants described below. - SKIP_PHPUNIT: 1 - -# Run two variations of composer job. -composer: - parallel: - matrix: - - _TARGET_PHP: [ "7.4" ] - _TARGET_CORE: [ "9.5.x" ] - - _TARGET_PHP: [ "$CORE_PHP_MIN" ] - _TARGET_CORE: [ "$CORE_STABLE" ] - +# Pipeline configuration variables are defined with default values and descriptions in the file +# https://git.drupalcode.org/project/gitlab_templates/-/blob/main/includes/include.drupalci.variables.yml +# Uncomment the lines below if you want to override any of the variables. The following is just an example. +################ -# Drupal Hook Mail tests section. -.phpunit-local: - variables: - SKIP_PHPUNIT: 0 -phpunit-d9: - needs: - - job: composer - parallel: - matrix: - - _TARGET_PHP: "7.4" - _TARGET_CORE: "9.5.x" - variables: - _TARGET_PHP: "7.4" - extends: - - .phpunit-base - - .phpunit-local +variables: -phpunit-d10: - needs: - - job: composer - parallel: - matrix: - - _TARGET_PHP: $CORE_PHP_MIN - _TARGET_CORE: $CORE_STABLE - variables: - _TARGET_PHP: $CORE_PHP_MIN - extends: - - .phpunit-base - - .phpunit-local + # Broaden test coverage. + OPT_IN_TEST_PREVIOUS_MINOR: 1 + OPT_IN_TEST_PREVIOUS_MAJOR: 1 + OPT_IN_TEST_NEXT_MINOR: 1 + OPT_IN_TEST_NEXT_MAJOR: 1 + OPT_IN_TEST_MAX_PHP: 1 diff --git a/phpstan.neon b/phpstan.neon deleted file mode 100644 index 3c0e29e346aae3357dc681f6173a23a1b29eee02..0000000000000000000000000000000000000000 --- a/phpstan.neon +++ /dev/null @@ -1,18 +0,0 @@ -# Configuration file for PHPStan static code checking. -# @see: https://git.drupalcode.org/project/drupal/-/blob/10.0.x/core/phpstan.neon.dist - -parameters: - - level: 1 - - ignoreErrors: - # new static() is a best practice in Drupal, so we cannot fix that. - # @see https://www.drupal.org/docs/develop/development-tools/phpstan/handling-unsafe-usage-of-new-static - - "#^Unsafe usage of new static#" - - # Ignore common errors for now. - - "#Drupal calls should be avoided in classes, use dependency injection instead#" - - "#^Plugin definitions cannot be altered.#" - - "#^Missing cache backend declaration for performance.#" - - "#cache tag might be unclear and does not contain the cache key in it.#" - - "#^Class .* extends @internal class#" diff --git a/reverse_proxy_header.info.yml b/reverse_proxy_header.info.yml index 59e840d7ce6798efdc90dbc865f017a2805252f4..bff3012f9cdc0ad405bad55501a513b9dac80441 100644 --- a/reverse_proxy_header.info.yml +++ b/reverse_proxy_header.info.yml @@ -1,5 +1,5 @@ name: Reverse Proxy Header type: module package: Other -core_version_requirement: ^9 || ^10 +core_version_requirement: ^10.3 || ^11 description: 'Provides an ability to use the specific HTTP header name to determine the client IP.' diff --git a/reverse_proxy_header.services.yml b/reverse_proxy_header.services.yml index f563bd81fde6562e26b1545dddc36d5dc9c859de..50a286d603b072303e56fdb12ed2aab95c6987ae 100644 --- a/reverse_proxy_header.services.yml +++ b/reverse_proxy_header.services.yml @@ -1,5 +1,5 @@ services: - reverse_proxy_header.clientiprestore: + reverse_proxy_header.client_ip_restore: class: Drupal\reverse_proxy_header\EventSubscriber\ReverseProxyHeaderClientIpRestore arguments: ['@http_client', '@settings', '@logger.channel.reverse_proxy_header'] tags: diff --git a/src/EventSubscriber/ReverseProxyHeaderClientIpRestore.php b/src/EventSubscriber/ReverseProxyHeaderClientIpRestore.php index f5217455c1d64d4536637c951ec0108a9fcd63ce..0ae60453efe6a7efc3dccb9b8ab184eb538004a0 100644 --- a/src/EventSubscriber/ReverseProxyHeaderClientIpRestore.php +++ b/src/EventSubscriber/ReverseProxyHeaderClientIpRestore.php @@ -19,21 +19,21 @@ class ReverseProxyHeaderClientIpRestore implements EventSubscriberInterface { * * @var \GuzzleHttp\ClientInterface */ - protected $httpClient; + protected ClientInterface $httpClient; /** * The settings object. * * @var \Drupal\Core\Site\Settings */ - protected $settings; + protected Settings $settings; /** * The logger. * * @var \Psr\Log\LoggerInterface */ - protected $logger; + protected LoggerInterface $logger; /** * Constructs a ReverseProxyHeaderClientIpRestore. @@ -45,7 +45,11 @@ class ReverseProxyHeaderClientIpRestore implements EventSubscriberInterface { * @param \Psr\Log\LoggerInterface $logger * The reverse_proxy_header logger channel. */ - public function __construct(ClientInterface $http_client, Settings $settings, LoggerInterface $logger) { + public function __construct( + ClientInterface $http_client, + Settings $settings, + LoggerInterface $logger, + ) { $this->httpClient = $http_client; $this->settings = $settings; $this->logger = $logger; @@ -54,7 +58,7 @@ class ReverseProxyHeaderClientIpRestore implements EventSubscriberInterface { /** * {@inheritdoc} */ - public static function getSubscribedEvents() { + public static function getSubscribedEvents(): array { // Priority is set to 350 (to run before RouterListener::onKernelRequest). // Which allows AuthenticationSubscriber methods to use the request IP. // @see \Symfony\Component\HttpKernel\EventListener\RouterListener::getSubscribedEvents @@ -67,7 +71,7 @@ class ReverseProxyHeaderClientIpRestore implements EventSubscriberInterface { /** * Restores the origination client IP from the custom HTTP header. */ - public function onRequest(RequestEvent $event) { + public function onRequest(RequestEvent $event): void { // Check the available settings. $reverse_proxy_header_name = $this->settings->get('reverse_proxy_header'); @@ -101,7 +105,10 @@ class ReverseProxyHeaderClientIpRestore implements EventSubscriberInterface { * @return bool * Return TRUE if IP address is invalid. */ - protected function isInvalidIpAddress($ip_address, $header_name) { + protected function isInvalidIpAddress( + string $ip_address, + string $header_name, + ): bool { $variables = [ '@ip_address' => $ip_address, '@header_name' => $header_name, diff --git a/tests/src/Kernel/ClientIpRestoreTest.php b/tests/src/Kernel/ClientIpRestoreTest.php index 4316c8c88e448e82a5de6e97bf6a87ddaac1d9ec..9d40e2db09b1051a6b59604c697a24fa7df730f2 100644 --- a/tests/src/Kernel/ClientIpRestoreTest.php +++ b/tests/src/Kernel/ClientIpRestoreTest.php @@ -21,7 +21,11 @@ class ClientIpRestoreTest extends ReverseProxyHeaderTestBase { * * @dataProvider providerClientIpsHeaders */ - public function testValidIps($header_name, $valid_ip, $invalid_ip) { + public function testValidIps( + string $header_name, + string $valid_ip, + string $invalid_ip, + ): void { $request = $this->reverseProxyHeaderRequest($header_name, $valid_ip); $this->assertEquals($request->getClientIp(), $valid_ip); } @@ -38,7 +42,11 @@ class ClientIpRestoreTest extends ReverseProxyHeaderTestBase { * * @dataProvider providerClientIpsHeaders */ - public function testInvalidIps($header_name, $valid_ip, $invalid_ip) { + public function testInvalidIps( + string $header_name, + string $valid_ip, + string $invalid_ip, + ): void { $this->reverseProxyHeaderRequest($header_name, $invalid_ip); $this->assertInvalidIpNoticeExist($invalid_ip, $header_name); } @@ -49,7 +57,7 @@ class ClientIpRestoreTest extends ReverseProxyHeaderTestBase { * @return array * Test Data to simulate incoming IP address. */ - public function providerClientIpsHeaders() { + public static function providerClientIpsHeaders(): array { return [ [ // It should work well with default headers as well. diff --git a/tests/src/Kernel/ReverseProxyHeaderTestBase.php b/tests/src/Kernel/ReverseProxyHeaderTestBase.php index dae664d60fe8f5a6bc2df30e09d937d4231ac28b..47036f1b51c3d97c8b4f6c88399132be63487a5d 100644 --- a/tests/src/Kernel/ReverseProxyHeaderTestBase.php +++ b/tests/src/Kernel/ReverseProxyHeaderTestBase.php @@ -5,15 +5,17 @@ namespace Drupal\Tests\reverse_proxy_header\Kernel; use Composer\Autoload\ClassLoader; use Drupal\Core\Database\Database; use Drupal\Core\DrupalKernel; -use Drupal\Core\Logger\LoggerChannelFactory; use Drupal\Core\Logger\LogMessageParser; +use Drupal\Core\Logger\LoggerChannelFactory; use Drupal\Core\Logger\RfcLogLevel; +use Drupal\Core\Session\AccountInterface; use Drupal\Core\Site\Settings; -use Drupal\dblog\Logger\DbLog; use Drupal\KernelTests\KernelTestBase; +use Drupal\dblog\Logger\DbLog; use Drupal\reverse_proxy_header\EventSubscriber\ReverseProxyHeaderClientIpRestore; use GuzzleHttp\Client; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -47,7 +49,10 @@ abstract class ReverseProxyHeaderTestBase extends KernelTestBase { * @return \Symfony\Component\HttpFoundation\Request * Return the request object. */ - public function reverseProxyHeaderRequest($header, $expected_client_ip) { + public function reverseProxyHeaderRequest( + string $header, + string $expected_client_ip, + ): Request { $client = new Client(); $auto_loader = new ClassLoader(); $request = Request::create('test'); @@ -57,13 +62,16 @@ abstract class ReverseProxyHeaderTestBase extends KernelTestBase { // Set server parameter reverse_proxy_header as expected client ip. $request->server->set($header, $expected_client_ip); - $logger = (new LoggerChannelFactory())->get('reverse_proxy_header'); + $logger = (new LoggerChannelFactory( + $this->createMock(RequestStack::class), + $this->createMock(AccountInterface::class), + ))->get('reverse_proxy_header'); $logger->addLogger(new DbLog(Database::getConnection(), new LogMessageParser())); $reverse_proxy_header_client_ip_restore_service = new ReverseProxyHeaderClientIpRestore($client, new Settings(Settings::getAll() + ['reverse_proxy_header' => $header]), $logger); $kernel = $this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface'); - $event = new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST); + $event = new RequestEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST); $reverse_proxy_header_client_ip_restore_service->onRequest($event); return $request; } @@ -76,7 +84,10 @@ abstract class ReverseProxyHeaderTestBase extends KernelTestBase { * @param string $header_name * The header name. */ - protected function assertInvalidIpNoticeExist($ip_address, $header_name) { + protected function assertInvalidIpNoticeExist( + string $ip_address, + string $header_name, + ): void { // Prepare the message and its arguments for testing. if (empty($ip_address)) { $message = 'Empty IP address value retrieved from @header_name header is invalid.';