diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/PasswordItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/PasswordItem.php index 1df00cb..6a8a8a2 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/PasswordItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/PasswordItem.php @@ -40,13 +40,18 @@ public function preSave() { $entity = $this->getEntity(); - // Update the user password if it has changed. - 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. - if (!$this->value) { - throw new EntityMalformedException('The entity does not have a password.'); + // Skip if the password is pre hashed. This is set when migrating users from + // Drupal 7. + if (!$this->pre_hashed) { + // Update the user password for a new user or if the password has changed. + 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. + if (!$this->value) { + throw new EntityMalformedException('The entity does not have a password.'); + } } } diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php index fb307f0..2797b6c 100644 --- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php +++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php @@ -40789,7 +40789,7 @@ ->values(array( 'uid' => '2', 'name' => 'Odo', - 'pass' => '$S$DZ4P7zZOh92vgrgZDBbv8Pu6lQB337OJ1wsOy21602G4A5F7.M9K', + 'pass' => '$S$DGFZUE.FhrXbe4y52eC7p0ZVRGD/gOPtVctDlmC89qkujnBokAlJ', 'mail' => 'odo@local.host', 'theme' => '', 'signature' => '', diff --git a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php index 4187121..64818f1 100644 --- a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php +++ b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php @@ -3,6 +3,7 @@ namespace Drupal\user\Plugin\migrate\destination; use Drupal\Component\Utility\Unicode; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\FieldTypePluginManagerInterface; @@ -106,6 +107,17 @@ public function import(Row $row, array $old_destination_id_values = array()) { /** * {@inheritdoc} */ + protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) { + if (!$this->password) { + // Tell the PasswordItem field not to re-hash the password. + $entity->pass->pre_hashed = TRUE; + } + return parent::save($entity, $old_destination_id_values); + } + + /** + * {@inheritdoc} + */ protected function processStubRow(Row $row) { parent::processStubRow($row); // Email address is not defined as required in the base field definition but diff --git a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php index 61ff800..0cb1ccd 100644 --- a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php +++ b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php @@ -44,6 +44,8 @@ protected function setUp() { * The username. * @param string $mail * The user's email address. + * @param string $password + * The password for this user. * @param int $access * The last access time. * @param int $login @@ -59,7 +61,7 @@ protected function setUp() { * @param bool $has_picture * Whether the user is expected to have a picture attached. */ - protected function assertEntity($id, $label, $mail, $access, $login, $blocked, $langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID], $has_picture = FALSE) { + protected function assertEntity($id, $label, $mail, $password, $access, $login, $blocked, $langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID], $has_picture = FALSE) { /** @var \Drupal\user\UserInterface $user */ $user = User::load($id); $this->assertTrue($user instanceof UserInterface); @@ -77,13 +79,17 @@ protected function assertEntity($id, $label, $mail, $access, $login, $blocked, $ $this->assertIdentical($init, $user->getInitialEmail()); $this->assertIdentical($roles, $user->getRoles()); $this->assertIdentical($has_picture, !$user->user_picture->isEmpty()); + $this->assertIdentical($password, $user->getPassword()); } /** * Tests the Drupal 7 user to Drupal 8 migration. */ public function testUser() { - $this->assertEntity(2, 'Odo', 'odo@local.host', '0', '0', FALSE, '', 'odo@local.host'); + $password = '$S$DGFZUE.FhrXbe4y52eC7p0ZVRGD/gOPtVctDlmC89qkujnBokAlJ'; + $this->assertEntity(2, 'Odo', 'odo@local.host', $password, '0', '0', FALSE, '', 'odo@local.host'); + // Ensure that the user can authenticate. + $this->assertEquals(2, \Drupal::service('user.auth')->authenticate('Odo', 'a password')); } }