Issue #1966334 by Alan Evans, fubhy, dawehner, ParisLiakos: Convert user_access() to User::hasPermission().
parent
4f6161a226
commit
edcd8df4bd
|
@ -41,6 +41,10 @@ class UpdateModuleHandler extends ModuleHandler {
|
||||||
return array('system');
|
return array('system');
|
||||||
// This is called during rebuild to find testing themes.
|
// This is called during rebuild to find testing themes.
|
||||||
case 'system_theme_info':
|
case 'system_theme_info':
|
||||||
|
// Those are needed by user_access() to check access on update.php.
|
||||||
|
case 'entity_info':
|
||||||
|
case 'entity_load':
|
||||||
|
case 'user_role_load':
|
||||||
return array();
|
return array();
|
||||||
// t() in system_stream_wrappers() needs this. Other schema calls aren't
|
// t() in system_stream_wrappers() needs this. Other schema calls aren't
|
||||||
// supported.
|
// supported.
|
||||||
|
|
|
@ -31,6 +31,17 @@ interface AccountInterface {
|
||||||
*/
|
*/
|
||||||
public function getRoles();
|
public function getRoles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a user has a certain permission.
|
||||||
|
*
|
||||||
|
* @param string $permission
|
||||||
|
* The permission string to check.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* TRUE if the user has the permission, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public function hasPermission($permission);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the session ID.
|
* Returns the session ID.
|
||||||
*
|
*
|
||||||
|
|
|
@ -112,6 +112,26 @@ class UserSession implements AccountInterface {
|
||||||
return $this->roles;
|
return $this->roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function hasPermission($permission) {
|
||||||
|
// User #1 has all privileges.
|
||||||
|
if ((int) $this->id() === 1) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$roles = \Drupal::entityManager()->getStorageController('user_role')->loadMultiple($this->getRoles());
|
||||||
|
|
||||||
|
foreach ($roles as $role) {
|
||||||
|
if ($role->hasPermission($permission)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -215,6 +215,26 @@ class User extends EntityNG implements UserInterface {
|
||||||
$this->set('roles', array_diff($this->getRoles(), array($rid)));
|
$this->set('roles', array_diff($this->getRoles(), array($rid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function hasPermission($permission) {
|
||||||
|
// User #1 has all privileges.
|
||||||
|
if ((int) $this->id() === 1) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$roles = \Drupal::entityManager()->getStorageController('user_role')->loadMultiple($this->getRoles());
|
||||||
|
|
||||||
|
foreach ($roles as $role) {
|
||||||
|
if ($role->hasPermission($permission)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,15 +14,6 @@ use Drupal\Core\Config\Entity\ConfigStorageController;
|
||||||
*/
|
*/
|
||||||
class RoleStorageController extends ConfigStorageController implements RoleStorageControllerInterface {
|
class RoleStorageController extends ConfigStorageController implements RoleStorageControllerInterface {
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function resetCache(array $ids = NULL) {
|
|
||||||
parent::resetCache($ids);
|
|
||||||
// Clear the user access cache.
|
|
||||||
drupal_static_reset('user_access');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -41,6 +41,13 @@ class UserBCDecorator extends EntityBCDecorator implements UserInterface {
|
||||||
return $this->decorated->getRoles();
|
return $this->decorated->getRoles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function hasPermission($permission) {
|
||||||
|
return $this->decorated->hasPermission($permission);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -50,6 +50,17 @@ interface UserInterface extends EntityInterface, AccountInterface {
|
||||||
*/
|
*/
|
||||||
public function removeRole($rid);
|
public function removeRole($rid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a user has a certain permission.
|
||||||
|
*
|
||||||
|
* @param string $permission
|
||||||
|
* The permission string to check.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* TRUE if the user has the permission, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public function hasPermission($permission);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the hashed password.
|
* Returns the hashed password.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\user\Tests\Plugin\Core\Entity\UserTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\user\Tests\Plugin\Core\Entity;
|
||||||
|
|
||||||
|
use Drupal\Tests\Core\Session\UserSessionTest;
|
||||||
|
use Drupal\user\Plugin\Core\Entity\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the user object.
|
||||||
|
*
|
||||||
|
* @see \Drupal\user\Plugin\Core\Entity\User
|
||||||
|
*/
|
||||||
|
class UserTest extends UserSessionTest {
|
||||||
|
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'User object',
|
||||||
|
'description' => 'Tests the user object.',
|
||||||
|
'group' => 'User',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function createUserSession(array $rids = array()) {
|
||||||
|
$user = $this->getMockBuilder('Drupal\user\Plugin\Core\Entity\User')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->setMethods(array('getRoles', 'id'))
|
||||||
|
->getMock();
|
||||||
|
$user->expects($this->any())
|
||||||
|
->method('id')
|
||||||
|
// @todo Also test the uid = 1 handling.
|
||||||
|
->will($this->returnValue(0));
|
||||||
|
$user->expects($this->any())
|
||||||
|
->method('getRoles')
|
||||||
|
->will($this->returnValue($rids));
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -462,27 +462,7 @@ function user_access($string, AccountInterface $account = NULL) {
|
||||||
$account = Drupal::request()->attributes->get('account') ?: $user;
|
$account = Drupal::request()->attributes->get('account') ?: $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
// User #1 has all privileges:
|
return $account->hasPermission($string);
|
||||||
if ($account->id() == 1) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// To reduce the number of SQL queries, we cache the user's permissions
|
|
||||||
// in a static variable.
|
|
||||||
// Use the advanced drupal_static() pattern, since this is called very often.
|
|
||||||
static $drupal_static_fast;
|
|
||||||
if (!isset($drupal_static_fast)) {
|
|
||||||
$drupal_static_fast['perm'] = &drupal_static(__FUNCTION__);
|
|
||||||
}
|
|
||||||
$perm = &$drupal_static_fast['perm'];
|
|
||||||
if (!isset($perm[$account->id()])) {
|
|
||||||
$perm[$account->id()] = array();
|
|
||||||
foreach (user_role_permissions($account->getRoles()) as $role_permissions) {
|
|
||||||
$perm[$account->id()] += array_fill_keys($role_permissions, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isset($perm[$account->id()][$string]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1744,8 +1724,6 @@ function user_role_grant_permissions($rid, array $permissions = array()) {
|
||||||
$role->grantPermission($permission);
|
$role->grantPermission($permission);
|
||||||
}
|
}
|
||||||
$role->save();
|
$role->save();
|
||||||
// Clear the user access cache.
|
|
||||||
drupal_static_reset('user_access');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1766,8 +1744,6 @@ function user_role_revoke_permissions($rid, array $permissions = array()) {
|
||||||
$role->revokePermission($permission);
|
$role->revokePermission($permission);
|
||||||
}
|
}
|
||||||
$role->save();
|
$role->save();
|
||||||
// Clear the user access cache.
|
|
||||||
drupal_static_reset('user_access');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function user_multiple_cancel_confirm($form, &$form_state) {
|
function user_multiple_cancel_confirm($form, &$form_state) {
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Tests\Core\Session\UserSessionTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Tests\Core\Session;
|
||||||
|
|
||||||
|
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||||
|
use Drupal\Core\Session\UserSession;
|
||||||
|
use Drupal\Tests\UnitTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the user session object.
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\Session\UserSession
|
||||||
|
*/
|
||||||
|
class UserSessionTest extends UnitTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user sessions used in the test
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Session\AccountInterface[]
|
||||||
|
*/
|
||||||
|
protected $users = array();
|
||||||
|
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'User session object',
|
||||||
|
'description' => 'Tests the user session object.',
|
||||||
|
'group' => 'Session',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides test data for getHasPermission().
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function providerTestHasPermission() {
|
||||||
|
$data = array();
|
||||||
|
$data[] = array('example permission', array('user_one', 'user_two'), array('user_last'));
|
||||||
|
$data[] = array('another example permission', array('user_two'), array('user_one', 'user_last'));
|
||||||
|
$data[] = array('final example permission', array(), array('user_one', 'user_two', 'user_last'));
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setups a user session for the test.
|
||||||
|
*
|
||||||
|
* @param array $rids
|
||||||
|
* The rids of the user.
|
||||||
|
*
|
||||||
|
* @return \Drupal\Core\Session\AccountInterface
|
||||||
|
* The created user session.
|
||||||
|
*/
|
||||||
|
protected function createUserSession(array $rids = array()) {
|
||||||
|
return new UserSession(array('roles' => $rids));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$roles = array();
|
||||||
|
$roles['role_one'] = $this->getMockBuilder('Drupal\user\Plugin\Core\Entity\Role')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->setMethods(array('hasPermission'))
|
||||||
|
->getMock();
|
||||||
|
$roles['role_one']->expects($this->any())
|
||||||
|
->method('hasPermission')
|
||||||
|
->will($this->returnValueMap(array(
|
||||||
|
array('example permission', TRUE),
|
||||||
|
array('another example permission', FALSE),
|
||||||
|
array('last example permission', FALSE),
|
||||||
|
)));
|
||||||
|
|
||||||
|
$roles['role_two'] = $this->getMockBuilder('Drupal\user\Plugin\Core\Entity\Role')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->setMethods(array('hasPermission'))
|
||||||
|
->getMock();
|
||||||
|
$roles['role_two']->expects($this->any())
|
||||||
|
->method('hasPermission')
|
||||||
|
->will($this->returnValueMap(array(
|
||||||
|
array('example permission', TRUE),
|
||||||
|
array('another example permission', TRUE),
|
||||||
|
array('last example permission', FALSE),
|
||||||
|
)));
|
||||||
|
|
||||||
|
$role_storage = $this->getMockBuilder('Drupal\user\RoleStorageController')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->setMethods(array('loadMultiple'))
|
||||||
|
->getMock();
|
||||||
|
$role_storage->expects($this->any())
|
||||||
|
->method('loadMultiple')
|
||||||
|
->will($this->returnValueMap(array(
|
||||||
|
array(array(), array()),
|
||||||
|
array(NULL, $roles),
|
||||||
|
array(array('role_one'), array($roles['role_one'])),
|
||||||
|
array(array('role_two'), array($roles['role_two'])),
|
||||||
|
array(array('role_one', 'role_two'), array($roles['role_one'], $roles['role_two'])),
|
||||||
|
)));
|
||||||
|
|
||||||
|
$entity_manager = $this->getMockBuilder('Drupal\Core\Entity\EntityManager')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$entity_manager->expects($this->any())
|
||||||
|
->method('getStorageController')
|
||||||
|
->with($this->equalTo('user_role'))
|
||||||
|
->will($this->returnValue($role_storage));
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$container->set('plugin.manager.entity', $entity_manager);
|
||||||
|
\Drupal::setContainer($container);
|
||||||
|
|
||||||
|
$this->users['user_one'] = $this->createUserSession(array('role_one'));
|
||||||
|
$this->users['user_two'] = $this->createUserSession(array('role_one', 'role_two'));
|
||||||
|
$this->users['user_last'] = $this->createUserSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function tearDown() {
|
||||||
|
parent::tearDown();
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
\Drupal::setContainer($container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the has permission method.
|
||||||
|
*
|
||||||
|
* @param string $permission
|
||||||
|
* The permission to check.
|
||||||
|
* @param \Drupal\Core\Session\AccountInterface[] $sessions_with_access
|
||||||
|
* The users with access.
|
||||||
|
* @param \Drupal\Core\Session\AccountInterface[] $sessions_without_access
|
||||||
|
* The users without access.
|
||||||
|
*
|
||||||
|
* @dataProvider providerTestHasPermission
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\Session\UserSession::hasPermission().
|
||||||
|
*/
|
||||||
|
public function testHasPermission($permission, array $sessions_with_access, array $sessions_without_access) {
|
||||||
|
foreach ($sessions_with_access as $name) {
|
||||||
|
$this->assertTrue($this->users[$name]->hasPermission($permission));
|
||||||
|
}
|
||||||
|
foreach ($sessions_without_access as $name) {
|
||||||
|
$this->assertFalse($this->users[$name]->hasPermission($permission));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue