Commit 8bfb6d22 authored by Liam Hiscock's avatar Liam Hiscock Committed by Norman Kämper-Leymann
Browse files

Issue #3143391 by loze, ramesh.tellamekala, LiamPower, ongdesign, jcnventura,...

Issue #3143391 by loze, ramesh.tellamekala, LiamPower, ongdesign, jcnventura, sorina.hriban, rviner, joum, camhoward: Password reset form validation allows non-matching passwords
parent ad7b3fc1
Loading
Loading
Loading
Loading
+47 −3
Original line number Diff line number Diff line
@@ -2,11 +2,14 @@

namespace Drupal\prlp\Controller;

use Drupal\Core\Form\FormState;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
use Drupal\user\Controller\UserController;
use Drupal\user\Form\UserPasswordResetForm;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

/**
 * Controller routines for prlp routes.
@@ -29,6 +32,49 @@ class PrlpController extends UserController {
   *   Returns parent result object.
   */
  public function prlpResetPassLogin(Request $request, $uid, $timestamp, $hash) {
    /** @var \Drupal\user\UserInterface $user */
    $user = $this->userStorage->load($uid);

    // Verify that the user exists and is active.
    if ($user === NULL || !$user->isActive()) {
      // Blocked or invalid user ID, so deny access. The parameters will be in
      // the watchdog's URL for the administrator to check.
      throw new AccessDeniedHttpException();
    }

    // Build form to call for validation and submit handlers.
    $timeout = $this->config('user.settings')->get('password_reset_timeout');
    $expiration_date = $user->getLastLoginTime() ? $this->dateFormatter->format($timestamp + $timeout) : NULL;

    $form_state = new FormState();
    $form_state->addBuildInfo('args', array_values([
      $user,
      $expiration_date,
      $timestamp,
      $hash,
    ]));

    // The form tries to redirect and returns an error due to this. Catch
    // the error in order to use the form state.
    try {
      $this->formBuilder()
        ->buildForm(UserPasswordResetForm::class, $form_state);
    }
    catch (\Exception $exception) {
    }

    if ($form_state->getErrors()) {
      // We have errors. Go back to the form.
      $session = $request->getSession();
      $session->set('pass_reset_hash', $hash);
      $session->set('pass_reset_timeout', $timestamp);
      return $this->redirect(
        'user.reset.form',
        ['uid' => $uid]
      );
    }

    // Carry on with the response checking if there are no form errors.
    $response = parent::resetPassLogin($uid, $timestamp, $hash, $request);

    try {
@@ -45,8 +91,6 @@ class PrlpController extends UserController {
          // should be done to the user.
          $pass = is_array($passwords) ? reset($passwords) : NULL;
          if (!empty($pass)) {
            /** @var \Drupal\user\UserInterface $user */
            $user = $this->userStorage->load($uid);
            $user->setPassword($pass);
            $user->save();
            $this->messenger()->deleteByType(MessengerInterface::TYPE_STATUS);