From 57a9309a09dec1076bc2ada8c26259f4365e00e7 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Tue, 25 Jul 2023 10:51:49 +0100 Subject: [PATCH] Issue #2881572 by Bhanu951, paulocs, catch, Spokje, munish.kumar, vijaycs85, ranjith_kumar_k_u, vikashsoni, smustgrave, heddn, larowlan, lauriii: User login flood lock doesn't clear when reset password as admin --- core/modules/user/src/Entity/User.php | 13 +++++ .../src/Functional/UserPasswordResetTest.php | 51 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php index 75a35a9ac305..2af4c9b846d0 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\Flood\PrefixFloodInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\user\RoleInterface; use Drupal\user\StatusItem; @@ -125,6 +126,18 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { if ($this->id() == \Drupal::currentUser()->id()) { \Drupal::service('session')->migrate(); } + + $flood_config = \Drupal::config('user.flood'); + $flood_service = \Drupal::flood(); + $identifier = $this->id(); + if ($flood_config->get('uid_only')) { + // Clear flood events based on the uid only if configured. + $flood_service->clear('user.failed_login_user', $identifier); + } + elseif ($flood_service instanceof PrefixFloodInterface) { + $flood_service->clearByPrefix('user.failed_login_user', $identifier); + } + } // If the user was blocked, delete the user's sessions to force a logout. diff --git a/core/modules/user/tests/src/Functional/UserPasswordResetTest.php b/core/modules/user/tests/src/Functional/UserPasswordResetTest.php index 19f97cba42f0..ca40e9a66210 100644 --- a/core/modules/user/tests/src/Functional/UserPasswordResetTest.php +++ b/core/modules/user/tests/src/Functional/UserPasswordResetTest.php @@ -494,6 +494,57 @@ public function testUserResetPasswordUserFloodControlIsCleared() { $this->assertCount($before + 4, $this->drupalGetMails(['id' => 'user_password_reset']), 'Another email was sent after clearing flood control.'); } + /** + * Tests user password reset flood control is cleared on admin reset. + */ + public function testUserResetPasswordUserFloodControlAdmin() { + $admin_user = $this->drupalCreateUser([ + 'administer account settings', + 'administer users', + ]); + \Drupal::configFactory()->getEditable('user.flood') + ->set('user_limit', 3) + ->save(); + + $edit = [ + 'name' => $this->account->getAccountName(), + 'pass' => 'wrong_password', + ]; + + // Try 3 requests that should not trigger flood control. + for ($i = 0; $i < 3; $i++) { + $this->drupalGet('user/login'); + $this->submitForm($edit, 'Log in'); + $this->assertSession()->pageTextNotContains('There have been more than 3 failed login attempts for this account. It is temporarily blocked.'); + } + $this->drupalGet('user/login'); + $this->submitForm($edit, 'Log in'); + $this->assertSession()->pageTextContains('There have been more than 3 failed login attempts for this account. It is temporarily blocked.'); + + $password = $this->randomMachineName(); + $edit = [ + 'pass[pass1]' => $password, + 'pass[pass2]' => $password, + ]; + // Log in as admin and change the user password. + $this->drupalLogin($admin_user); + $this->drupalGet('user/' . $this->account->id() . '/edit'); + $this->submitForm($edit, 'Save'); + $this->drupalLogout(); + + $edit = [ + 'name' => $this->account->getAccountName(), + 'pass' => $password, + ]; + + // The next request should *not* trigger flood control, since the + // password change should have cleared flood events for this user. + $this->account->passRaw = $password; + $this->drupalLogin($this->account); + + $this->assertSession()->pageTextNotContains('There have been more than 3 failed login attempts for this account. It is temporarily blocked.'); + } + /** * Helper function to make assertions about a valid password reset. * -- GitLab