Commit fb8e894c authored by alexpott's avatar alexpott

Issue #2563751 by borisson_, rocketeerbkw, cilefen, NikitaJain,...

Issue #2563751 by borisson_, rocketeerbkw, cilefen, NikitaJain, imanol.eguskiza, pjonckiere: Password field errors on user create/edit/login when password is (literally) 0
parent 877fe966
......@@ -46,7 +46,7 @@ public function preSave() {
$entity = $this->getEntity();
// Update the user password if it has changed.
if ($entity->isNew() || ($this->value && $this->value != $entity->original->{$this->getFieldDefinition()->getName()}->value)) {
if ($entity->isNew() || (strlen(trim($this->value)) > 0 && $this->value != $entity->original->{$this->getFieldDefinition()->getName()}->value)) {
// Allow alternate password hashing schemes.
$this->value = \Drupal::service('password')->hash(trim($this->value));
// Abort if the hashing failed and returned FALSE.
......
......@@ -102,7 +102,7 @@ public static function processPasswordConfirm(&$element, FormStateInterface $for
public static function validatePasswordConfirm(&$element, FormStateInterface $form_state, &$complete_form) {
$pass1 = trim($element['pass1']['#value']);
$pass2 = trim($element['pass2']['#value']);
if (!empty($pass1) || !empty($pass2)) {
if (strlen($pass1) > 0 || strlen($pass2) > 0) {
if (strcmp($pass1, $pass2)) {
$form_state->setError($element, t('The specified passwords do not match.'));
}
......
......@@ -333,7 +333,8 @@ public function buildEntity(array $form, FormStateInterface $form_state) {
}
// Set existing password if set in the form state.
if ($current_pass = $form_state->getValue('current_pass')) {
$current_pass = trim($form_state->getValue('current_pass'));
if (strlen($current_pass) > 0) {
$account->setExistingPassword($current_pass);
}
......
......@@ -407,7 +407,7 @@ public function setExistingPassword($password) {
* {@inheritdoc}
*/
public function checkExistingPassword(UserInterface $account_unchanged) {
return !empty($this->get('pass')->existing) && \Drupal::service('password')->check(trim($this->get('pass')->existing), $account_unchanged->getPassword());
return strlen($this->get('pass')->existing) > 0 && \Drupal::service('password')->check(trim($this->get('pass')->existing), $account_unchanged->getPassword());
}
/**
......
......@@ -167,7 +167,7 @@ public function validateName(array &$form, FormStateInterface $form_state) {
public function validateAuthentication(array &$form, FormStateInterface $form_state) {
$password = trim($form_state->getValue('pass'));
$flood_config = $this->config('user.flood');
if (!$form_state->isValueEmpty('name') && !empty($password)) {
if (!$form_state->isValueEmpty('name') && strlen($password) > 0) {
// Do not allow any login from the current user's IP if the limit has been
// reached. Default is 50 failed attempts allowed in one hour. This is
// independent of the per-user limit to catch attempts from one IP to log
......
......@@ -114,5 +114,19 @@ public function testUserAdd() {
$user = user_load_by_name($name);
$this->assertEqual($user->isActive(), 'User is not blocked');
}
// Test that the password '0' is considered a password.
// @see https://www.drupal.org/node/2563751.
$name = $this->randomMachineName();
$edit = array(
'name' => $name,
'mail' => $this->randomMachineName() . '@example.com',
'pass[pass1]' => 0,
'pass[pass2]' => 0,
'notify' => FALSE,
);
$this->drupalPostForm('admin/people/create', $edit, t('Create new account'));
$this->assertText("Created a new user account for $name. No email has been sent");
$this->assertNoText('Password field is required');
}
}
......@@ -108,6 +108,24 @@ function testUserEdit() {
$this->assertFieldChecked('edit-status-1');
}
/**
* Tests setting the password to "0".
*
* We discovered in https://www.drupal.org/node/2563751 that logging in with a
* password that is literally "0" was not possible. This test ensures that
* this regression can't happen again.
*/
public function testUserWith0Password() {
$admin = $this->drupalCreateUser(['administer users']);
$this->drupalLogin($admin);
// Create a regular user.
$user1 = $this->drupalCreateUser([]);
$edit = ['pass[pass1]' => '0', 'pass[pass2]' => '0'];
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
$this->assertRaw(t("The changes have been saved."));
}
/**
* Tests editing of a user account without an email address.
*/
......
......@@ -48,7 +48,7 @@ public function __construct(EntityManagerInterface $entity_manager, PasswordInte
public function authenticate($username, $password) {
$uid = FALSE;
if (!empty($username) && !empty($password)) {
if (!empty($username) && strlen($password) > 0) {
$account_search = $this->entityManager->getStorage('user')->loadByProperties(array('name' => $username));
if ($account = reset($account_search)) {
......
......@@ -164,6 +164,33 @@ public function testAuthenticateWithCorrectPassword() {
$this->assertsame(1, $this->userAuth->authenticate($this->username, $this->password));
}
/**
* Tests the authenticate method with a correct password.
*
* We discovered in https://www.drupal.org/node/2563751 that logging in with a
* password that is literally "0" was not possible. This test ensures that
* this regression can't happen again.
*
* @covers ::authenticate
*/
public function testAuthenticateWithZeroPassword() {
$this->testUser->expects($this->once())
->method('id')
->will($this->returnValue(2));
$this->userStorage->expects($this->once())
->method('loadByProperties')
->with(array('name' => $this->username))
->will($this->returnValue(array($this->testUser)));
$this->passwordService->expects($this->once())
->method('check')
->with(0, 0)
->will($this->returnValue(TRUE));
$this->assertsame(2, $this->userAuth->authenticate($this->username, 0));
}
/**
* Tests the authenticate method with a correct password and new password hash.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment