diff --git a/core/modules/user/lib/Drupal/user/Controller/UserController.php b/core/modules/user/lib/Drupal/user/Controller/UserController.php index 495a5aa..4c49487 100644 --- a/core/modules/user/lib/Drupal/user/Controller/UserController.php +++ b/core/modules/user/lib/Drupal/user/Controller/UserController.php @@ -9,14 +9,55 @@ use Drupal\Component\Utility\Xss; use Drupal\Core\Controller\ControllerBase; +use Drupal\Core\Datetime\Date; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\Form\FormBuilderInterface; use Drupal\user\UserInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; /** * Controller routines for user routes. */ -class UserController extends ControllerBase { +class UserController extends ControllerBase implements ContainerInjectionInterface { + + /** + * The form builder service. + * + * @var \Drupal\Core\Form\FormBuilderInterface + */ + protected $formBuilder; + + /** + * The date formatting service. + * + * @var \Drupal\Core\Datetime\Date + */ + protected $date; + + /** + * Constructs a UserController object. + * + * @param \Drupal\Core\Form\FormBuilderInterface $form_builder + * The form builder. + * @param \Drupal\Core\Datetime\Date $date + * The date formatting service. + */ + public function __construct(FormBuilderInterface $form_builder, Date $date) { + $this->formBuilder = $form_builder; + $this->date = $date; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('form_builder'), + $container->get('date') + ); + } /** * Returns the user page. @@ -39,7 +80,7 @@ public function userPage(Request $request) { else { // Sets the proper request. // @todo Remove when the request object is synchronized. - $form_builder = \Drupal::formBuilder(); + $form_builder = $this->formBuilder; $form_builder->setRequest($request); $response = $form_builder->getForm('Drupal\user\Form\UserLoginForm'); } @@ -69,10 +110,11 @@ public function userTitle(UserInterface $user = NULL) { * @param string $hash * Login link hash. * - * @return array - * The form structure. + * @return array|\Symfony\Component\HttpFoundation\RedirectResponse + * The form structure or a redirect response. * * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + * If the login link is for a blocked user or invalid user ID. */ public function resetPass($uid, $timestamp, $hash) { $account = $this->currentUser(); @@ -88,7 +130,7 @@ public function resetPass($uid, $timestamp, $hash) { // A different user is already logged in on the computer. else { $reset_link_user = $user_storage_controller->load($uid); - if (!empty($reset_link_user)) { + if ($reset_link_user) { drupal_set_message($this->t('Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user. Please logout and try using the link again.', array('%other_user' => $account->getUsername(), '%resetting_user' => $reset_link_user->getUsername(), '!logout' => $this->url('user.logout')))); } @@ -107,15 +149,15 @@ public function resetPass($uid, $timestamp, $hash) { /* @var \Drupal\user\UserInterface $user */ $user = $user_storage_controller->load($uid); // Verify that the user exists and is active. - if ($user->isActive()) { + if ($user && $user->isActive()) { // No time out for first time login. if ($user->getLastLoginTime() && $current - $timestamp > $timeout) { drupal_set_message($this->t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.')); return $this->redirect('user.pass'); } elseif ($user->isAuthenticated() && $timestamp >= $user->getLastLoginTime() && $timestamp <= $current && $hash === user_pass_rehash($user->getPassword(), $timestamp, $user->getLastLoginTime())) { - $expiration_date = $user->getLastLoginTime() ? $this->container()->get('date')->format($timestamp + $timeout) : NULL; - return \Drupal::formBuilder()->getForm('Drupal\user\Form\UserPasswordResetForm', $user, $expiration_date, $timestamp, $hash); + $expiration_date = $user->getLastLoginTime() ? $this->date->format($timestamp + $timeout) : NULL; + return $this->formBuilder->getForm('Drupal\user\Form\UserPasswordResetForm', $user, $expiration_date, $timestamp, $hash); } else { drupal_set_message($this->t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.')); @@ -123,8 +165,8 @@ public function resetPass($uid, $timestamp, $hash) { } } } - // Deny access, no more clues. - // Everything will be in the watchdog's URL for the administrator to check. + // 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(); } diff --git a/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php b/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php index f8635fd..5894a1d 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php @@ -102,6 +102,13 @@ function testUserPasswordReset() { $_uid = $this->account->id(); $this->drupalGet("user/reset/$_uid/$bogus_timestamp/" . user_pass_rehash($this->account->getPassword(), $bogus_timestamp, $this->account->getLastLoginTime())); $this->assertText(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'Expired password reset request rejected.'); + + // Create a user, block the account, and verify that a login link is denied. + $timestamp = REQUEST_TIME - 1; + $blocked_account = $this->drupalCreateUser()->block(); + $blocked_account->save(); + $this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account->getPassword(), $timestamp, $blocked_account->getLastLoginTime())); + $this->assertResponse(403); } /**