Update to Drupal 8.1.5. For more information, see https://www.drupal.org/project/drupal/releases/8.1.5

This commit is contained in:
Pantheon Automation 2016-07-07 09:44:38 -07:00 committed by Greg Anderson
parent 13b6ca7cc2
commit 38ba7c357d
342 changed files with 7814 additions and 1534 deletions

View file

@ -1,89 +0,0 @@
<?php
namespace Drupal\user;
use Drupal\Core\Password\PasswordInterface;
/**
* Replaces the original 'password' service in order to prefix the MD5 re-hashed
* passwords with the 'U' flag. The new salted hash is recreated on first login
* similarly to the D6->D7 upgrade path.
*/
class MigratePassword implements PasswordInterface {
/**
* The original password service.
*
* @var \Drupal\Core\Password\PasswordInterface
*/
protected $originalPassword;
/**
* Indicates if MD5 password prefixing is enabled.
*/
protected $enabled = FALSE;
/**
* Builds the replacement password service class.
*
* @param \Drupal\Core\Password\PasswordInterface $original_password
* The password object.
*/
public function __construct(PasswordInterface $original_password) {
$this->originalPassword = $original_password;
}
/**
* {@inheritdoc}
*/
public function check($password, $hash) {
return $this->originalPassword->check($password, $hash);
}
/**
* {@inheritdoc}
*/
public function needsRehash($hash) {
return $this->originalPassword->needsRehash($hash);
}
/**
* {@inheritdoc}
*/
public function hash($password) {
$hash = $this->originalPassword->hash($password);
// Allow prefixing only if the service was asked to prefix. Check also if
// the $password pattern is conforming to a MD5 result.
if ($this->enabled && preg_match('/^[0-9a-f]{32}$/', $password)) {
$hash = 'U' . $hash;
}
return $hash;
}
/**
* Enables the MD5 password prefixing.
*/
public function enableMd5Prefixing() {
$this->enabled = TRUE;
}
/**
* Disables the MD5 password prefixing.
*/
public function disableMd5Prefixing() {
$this->enabled = FALSE;
}
/**
* Implements the PhpassHashedPassword::getCountLog2() method.
*
* @todo: Revisit this whole alternate password service:
* https://www.drupal.org/node/2540594.
*/
public function getCountLog2($setting) {
return $this->originalPassword->getCountLog2($setting);
}
}

View file

@ -3,14 +3,13 @@
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;
use Drupal\Core\Field\Plugin\Field\FieldType\EmailItem;
use Drupal\Core\Password\PasswordInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\MigrateException;
use Drupal\user\MigratePassword;
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -55,9 +54,7 @@ class EntityUser extends EntityContentBase {
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, PasswordInterface $password) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager, $field_type_manager);
if (isset($configuration['md5_passwords'])) {
$this->password = $password;
}
$this->password = $password;
}
/**
@ -83,24 +80,29 @@ class EntityUser extends EntityContentBase {
* @throws \Drupal\migrate\MigrateException
*/
public function import(Row $row, array $old_destination_id_values = array()) {
if ($this->password) {
if ($this->password instanceof MigratePassword) {
$this->password->enableMd5Prefixing();
}
else {
throw new MigrateException('Password service has been altered by another module, aborting.');
}
}
// Do not overwrite the root account password.
if ($row->getDestinationProperty('uid') == 1) {
$row->removeDestinationProperty('pass');
}
$ids = parent::import($row, $old_destination_id_values);
if ($this->password) {
$this->password->disableMd5Prefixing();
}
return parent::import($row, $old_destination_id_values);
}
return $ids;
/**
* {@inheritdoc}
*/
protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) {
// Do not overwrite the root account password.
if ($entity->id() != 1) {
// Set the pre_hashed password so that the PasswordItem field does not hash
// already hashed passwords. If the md5_passwords configuration option is
// set we need to rehash the password and prefix with a U.
// @see \Drupal\Core\Field\Plugin\Field\FieldType\PasswordItem::preSave()
$entity->pass->pre_hashed = TRUE;
if (isset($this->configuration['md5_passwords'])) {
$entity->pass->value = 'U' . $this->password->hash($entity->pass->value);
}
}
return parent::save($entity, $old_destination_id_values);
}
/**

View file

@ -27,7 +27,7 @@ class Role extends DrupalSqlBase {
public function query() {
$query = $this->select('role', 'r')
->fields('r', array('rid', 'name'))
->orderBy('rid');
->orderBy('r.rid');
return $query;
}

View file

@ -20,7 +20,7 @@ class User extends DrupalSqlBase {
public function query() {
return $this->select('users', 'u')
->fields('u', array_keys($this->baseFields()))
->condition('uid', 0, '>');
->condition('u.uid', 0, '>');
}
/**

View file

@ -22,7 +22,7 @@ class UserPicture extends DrupalSqlBase {
$query = $this->select('users', 'u')
->condition('picture', '', '<>')
->fields('u', array('uid', 'access', 'picture'))
->orderBy('access');
->orderBy('u.access');
return $query;
}

View file

@ -33,7 +33,7 @@ class UserPictureFile extends DrupalSqlBase {
*/
public function query() {
$query = $this->select('users', 'u')
->condition('picture', '', '<>')
->condition('u.picture', '', '<>')
->fields('u', array('uid', 'picture'));
return $query;
}

View file

@ -20,7 +20,7 @@ class User extends FieldableEntity {
public function query() {
return $this->select('users', 'u')
->fields('u')
->condition('uid', 0, '>');
->condition('u.uid', 0, '>');
}
/**

View file

@ -163,7 +163,7 @@ class SharedTempStore {
*
* @return bool
* TRUE if the data was set, or FALSE if it already exists and is not owned
* by $this->user.
* by $this->user.
*/
public function setIfOwner($key, $value) {
if ($this->setIfNotExists($key, $value)) {

View file

@ -42,8 +42,6 @@ interface UserDataInterface {
* The name of the data key.
* @param mixed $value
* The value to store. Non-scalar values are serialized automatically.
*
* @return void
*/
public function set($module, $uid, $name, $value);
@ -60,8 +58,6 @@ interface UserDataInterface {
* @param string $name
* (optional) The name of the data key. If omitted, all data associated with
* $module and $uid is deleted.
*
* @return void
*/
public function delete($module = NULL, $uid = NULL, $name = NULL);

View file

@ -1,25 +0,0 @@
<?php
namespace Drupal\user;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
/**
* Swaps the original 'password' service in order to handle password hashing for
* user migrations that have passwords hashed to MD5.
*
* @see \Drupal\migrate\MigratePassword
* @see \Drupal\Core\Password\PhpassHashedPassword
*/
class UserServiceProvider implements ServiceModifierInterface {
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
$container->setDefinition('password_original', $container->getDefinition('password'));
$container->setDefinition('password', $container->getDefinition('password_migrate'));
}
}

View file

@ -44,6 +44,8 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
* 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 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
* @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,29 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
$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'));
// After authenticating the password will be rehashed because the password
// stretching iteration count has changed from 15 in Drupal 7 to 16 in
// Drupal 8.
$user = User::load(2);
$rehash = $user->getPassword();
$this->assertNotEquals($password, $rehash);
// Authenticate again and there should be no re-hash.
$this->assertEquals(2, \Drupal::service('user.auth')->authenticate('Odo', 'a password'));
$user = User::load(2);
$this->assertEquals($rehash, $user->getPassword());
}
}

View file

@ -66,9 +66,6 @@ services:
arguments: ['@current_user', '@entity.manager']
tags:
- { name: 'context_provider' }
password_migrate:
class: Drupal\user\MigratePassword
arguments: ['@password_original']
parameters:
user.tempstore.expire: 604800