Verified Commit 720d213c authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #3261663 by s.messaris, DieterHolvoet, ShaunDychko, smustgrave,...

Issue #3261663 by s.messaris, DieterHolvoet, ShaunDychko, smustgrave, schillerm, dww: Password reset json endpoint reveals whether an email or username is in use

(cherry picked from commit 98618df7)
parent 5fd0284c
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -240,18 +240,24 @@ public function resetPassword(Request $request) {
    }

    // Load by name if provided.
    $identifier = '';
    if (isset($credentials['name'])) {
      $users = $this->userStorage->loadByProperties(['name' => trim($credentials['name'])]);
      $identifier = $credentials['name'];
      $users = $this->userStorage->loadByProperties(['name' => trim($identifier)]);
    }
    elseif (isset($credentials['mail'])) {
      $users = $this->userStorage->loadByProperties(['mail' => trim($credentials['mail'])]);
      $identifier = $credentials['mail'];
      $users = $this->userStorage->loadByProperties(['mail' => trim($identifier)]);
    }

    /** @var \Drupal\Core\Session\AccountInterface $account */
    $account = reset($users);
    if ($account && $account->id()) {
      if ($this->userIsBlocked($account->getAccountName())) {
        throw new BadRequestHttpException('The user has not been activated or is blocked.');
        $this->logger->error('Unable to send password reset email for blocked or not yet activated user %identifier.', [
          '%identifier' => $identifier,
        ]);
        return new Response();
      }

      // Send the password reset email.
@@ -266,7 +272,10 @@ public function resetPassword(Request $request) {
    }

    // Error if no users found with provided name or mail.
    throw new BadRequestHttpException('Unrecognized username or email address.');
    $this->logger->error('Unable to send password reset email for unrecognized username or email address %identifier.', [
      '%identifier' => $identifier,
    ]);
    return new Response();
  }

  /**
+34 −4
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

use Drupal\Core\Flood\DatabaseBackend;
use Drupal\Core\Test\AssertMailTrait;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
use Drupal\user\Controller\UserAuthenticationController;
@@ -534,20 +535,49 @@ protected function doTestPasswordReset($format, $account) {
    $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name or credentials.mail', $format);

    $response = $this->passwordRequest(['name' => 'dramallama'], $format);
    $this->assertHttpResponseWithMessage($response, 400, 'Unrecognized username or email address.', $format);
    $this->assertEquals(200, $response->getStatusCode());

    $response = $this->passwordRequest(['mail' => 'llama@drupal.org'], $format);
    $this->assertHttpResponseWithMessage($response, 400, 'Unrecognized username or email address.', $format);
    $this->assertEquals(200, $response->getStatusCode());

    $account
      ->block()
      ->save();

    $response = $this->passwordRequest(['name' => $account->getAccountName()], $format);
    $this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format);
    $this->assertEquals(200, $response->getStatusCode());

    // Check that the proper warning has been logged.
    $arguments = [
      '%identifier' => $account->getAccountName(),
    ];
    $logged = Database::getConnection()->select('watchdog')
      ->fields('watchdog', ['variables'])
      ->condition('type', 'user')
      ->condition('message', 'Unable to send password reset email for blocked or not yet activated user %identifier.')
      ->orderBy('wid', 'DESC')
      ->range(0, 1)
      ->execute()
      ->fetchField();
    $this->assertEquals(serialize($arguments), $logged);

    $response = $this->passwordRequest(['mail' => $account->getEmail()], $format);
    $this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format);
    $this->assertEquals(200, $response->getStatusCode());

    // Check that the proper warning has been logged.
    $arguments = [
      '%identifier' => $account->getEmail(),
    ];

    $logged = Database::getConnection()->select('watchdog')
      ->fields('watchdog', ['variables'])
      ->condition('type', 'user')
      ->condition('message', 'Unable to send password reset email for blocked or not yet activated user %identifier.')
      ->orderBy('wid', 'DESC')
      ->range(0, 1)
      ->execute()
      ->fetchField();
    $this->assertEquals(serialize($arguments), $logged);

    $account
      ->activate()