View source
<?php
namespace Drupal\Tests\user\Functional;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
use Drupal\user\Entity\User;
class UserLoginTest extends BrowserTestBase {
protected $defaultTheme = 'stark';
protected static $modules = [
'dblog',
];
public function testLoginCacheTagsAndDestination() {
$this
->drupalGet('user/login');
$this
->assertSession()
->responseHeaderContains('X-Drupal-Cache-Tags', 'config:system.site');
$user = $this
->drupalCreateUser([]);
$this
->drupalGet('user/login', [
'query' => [
'destination' => 'foo',
],
]);
$edit = [
'name' => $user
->getAccountName(),
'pass' => $user->passRaw,
];
$this
->submitForm($edit, 'Log in');
$this
->assertSession()
->addressEquals('foo');
}
public function testGlobalLoginFloodControl() {
$this
->config('user.flood')
->set('ip_limit', 10)
->set('user_limit', 4000)
->save();
$user1 = $this
->drupalCreateUser([]);
$incorrect_user1 = clone $user1;
$incorrect_user1->passRaw .= 'incorrect';
for ($i = 0; $i < 2; $i++) {
$this
->assertFailedLogin($incorrect_user1);
}
$this
->drupalLogin($user1);
$this
->drupalLogout();
for ($i = 0; $i < 8; $i++) {
$this
->assertFailedLogin($incorrect_user1);
}
$this
->assertFailedLogin($incorrect_user1, 'ip');
$this
->assertFailedLogin($user1, 'ip');
}
public function testPerUserLoginFloodControl() {
$this
->config('user.flood')
->set('ip_limit', 4000)
->set('user_limit', 3)
->save();
$user1 = $this
->drupalCreateUser([]);
$incorrect_user1 = clone $user1;
$incorrect_user1->passRaw .= 'incorrect';
$user2 = $this
->drupalCreateUser([]);
for ($i = 0; $i < 2; $i++) {
$this
->assertFailedLogin($incorrect_user1);
}
$this
->drupalLogin($user1);
$this
->drupalLogout();
for ($i = 0; $i < 3; $i++) {
$this
->assertFailedLogin($incorrect_user1);
}
$this
->drupalLogin($user2);
$this
->drupalLogout();
$this
->assertFailedLogin($user1, 'user');
}
public function testPasswordRehashOnLogin() {
$default_count_log2 = 16;
$password_hasher = $this->container
->get('password');
$account = $this
->drupalCreateUser([]);
$password = $account->passRaw;
$this
->drupalLogin($account);
$this
->drupalLogout();
$user_storage = $this->container
->get('entity_type.manager')
->getStorage('user');
$account = User::load($account
->id());
$this
->assertSame($default_count_log2, $password_hasher
->getCountLog2($account
->getPassword()));
$overridden_count_log2 = 19;
\Drupal::service('module_installer')
->install([
'user_custom_phpass_params_test',
]);
$this
->resetAll();
$account->passRaw = $password;
$this
->drupalLogin($account);
$user_storage
->resetCache([
$account
->id(),
]);
$account = $user_storage
->load($account
->id());
$this
->assertSame($overridden_count_log2, $password_hasher
->getCountLog2($account
->getPassword()));
$this
->assertTrue($password_hasher
->check($password, $account
->getPassword()));
}
public function testCookiesNotAccepted() {
$this
->drupalGet('user/login');
$form_build_id = $this
->getSession()
->getPage()
->findField('form_build_id');
$account = $this
->drupalCreateUser([]);
$post = [
'form_id' => 'user_login_form',
'form_build_id' => $form_build_id,
'name' => $account
->getAccountName(),
'pass' => $account->passRaw,
'op' => 'Log in',
];
$url = $this
->buildUrl(Url::fromRoute('user.login'));
$response = $this
->getHttpClient()
->post($url, [
'form_params' => $post,
'http_errors' => FALSE,
'cookies' => FALSE,
'allow_redirects' => FALSE,
]);
$this
->drupalGet($response
->getHeader('location')[0]);
$this
->assertSession()
->statusCodeEquals(403);
$this
->assertSession()
->pageTextContains('To log in to this site, your browser must accept cookies from the domain');
}
public function assertFailedLogin($account, $flood_trigger = NULL) {
$database = \Drupal::database();
$edit = [
'name' => $account
->getAccountName(),
'pass' => $account->passRaw,
];
$this
->drupalGet('user/login');
$this
->submitForm($edit, 'Log in');
if (isset($flood_trigger)) {
$this
->assertSession()
->statusCodeEquals(403);
$this
->assertSession()
->fieldNotExists('pass');
$last_log = $database
->select('watchdog', 'w')
->fields('w', [
'message',
])
->condition('type', 'user')
->orderBy('wid', 'DESC')
->range(0, 1)
->execute()
->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()
->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.');
}
else {
$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()
->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.');
}
}
else {
$this
->assertSession()
->statusCodeEquals(200);
$this
->assertSession()
->fieldValueEquals('pass', '');
$this
->assertSession()
->pageTextContains('Unrecognized username or password. Forgot your password?');
}
}
}