From fee6f4e0821415d52f8f0db13dca57baec5fb5dd Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Wed, 10 Jul 2024 08:41:14 +0100 Subject: [PATCH] Issue #3456738 by cmlara, Anybody, andrewbelcher, Berdir, catch: BC break in login auth changes from #3444978 (cherry picked from commit e015f80827e2a92da1a1cd7f13bd7e47b453b956) --- .../UserAuthenticationController.php | 2 +- core/modules/user/src/Form/UserLoginForm.php | 7 ++++ .../src/UserAuthDecorator.php | 28 ++++++++++++++++ .../user_auth_decorator_test.info.yml | 5 +++ .../user_auth_decorator_test.services.yml | 6 ++++ .../Rest/UserJsonBasicAuthDecoratedTest.php | 31 +++++++++++++++++ .../src/Functional/UserLoginDecoratedTest.php | 33 +++++++++++++++++++ .../Functional/UserLoginHttpDecoratedTest.php | 33 +++++++++++++++++++ 8 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 core/modules/user/tests/modules/user_auth_decorator_test/src/UserAuthDecorator.php create mode 100644 core/modules/user/tests/modules/user_auth_decorator_test/user_auth_decorator_test.info.yml create mode 100644 core/modules/user/tests/modules/user_auth_decorator_test/user_auth_decorator_test.services.yml create mode 100644 core/modules/user/tests/src/Functional/Rest/UserJsonBasicAuthDecoratedTest.php create mode 100644 core/modules/user/tests/src/Functional/UserLoginDecoratedTest.php create mode 100644 core/modules/user/tests/src/Functional/UserLoginHttpDecoratedTest.php diff --git a/core/modules/user/src/Controller/UserAuthenticationController.php b/core/modules/user/src/Controller/UserAuthenticationController.php index 7758b0d96d2f..af31a878ddcc 100644 --- a/core/modules/user/src/Controller/UserAuthenticationController.php +++ b/core/modules/user/src/Controller/UserAuthenticationController.php @@ -201,7 +201,7 @@ public function login(Request $request) { $authenticated = $this->userAuth->authenticateAccount($account, $credentials['pass']) ? $account->id() : FALSE; } else { - $authenticated = $this->userAuth->authenticateAccount($credentials['name'], $credentials['pass']); + $authenticated = $this->userAuth->authenticate($credentials['name'], $credentials['pass']); } if ($authenticated) { $this->userFloodControl->clear('user.http_login', $this->getLoginFloodIdentifier($request, $credentials['name'])); diff --git a/core/modules/user/src/Form/UserLoginForm.php b/core/modules/user/src/Form/UserLoginForm.php index 8fe696d15a53..33e6653eb154 100644 --- a/core/modules/user/src/Form/UserLoginForm.php +++ b/core/modules/user/src/Form/UserLoginForm.php @@ -246,6 +246,13 @@ public function validateAuthentication(array &$form, FormStateInterface $form_st if ($this->userAuth instanceof UserAuthenticationInterface) { $form_state->set('uid', $this->userAuth->authenticateAccount($account, $password) ? $account->id() : FALSE); } + // The userAuth object is decorated by an object that that has not + // been upgraded to the new UserAuthenticationInterface. Fallback + // to the authenticate() method. + else { + $uid = $this->userAuth->authenticate($form_state->getValue('name'), $password); + $form_state->set('uid', $uid); + } } elseif (!$this->userAuth instanceof UserAuthenticationInterface) { $uid = $this->userAuth->authenticate($form_state->getValue('name'), $password); diff --git a/core/modules/user/tests/modules/user_auth_decorator_test/src/UserAuthDecorator.php b/core/modules/user/tests/modules/user_auth_decorator_test/src/UserAuthDecorator.php new file mode 100644 index 000000000000..fc2fd1a5c8fb --- /dev/null +++ b/core/modules/user/tests/modules/user_auth_decorator_test/src/UserAuthDecorator.php @@ -0,0 +1,28 @@ +<?php + +namespace Drupal\user_auth_decorator_test; + +use Drupal\user\UserAuthInterface; + +/** + * Helper to validate UserAuthInterface BC layers are functional. + */ +class UserAuthDecorator implements UserAuthInterface { + + /** + * Constructs a UserAuthDecorator object. + * + * @param \Drupal\user\UserAuthInterface $inner + * The inner User.Auth service. + */ + public function __construct(protected UserAuthInterface $inner) { + } + + /** + * {@inheritdoc} + */ + public function authenticate($username, #[\SensitiveParameter] $password) { + return $this->inner->authenticate($username, $password); + } + +} diff --git a/core/modules/user/tests/modules/user_auth_decorator_test/user_auth_decorator_test.info.yml b/core/modules/user/tests/modules/user_auth_decorator_test/user_auth_decorator_test.info.yml new file mode 100644 index 000000000000..a05dfd67c2ee --- /dev/null +++ b/core/modules/user/tests/modules/user_auth_decorator_test/user_auth_decorator_test.info.yml @@ -0,0 +1,5 @@ +name: 'User Auth Service decorated only with UserAuthInterface' +type: module +description: 'Support module for user authentication testing.' +package: Testing +version: VERSION diff --git a/core/modules/user/tests/modules/user_auth_decorator_test/user_auth_decorator_test.services.yml b/core/modules/user/tests/modules/user_auth_decorator_test/user_auth_decorator_test.services.yml new file mode 100644 index 000000000000..c274386664cb --- /dev/null +++ b/core/modules/user/tests/modules/user_auth_decorator_test/user_auth_decorator_test.services.yml @@ -0,0 +1,6 @@ +services: + user_auth_decorator.user.auth: + class: \Drupal\user_auth_decorator_test\UserAuthDecorator + decorates: user.auth + arguments: + - '@user_auth_decorator.user.auth.inner' diff --git a/core/modules/user/tests/src/Functional/Rest/UserJsonBasicAuthDecoratedTest.php b/core/modules/user/tests/src/Functional/Rest/UserJsonBasicAuthDecoratedTest.php new file mode 100644 index 000000000000..463852243dec --- /dev/null +++ b/core/modules/user/tests/src/Functional/Rest/UserJsonBasicAuthDecoratedTest.php @@ -0,0 +1,31 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\user\Functional\Rest; + +use Drupal\user_auth_decorator_test\UserAuthDecorator; + +/** + * Run UserJsonBasicAuthTest with a user.auth decorator. + * + * @group rest + * @group #slow + */ +class UserJsonBasicAuthDecoratedTest extends UserJsonBasicAuthTest { + /** + * Modules to install. + * + * @var array + */ + protected static $modules = ['user_auth_decorator_test']; + + /** + * Test that the UserAuthDecorator is providing user.auth. + */ + public function testServiceDecorated(): void { + $service = \Drupal::service('user.auth'); + $this->assertInstanceOf(UserAuthDecorator::class, $service); + } + +} diff --git a/core/modules/user/tests/src/Functional/UserLoginDecoratedTest.php b/core/modules/user/tests/src/Functional/UserLoginDecoratedTest.php new file mode 100644 index 000000000000..2f09b03927d5 --- /dev/null +++ b/core/modules/user/tests/src/Functional/UserLoginDecoratedTest.php @@ -0,0 +1,33 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\user\Functional; + +use Drupal\user_auth_decorator_test\UserAuthDecorator; + +/** + * Ensure that login works as expected with a decorator. + * + * The decorator does not implement UserAuthenticationInterface. + * + * @group user + */ +class UserLoginDecoratedTest extends UserLoginTest { + + /** + * Modules to install. + * + * @var array + */ + protected static $modules = ['user_auth_decorator_test']; + + /** + * Test that the UserAuthDecorator is providing user.auth. + */ + public function testServiceDecorated(): void { + $service = \Drupal::service('user.auth'); + $this->assertInstanceOf(UserAuthDecorator::class, $service); + } + +} diff --git a/core/modules/user/tests/src/Functional/UserLoginHttpDecoratedTest.php b/core/modules/user/tests/src/Functional/UserLoginHttpDecoratedTest.php new file mode 100644 index 000000000000..71ab498faf4f --- /dev/null +++ b/core/modules/user/tests/src/Functional/UserLoginHttpDecoratedTest.php @@ -0,0 +1,33 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\user\Functional; + +use Drupal\user_auth_decorator_test\UserAuthDecorator; + +/** + * Tests login and password reset via direct HTTP with a user.auth decorator. + * + * The decorator does not implement UserAuthenticationInterface. + * + * @group user + */ +class UserLoginHttpDecoratedTest extends UserLoginHttpTest { + + /** + * Modules to install. + * + * @var array + */ + protected static $modules = ['user_auth_decorator_test']; + + /** + * Test that the UserAuthDecorator is providing user.auth. + */ + public function testServiceDecorated(): void { + $service = \Drupal::service('user.auth'); + $this->assertInstanceOf(UserAuthDecorator::class, $service); + } + +} -- GitLab