Issue #3198010 by mcdruid, acbramley, mstrelan, quietone, manojithape, vikashsoni, chetanbharambe, sarguna raj M, larowlan, alexpott: User login page broken when there are more than 5 failed login attempts for an account
parent
09c511d26e
commit
2b83cffdf2
|
@ -5,13 +5,13 @@ namespace Drupal\user\Form;
|
|||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Render\BareHtmlPageRendererInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\user\UserAuthInterface;
|
||||
use Drupal\user\UserInterface;
|
||||
use Drupal\user\UserStorageInterface;
|
||||
use Drupal\user\UserFloodControlInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Provides a user login form.
|
||||
|
@ -48,6 +48,13 @@ class UserLoginForm extends FormBase {
|
|||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* The bare HTML renderer.
|
||||
*
|
||||
* @var \Drupal\Core\Render\BareHtmlPageRendererInterface
|
||||
*/
|
||||
protected $bareHtmlPageRenderer;
|
||||
|
||||
/**
|
||||
* Constructs a new UserLoginForm.
|
||||
*
|
||||
|
@ -59,16 +66,23 @@ class UserLoginForm extends FormBase {
|
|||
* The user authentication object.
|
||||
* @param \Drupal\Core\Render\RendererInterface $renderer
|
||||
* The renderer.
|
||||
* @param \Drupal\Core\Render\BareHtmlPageRendererInterface $bare_html_renderer
|
||||
* The renderer.
|
||||
*/
|
||||
public function __construct($user_flood_control, UserStorageInterface $user_storage, UserAuthInterface $user_auth, RendererInterface $renderer) {
|
||||
public function __construct($user_flood_control, UserStorageInterface $user_storage, UserAuthInterface $user_auth, RendererInterface $renderer, BareHtmlPageRendererInterface $bare_html_renderer = NULL) {
|
||||
if (!$user_flood_control instanceof UserFloodControlInterface) {
|
||||
@trigger_error('Passing the flood service to ' . __METHOD__ . ' is deprecated in drupal:9.1.0 and is replaced by user.flood_control in drupal:10.0.0. See https://www.drupal.org/node/3067148', E_USER_DEPRECATED);
|
||||
$user_flood_control = \Drupal::service('user.flood_control');
|
||||
}
|
||||
if (!$bare_html_renderer instanceof BareHtmlPageRendererInterface) {
|
||||
@trigger_error('Calling UserLoginForm::__construct() without the $bare_html_renderer argument is deprecated in drupal:9.4.0 and will be required before drupal:10.0.0. See https://www.drupal.org/node/3251987.', E_USER_DEPRECATED);
|
||||
$bare_html_renderer = \Drupal::service('bare_html_page_renderer');
|
||||
}
|
||||
$this->userFloodControl = $user_flood_control;
|
||||
$this->userStorage = $user_storage;
|
||||
$this->userAuth = $user_auth;
|
||||
$this->renderer = $renderer;
|
||||
$this->bareHtmlPageRenderer = $bare_html_renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,7 +93,8 @@ class UserLoginForm extends FormBase {
|
|||
$container->get('user.flood_control'),
|
||||
$container->get('entity_type.manager')->getStorage('user'),
|
||||
$container->get('user.auth'),
|
||||
$container->get('renderer')
|
||||
$container->get('renderer'),
|
||||
$container->get('bare_html_page_renderer')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -237,7 +252,9 @@ class UserLoginForm extends FormBase {
|
|||
// We did not find a uid, so the limit is IP-based.
|
||||
$message = $this->t('Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', [':url' => Url::fromRoute('user.pass')->toString()]);
|
||||
}
|
||||
$form_state->setResponse(new Response($message, 403));
|
||||
$response = $this->bareHtmlPageRenderer->renderBarePage(['#markup' => $message], $this->t('Login failed'), 'maintenance_page');
|
||||
$response->setStatusCode(403);
|
||||
$form_state->setResponse($response);
|
||||
}
|
||||
else {
|
||||
// Use $form_state->getUserInput() in the error message to guarantee
|
||||
|
|
|
@ -217,6 +217,7 @@ class UserLoginTest extends BrowserTestBase {
|
|||
->fetchField();
|
||||
if ($flood_trigger == 'user') {
|
||||
$this->assertSession()->pageTextMatches("/There (has|have) been more than \w+ failed login attempt.* for this account. It is temporarily blocked. Try again later or request a new password./");
|
||||
$this->assertSession()->elementExists('css', 'body.maintenance-page');
|
||||
$this->assertSession()->linkExists("request a new password");
|
||||
$this->assertSession()->linkByHrefExists(Url::fromRoute('user.pass')->toString());
|
||||
$this->assertEquals('Flood control blocked login attempt for uid %uid from %ip', $last_log, 'A watchdog message was logged for the login attempt blocked by flood control per user.');
|
||||
|
@ -224,6 +225,7 @@ class UserLoginTest extends BrowserTestBase {
|
|||
else {
|
||||
// No uid, so the limit is IP-based.
|
||||
$this->assertSession()->pageTextContains("Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or request a new password.");
|
||||
$this->assertSession()->elementExists('css', 'body.maintenance-page');
|
||||
$this->assertSession()->linkExists("request a new password");
|
||||
$this->assertSession()->linkByHrefExists(Url::fromRoute('user.pass')->toString());
|
||||
$this->assertEquals('Flood control blocked login attempt from %ip', $last_log, 'A watchdog message was logged for the login attempt blocked by flood control per IP.');
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\Tests\user\Kernel\Form;
|
|||
|
||||
use Drupal\Core\Flood\FloodInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Render\BareHtmlPageRendererInterface;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\user\Form\UserLoginForm;
|
||||
use Drupal\user\UserAuthInterface;
|
||||
|
@ -29,11 +30,13 @@ class UserLoginFormTest extends KernelTestBase {
|
|||
$user_storage = $this->prophesize(UserStorageInterface::class);
|
||||
$user_auth = $this->prophesize(UserAuthInterface::class);
|
||||
$renderer = $this->prophesize(RendererInterface::class);
|
||||
$bare_html_renderer = $this->prophesize(BareHtmlPageRendererInterface::class);
|
||||
$form = new UserLoginForm(
|
||||
$flood->reveal(),
|
||||
$user_storage->reveal(),
|
||||
$user_auth->reveal(),
|
||||
$renderer->reveal()
|
||||
$renderer->reveal(),
|
||||
$bare_html_renderer->reveal()
|
||||
);
|
||||
$this->assertNotNull($form);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue