Issue #3348092 by andypost, alexpott, Ranjit1032002, smustgrave, catch: Deprecate user_role_permissions()

merge-requests/3738/head
catch 2023-03-28 15:58:56 +01:00
parent 0bbf07394d
commit 0fadc15359
5 changed files with 98 additions and 24 deletions

View File

@ -1599,7 +1599,7 @@ services:
Drupal\Core\Session\AccountSwitcherInterface: '@account_switcher'
user_permissions_hash_generator:
class: Drupal\Core\Session\PermissionsHashGenerator
arguments: ['@private_key', '@cache.bootstrap', '@cache.static']
arguments: ['@private_key', '@cache.bootstrap', '@cache.static', '@entity_type.manager']
Drupal\Core\Session\PermissionsHashGeneratorInterface: '@user_permissions_hash_generator'
current_user:
class: Drupal\Core\Session\AccountProxy

View File

@ -2,6 +2,7 @@
namespace Drupal\Core\Session;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\PrivateKey;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
@ -42,11 +43,17 @@ class PermissionsHashGenerator implements PermissionsHashGeneratorInterface {
* The cache backend interface to use for the persistent cache.
* @param \Drupal\Core\Cache\CacheBackendInterface $static
* The cache backend interface to use for the static cache.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface|null $entityTypeManager
* The entity type manager.
*/
public function __construct(PrivateKey $private_key, CacheBackendInterface $cache, CacheBackendInterface $static) {
public function __construct(PrivateKey $private_key, CacheBackendInterface $cache, CacheBackendInterface $static, protected ?EntityTypeManagerInterface $entityTypeManager = NULL) {
$this->privateKey = $private_key;
$this->cache = $cache;
$this->static = $static;
if ($this->entityTypeManager === NULL) {
@trigger_error('Calling ' . __METHOD__ . '() without the $entityTypeManager argument is deprecated in drupal:10.1.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3348138', E_USER_DEPRECATED);
$this->entityTypeManager = \Drupal::entityTypeManager();
}
}
/**
@ -93,18 +100,17 @@ class PermissionsHashGenerator implements PermissionsHashGeneratorInterface {
* The permissions hash.
*/
protected function doGenerate(array $roles) {
// @todo Once Drupal gets rid of user_role_permissions(), we should be able
// to inject the user role controller and call a method on that instead.
$permissions_by_role = user_role_permissions($roles);
foreach ($permissions_by_role as $role => $permissions) {
sort($permissions);
$permissions_by_role = [];
/** @var \Drupal\user\RoleInterface[] $entities */
$entities = $this->entityTypeManager->getStorage('user_role')->loadMultiple($roles);
foreach ($roles as $role) {
// Note that for admin roles (\Drupal\user\RoleInterface::isAdmin()), the
// permissions returned will be empty ($permissions = []). Therefore the
// presence of the role ID as a key in $permissions_by_role is essential
// to ensure that the hash correctly recognizes admin roles. (If the hash
// was based solely on the union of $permissions, the admin roles would
// effectively be no-ops, allowing for hash collisions.)
$permissions_by_role[$role] = $permissions;
$permissions_by_role[$role] = isset($entities[$role]) ? $entities[$role]->getPermissions() : [];
}
return $this->hash(serialize($permissions_by_role));
}

View File

@ -0,0 +1,56 @@
<?php
namespace Drupal\Tests\user\Kernel;
use Drupal\KernelTests\KernelTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
/**
* Tests deprecated user module functions.
*
* @group user
* @group legacy
*/
class LegacyUserTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = [
'system',
'user',
];
/**
* Tests deprecation of user_role_permissions().
*/
public function testUserRolePermissions() {
$this->expectDeprecation('user_role_permissions() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement beyond loading the roles and calling \Drupal\user\Entity\Role::getPermissions(). See https://www.drupal.org/node/3348138');
$expected = [
RoleInterface::ANONYMOUS_ID => [],
RoleInterface::AUTHENTICATED_ID => [],
];
$permissions = user_role_permissions(array_keys($expected));
$this->assertSame($expected, $permissions);
$permission = 'administer permissions';
$role = Role::create([
'id' => 'admin',
'label' => 'Test',
'is_admin' => TRUE,
'permissions' => [$permission],
]);
$role->save();
$permissions = user_role_permissions([$role->id()]);
$this->assertSame([$role->id() => []], $permissions);
$role
->setIsAdmin(FALSE)
->grantPermission($permission)
->save();
$permissions = user_role_permissions([$role->id()]);
$this->assertSame([$role->id() => [$permission]], $permissions);
}
}

View File

@ -227,8 +227,15 @@ function user_validate_name($name) {
* @return array
* An array indexed by role ID. Each value is an array of permission strings
* for the given role.
*
* @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no
* replacement beyond loading the roles and calling
* \Drupal\user\Entity\Role::getPermissions().
*
* @see https://www.drupal.org/node/3348138
*/
function user_role_permissions(array $roles) {
@trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement beyond loading the roles and calling \Drupal\user\Entity\Role::getPermissions(). See https://www.drupal.org/node/3348138', E_USER_DEPRECATED);
if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
return _user_role_permissions_update($roles);
}
@ -253,8 +260,14 @@ function user_role_permissions(array $roles) {
* @return array
* An array indexed by role ID. Each value is an array of permission strings
* for the given role.
*
* @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no
* replacement.
*
* @see https://www.drupal.org/node/3348138
*/
function _user_role_permissions_update($roles) {
@trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3348138', E_USER_DEPRECATED);
$role_permissions = [];
foreach ($roles as $rid) {
$role_permissions[$rid] = \Drupal::config("user.role.$rid")->get('permissions') ?: [];

View File

@ -3,9 +3,11 @@
namespace Drupal\Tests\Core\Session;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\PermissionsHashGenerator;
use Drupal\Core\Site\Settings;
use Drupal\Tests\UnitTestCase;
use Drupal\user\RoleStorageInterface;
/**
* @coversDefaultClass \Drupal\Core\Session\PermissionsHashGenerator
@ -142,8 +144,20 @@ class PermissionsHashGeneratorTest extends UnitTestCase {
$this->staticCache = $this->getMockBuilder('Drupal\Core\Cache\CacheBackendInterface')
->disableOriginalConstructor()
->getMock();
$entityTypeManager = $this->getMockBuilder(EntityTypeManagerInterface::class)
->disableOriginalConstructor()
->getMock();
$this->permissionsHash = new PermissionsHashGenerator($this->privateKey, $this->cache, $this->staticCache);
$roleStorage = $this->getMockBuilder(RoleStorageInterface::class)
->disableOriginalConstructor()
->getMock();
$entityTypeManager->expects($this->any())
->method('getStorage')
->with('user_role')
->willReturn($roleStorage);
$this->permissionsHash = new PermissionsHashGenerator($this->privateKey, $this->cache, $this->staticCache, $entityTypeManager);
}
/**
@ -245,18 +259,3 @@ class PermissionsHashGeneratorTest extends UnitTestCase {
}
}
namespace Drupal\Core\Session;
// @todo remove once user_role_permissions() can be injected.
if (!function_exists('user_role_permissions')) {
function user_role_permissions(array $roles) {
$role_permissions = [];
foreach ($roles as $rid) {
$role_permissions[$rid] = [];
}
return $role_permissions;
}
}