diff --git a/core/modules/user/src/Authentication/Provider/Cookie.php b/core/modules/user/src/Authentication/Provider/Cookie.php index bac9e15..fee0d3a 100644 --- a/core/modules/user/src/Authentication/Provider/Cookie.php +++ b/core/modules/user/src/Authentication/Provider/Cookie.php @@ -8,7 +8,7 @@ namespace Drupal\user\Authentication\Provider; use Drupal\Core\Authentication\AuthenticationProviderInterface; -use Drupal\Core\Database\Connection; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\UserSession; use Drupal\Core\Session\SessionConfigurationInterface; @@ -28,23 +28,23 @@ class Cookie implements AuthenticationProviderInterface { protected $sessionConfiguration; /** - * The database connection. + * The entity manager. * - * @var \Drupal\Core\Database\Connection + * @var \Drupal\Core\Entity\EntityManagerInterface */ - protected $connection; + protected $entityManager; /** * Constructs a new cookie authentication provider. * * @param \Drupal\Core\Session\SessionConfigurationInterface $session_configuration * The session configuration. - * @param \Drupal\Core\Database\Connection $connection - * The database connection. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. */ - public function __construct(SessionConfigurationInterface $session_configuration, Connection $connection) { + public function __construct(SessionConfigurationInterface $session_configuration, EntityManagerInterface $entity_manager) { $this->sessionConfiguration = $session_configuration; - $this->connection = $connection; + $this->entityManager = $entity_manager; } /** @@ -73,27 +73,7 @@ public function authenticate(Request $request) { */ protected function getUserFromSession(SessionInterface $session) { if ($uid = $session->get('uid')) { - // @todo Load the User entity in SessionHandler so we don't need queries. - // @see https://www.drupal.org/node/2345611 - $values = $this->connection - ->query('SELECT * FROM {users_field_data} u WHERE u.uid = :uid AND u.default_langcode = 1', [':uid' => $uid]) - ->fetchAssoc(); - - // Check if the user data was found and the user is active. - if (!empty($values) && $values['status'] == 1) { - // UserSession::getLastAccessedTime() returns session save timestamp, - // while User::getLastAccessedTime() returns the user 'access' - // timestamp. This ensures they are synchronized. - $values['timestamp'] = $values['access']; - - // Add the user's roles. - $rids = $this->connection - ->query('SELECT roles_target_id FROM {user__roles} WHERE entity_id = :uid', [':uid' => $values['uid']]) - ->fetchCol(); - $values['roles'] = array_merge([AccountInterface::AUTHENTICATED_ROLE], $rids); - - return new UserSession($values); - } + return $this->entityManager->getStorage('user')->load($uid); } // This is an anonymous session. diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php index 1a78c98..cf05b7c 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -161,9 +161,22 @@ public function getRoles($exclude_locked_roles = FALSE) { } } - foreach ($this->get('roles') as $role) { - if ($role->target_id) { - $roles[] = $role->target_id; + // Optimize for the case where the field object has not been initialized + // yet, directly access the values. + if (!isset($this->fields['roles'])) { + if (isset($this->values['roles'][LanguageInterface::LANGCODE_DEFAULT][0])) { + foreach ($this->values['roles'][LanguageInterface::LANGCODE_DEFAULT] as $values) { + if (isset($values['target_id'])) { + $roles[] = $values['target_id']; + } + } + } + } + else { + foreach ($this->get('roles') as $role) { + if ($role->target_id) { + $roles[] = $role->target_id; + } } } diff --git a/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php b/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php index 4f004a0..dae3c6c 100644 --- a/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php +++ b/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php @@ -7,6 +7,7 @@ namespace Drupal\Tests\user\Unit\Plugin\Core\Entity; +use Drupal\Core\Language\LanguageInterface; use Drupal\Tests\Core\Session\UserSessionTest; use Drupal\user\Entity\User; use Drupal\user\RoleInterface; @@ -21,24 +22,28 @@ class UserTest extends UserSessionTest { * {@inheritdoc} */ protected function createUserSession(array $rids = array(), $authenticated = FALSE) { + $roles = array(); + foreach ($rids as $rid) { + $roles[] = array( + 'target_id' => $rid, + ); + } + $values = ['roles' => [LanguageInterface::LANGCODE_DEFAULT => $roles]]; + $user = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() - ->setMethods(array('get', 'id')) + ->setMethods(array('id')) ->getMock(); + + $reflect = new \ReflectionObject($user); + $property = $reflect->getProperty('values'); + $property->setAccessible(TRUE); + $property->setValue($user, $values); + $user->expects($this->any()) ->method('id') // @todo Also test the uid = 1 handling. ->will($this->returnValue($authenticated ? 2 : 0)); - $roles = array(); - foreach ($rids as $rid) { - $roles[] = (object) array( - 'target_id' => $rid, - ); - } - $user->expects($this->any()) - ->method('get') - ->with('roles') - ->will($this->returnValue($roles)); return $user; } diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml index 0a55b6e..57325a6 100644 --- a/core/modules/user/user.services.yml +++ b/core/modules/user/user.services.yml @@ -17,7 +17,7 @@ services: - { name: access_check, applies_to: _user_is_logged_in } authentication.cookie: class: Drupal\user\Authentication\Provider\Cookie - arguments: ['@session_configuration', '@database'] + arguments: ['@session_configuration', '@entity.manager'] tags: - { name: authentication_provider, priority: 0 } user.data: