diff --git a/composer.lock b/composer.lock index 07ec98f8ff803e8da62c907ea69cccb08914d7e6..5b53180ac385d820a114b7b2df2f298fd47ea328 100644 --- a/composer.lock +++ b/composer.lock @@ -5838,26 +5838,28 @@ }, { "name": "drupal/msqrole", - "version": "1.0.8", + "version": "1.0.10", "source": { "type": "git", "url": "https://git.drupalcode.org/project/msqrole.git", - "reference": "1.0.8" + "reference": "1.0.10" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/msqrole-1.0.8.zip", - "reference": "1.0.8", - "shasum": "7ca4924a0f0d23ad44701c5d9d69fa92d47fb3de" + "url": "https://ftp.drupal.org/files/projects/msqrole-1.0.10.zip", + "reference": "1.0.10", + "shasum": "90867c8709093ffa83f5b06c5a6088e9bc30a30f" }, "require": { - "drupal/core": "^8.8.4 || ^9 || ^10" + "drupal/core": "^9.4 || ^10", + "drupal/token": "~1", + "php": ">=7.4" }, "type": "drupal-module", "extra": { "drupal": { - "version": "1.0.8", - "datestamp": "1650607669", + "version": "1.0.10", + "datestamp": "1690031508", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -5874,7 +5876,7 @@ "homepage": "https://www.drupal.org/user/3612901" } ], - "description": "Masquerades a user based on role, and not as another user", + "description": "Allows the user to masquerade as certain roles rather than specific users.", "homepage": "https://www.drupal.org/project/msqrole", "support": { "source": "https://git.drupalcode.org/project/msqrole" diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 9bd4635e64bb5a3e1c98e97b2415784e9a2e4058..6d39faf11f228042da52a66ace927bb1adfde411 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -18,8 +18,8 @@ '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', - '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', + '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php', 'c9d07b32a2e02bc0fc582d4f0c1b56cc' => $vendorDir . '/laminas/laminas-servicemanager/src/autoload.php', '3e41e0554275033aae3e9e7e056c2d14' => $vendorDir . '/longwave/laminas-diactoros/src/functions/create_uploaded_file.php', 'f4ee20bfdee1006b0970e8d951bea11e' => $vendorDir . '/longwave/laminas-diactoros/src/functions/marshal_headers_from_sapi.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 9995636fb0f62ecccf94557644896cd58219286a..edb4a7b95c6d357a5c3544a1322e84a1fd500d2b 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -19,8 +19,8 @@ class ComposerStaticInit5c689ffcd54b9e495ed983fdce09b530 '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', - '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', + '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php', 'c9d07b32a2e02bc0fc582d4f0c1b56cc' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/autoload.php', '3e41e0554275033aae3e9e7e056c2d14' => __DIR__ . '/..' . '/longwave/laminas-diactoros/src/functions/create_uploaded_file.php', 'f4ee20bfdee1006b0970e8d951bea11e' => __DIR__ . '/..' . '/longwave/laminas-diactoros/src/functions/marshal_headers_from_sapi.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index cd00489d5ab0af0b0d16ec528500f3bd10168766..c42b28626c7e9a6477d79d0fa1c886720eda7297 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -6071,30 +6071,32 @@ }, { "name": "drupal/msqrole", - "version": "1.0.8", - "version_normalized": "1.0.8.0", + "version": "1.0.10", + "version_normalized": "1.0.10.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/msqrole.git", - "reference": "1.0.8" + "reference": "1.0.10" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/msqrole-1.0.8.zip", - "reference": "1.0.8", - "shasum": "7ca4924a0f0d23ad44701c5d9d69fa92d47fb3de" + "url": "https://ftp.drupal.org/files/projects/msqrole-1.0.10.zip", + "reference": "1.0.10", + "shasum": "90867c8709093ffa83f5b06c5a6088e9bc30a30f" }, "require": { - "drupal/core": "^8.8.4 || ^9 || ^10" + "drupal/core": "^9.4 || ^10", + "drupal/token": "~1", + "php": ">=7.4" }, "type": "drupal-module", "extra": { "drupal": { - "version": "1.0.8", - "datestamp": "1650607669", + "version": "1.0.10", + "datestamp": "1690031508", "security-coverage": { - "status": "not-covered", - "message": "Project has not opted into security advisory coverage!" + "status": "covered", + "message": "Covered by Drupal's security advisory policy" } } }, @@ -6109,7 +6111,7 @@ "homepage": "https://www.drupal.org/user/3612901" } ], - "description": "Masquerades a user based on role, and not as another user", + "description": "Allows the user to masquerade as certain roles rather than specific users.", "homepage": "https://www.drupal.org/project/msqrole", "support": { "source": "https://git.drupalcode.org/project/msqrole" diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index d50b7d50cd697e21723a2f7e7fc91c1ea6e716a4..3de5f3943a35c75f02fe6d8c7eecf5f24b9b0366 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'osu-asc-webservices/d8-upstream', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '8e8d09103abc6af07826c501f2e89361a15286f4', + 'reference' => 'c04844796ef3d7d8ec36f41e833624e3c88f0ab1', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -1001,9 +1001,9 @@ 'dev_requirement' => false, ), 'drupal/msqrole' => array( - 'pretty_version' => '1.0.8', - 'version' => '1.0.8.0', - 'reference' => '1.0.8', + 'pretty_version' => '1.0.10', + 'version' => '1.0.10.0', + 'reference' => '1.0.10', 'type' => 'drupal-module', 'install_path' => __DIR__ . '/../../web/modules/msqrole', 'aliases' => array(), @@ -1564,7 +1564,7 @@ 'osu-asc-webservices/d8-upstream' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '8e8d09103abc6af07826c501f2e89361a15286f4', + 'reference' => 'c04844796ef3d7d8ec36f41e833624e3c88f0ab1', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/web/modules/msqrole/.gitignore b/web/modules/msqrole/.gitignore index 9f11b755a17d8192c60f61cb17b8902dffbd9f23..f32e31af499da4e38a79d6fb73f098ae42473366 100644 --- a/web/modules/msqrole/.gitignore +++ b/web/modules/msqrole/.gitignore @@ -1 +1,2 @@ .idea/ +.DS_Store diff --git a/web/modules/msqrole/README.md b/web/modules/msqrole/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4a6e34c2e22f2bd009461c9b85f237e7e498bdcf Binary files /dev/null and b/web/modules/msqrole/README.md differ diff --git a/web/modules/msqrole/README.txt b/web/modules/msqrole/README.txt deleted file mode 100644 index 0a307820066139749e1bc6af58970a8871f34cec..0000000000000000000000000000000000000000 Binary files a/web/modules/msqrole/README.txt and /dev/null differ diff --git a/web/modules/msqrole/composer.json b/web/modules/msqrole/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..b9b535107558f2916d9561cd34d18a809a1b0d4c --- /dev/null +++ b/web/modules/msqrole/composer.json @@ -0,0 +1,11 @@ +{ + "name": "drupal/msqrole", + "type": "drupal-module", + "description": "Allows the user to masquerade as certain roles rather than specific users.", + "require": { + "php": ">=7.4", + "drupal/core": "^9.4 || ^10", + "drupal/token": "~1" + }, + "minimum-stability": "dev" +} diff --git a/web/modules/msqrole/css/masquerade-role.css b/web/modules/msqrole/css/masquerade-role.css index 0ced89ac463f0830984f823c9afe8679cf91984f..fb9e06b9dd30d6704385bc79fd61d137dc82f26c 100644 --- a/web/modules/msqrole/css/masquerade-role.css +++ b/web/modules/msqrole/css/masquerade-role.css @@ -1,18 +1,12 @@ -html { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - .masquerade-role-status { opacity: 0.5; - transition: opacity .4s ease-in-out; + transition: .4s ease-in-out; border-top-right-radius: 10px; background: #1d5fc3; position: fixed; z-index: 2000001; padding: 10px 20px; - bottom: 0; + bottom: -60px; left: 0; -moz-box-shadow: inset -2px 2px 10px 0 #000000; -webkit-box-shadow: inset -2px 2px 10px 0 #000000; @@ -23,6 +17,7 @@ html { .masquerade-role-status:focus, .masquerade-role-status:focus-within { opacity: 1; + bottom: 0; } .masquerade-role-status .roles { diff --git a/web/modules/msqrole/js/masquerade-role.js b/web/modules/msqrole/js/masquerade-role.js index 8485a9d2e983391097da8ea95b11d91730995f45..507783bbb3eaee796bd4b8c517528a9c236e5788 100644 --- a/web/modules/msqrole/js/masquerade-role.js +++ b/web/modules/msqrole/js/masquerade-role.js @@ -1,3 +1,3 @@ (function ($, Drupal, drupalSettings) { - $('body').prepend(drupalSettings.msqrole.markup); + $('body').append(drupalSettings.msqrole.markup); })(jQuery, Drupal, drupalSettings); diff --git a/web/modules/msqrole/msqrole.info.yml b/web/modules/msqrole/msqrole.info.yml index d3b4985cb5e2cc59b76ae21df123796c02af07dc..2fcd6cac5beab4ed6e787b506f167f2ed153a796 100644 --- a/web/modules/msqrole/msqrole.info.yml +++ b/web/modules/msqrole/msqrole.info.yml @@ -2,10 +2,12 @@ name: 'Masquerade as Role' description: 'Masquerades a user based on role, and not as another user' package: 'Administration' type: module -core_version_requirement: ^8.8.4 || ^9 || ^10 +core_version_requirement: ^9.4 || ^10 configure: msqrole.settings_form +dependencies: + - token:token -# Information added by Drupal.org packaging script on 2022-04-22 -version: '1.0.8' +# Information added by Drupal.org packaging script on 2023-07-22 +version: '1.0.10' project: 'msqrole' -datestamp: 1650607671 +datestamp: 1690031510 diff --git a/web/modules/msqrole/msqrole.module b/web/modules/msqrole/msqrole.module index 70b2a15224af669597ce1ad2adc245bbe88d7d35..e117bc1e9d13624f3bf591265a5617c75929bf04 100644 --- a/web/modules/msqrole/msqrole.module +++ b/web/modules/msqrole/msqrole.module @@ -1,8 +1,8 @@ <?php -use Drupal\Core\Render\Renderer; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; +use Drupal\user\Entity\Role; /** * Implements hook_help(). @@ -30,12 +30,26 @@ function msqrole_theme() { ]; } +/** + * Implements hook_entity_type_alter(). + */ +function msqrole_entity_type_alter(array &$entity_types) { + /** + * @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types + */ + // Set the user class, because we need to override the getRoles method. + $entity_types['user'] + ->setClass('Drupal\\msqrole\\Entity\\MasqueradeRoleUser'); +} + /** * Implements hook_user_logout(). */ function msqrole_user_logout($account) { - /** @var RoleManager $roleManager */ - if (!$role_manager = Drupal::service('msqrole.manager')) { + /** + * @var \Drupal\msqrole\RoleManagerInterface $roleManager + */ + if (!$role_manager = \Drupal::service('msqrole.manager')) { return; } @@ -50,7 +64,7 @@ function msqrole_page_attachments(array &$page) { /** * @var \Drupal\msqrole\RoleManagerInterface $roleManager */ - if (!$role_manager = Drupal::service('msqrole.manager')) { + if (!$role_manager = \Drupal::service('msqrole.manager')) { return; } @@ -60,12 +74,12 @@ function msqrole_page_attachments(array &$page) { } $roles = []; - foreach ($current_user->getRoles() as $role) { - if ($role === 'authenticated') { + foreach ($current_user->getRoles() as $role_id) { + if ($role_id === 'authenticated') { continue; } - $current = \Drupal\user\Entity\Role::load($role); - $roles[$role] = $current->label(); + $role = Role::load($role_id); + $roles[$role_id] = $role->label(); } $render = [ @@ -79,12 +93,12 @@ function msqrole_page_attachments(array &$page) { ], ]; - /** @var Renderer $renderer */ + /** + * @var \Drupal\Core\Render\RendererInterface $renderer + */ $renderer = \Drupal::service('renderer'); - $settings_js = [ + $page['#attached']['drupalSettings']['msqrole'] = [ 'markup' => $renderer->renderPlain($render), ]; - - $page['#attached']['drupalSettings']['msqrole'] = $settings_js; $page['#attached']['library'][] = 'msqrole/msqrole.status'; } diff --git a/web/modules/msqrole/msqrole.services.yml b/web/modules/msqrole/msqrole.services.yml index 96195be912fdf5534de4c70c873f1bcdc5854125..f2158931e9d34dabbedcc4163c248f73acb339c7 100644 --- a/web/modules/msqrole/msqrole.services.yml +++ b/web/modules/msqrole/msqrole.services.yml @@ -1,7 +1,7 @@ services: msqrole.manager: class: Drupal\msqrole\RoleManager - arguments: [ '@user.data', '@entity_type.manager', '@config.factory' ] + arguments: [ '@user.data', '@entity_type.manager', '@config.factory', '@token' ] current_user: class: Drupal\msqrole\MasqueradeAccountProxy arguments: [ '@event_dispatcher', '@msqrole.manager' ] diff --git a/web/modules/msqrole/src/Controller/MasqueradeRoleReset.php b/web/modules/msqrole/src/Controller/MasqueradeRoleReset.php index d49376eada1dd359799dc6e0a9543fe2780de467..da85debc5acb279352dd06819daf0035596de895 100644 --- a/web/modules/msqrole/src/Controller/MasqueradeRoleReset.php +++ b/web/modules/msqrole/src/Controller/MasqueradeRoleReset.php @@ -24,14 +24,14 @@ class MasqueradeRoleReset extends ControllerBase { * * @var \Drupal\msqrole\RoleManagerInterface */ - protected $roleManager; + protected RoleManagerInterface $roleManager; /** * The redirect destination object. * * @var \Drupal\Core\Routing\RedirectDestinationInterface */ - protected $destination; + protected RedirectDestinationInterface $destination; /** * MasqueradeRoleReset constructor. @@ -66,10 +66,11 @@ public static function create(ContainerInterface $container) { public function reset() { $this->roleManager->removeData($this->currentUser()->id()); - // Invalidate cache tags + // Invalidate cache tags. try { $this->roleManager->invalidateTags($this->currentUser()->id()); } catch (InvalidPluginDefinitionException | PluginNotFoundException $e) { + // Do nothing if this fails. } try { @@ -78,7 +79,9 @@ public function reset() { return $this->redirect($destination->getRouteName(), $destination->getRouteParameters()); } } catch(\Exception $e) { + // Do nothing, just redirect to the front page. } + return $this->redirect('<front>'); } diff --git a/web/modules/msqrole/src/DynamicRolePermissions.php b/web/modules/msqrole/src/DynamicRolePermissions.php index d17337a7f522950681e6357ab29b3ea9deef97fc..9a4595212e8fa889f166b06fec2a828f3c7e729c 100644 --- a/web/modules/msqrole/src/DynamicRolePermissions.php +++ b/web/modules/msqrole/src/DynamicRolePermissions.php @@ -25,9 +25,6 @@ public static function callback() { $roles = $role_manager->getConfigurableRoles(); $permissions = []; - /** - * @var \Drupal\user\RoleInterface $role - */ foreach ($roles as $role) { $permissions['masquerade as ' . $role->id()] = [ 'title' => t('Masquerade as :role', [ diff --git a/web/modules/msqrole/src/Entity/MasqueradeRoleUser.php b/web/modules/msqrole/src/Entity/MasqueradeRoleUser.php new file mode 100644 index 0000000000000000000000000000000000000000..2386d5e0150baf2f25dae51099cdd23aa7e34fe7 --- /dev/null +++ b/web/modules/msqrole/src/Entity/MasqueradeRoleUser.php @@ -0,0 +1,48 @@ +<?php + +namespace Drupal\msqrole\Entity; + +use Drupal\msqrole\RoleManagerInterface; +use Drupal\user\Entity\User; +use Drupal\user\RoleInterface; + +class MasqueradeRoleUser extends User { + + /** + * The role manager. + * + * @var \Drupal\msqrole\RoleManagerInterface + */ + protected RoleManagerInterface $roleManager; + + /** + * Returns the role manager. + * + * @return \Drupal\msqrole\RoleManagerInterface + */ + protected function roleManager(): RoleManagerInterface { + if (!isset($this->roleManager)) { + $this->roleManager = \Drupal::service('msqrole.manager'); + } + + return $this->roleManager; + } + + /** + * {@inheritdoc} + */ + public function getRoles($exclude_locked_roles = FALSE) { + if (!$this->roleManager()->isActive($this->id())) { + return parent::getRoles($exclude_locked_roles); + } + + $roles = $this->roleManager()->getRoles($this->id()); + if ($exclude_locked_roles) { + unset($roles[RoleInterface::ANONYMOUS_ID]); + unset($roles[RoleInterface::AUTHENTICATED_ID]); + } + + return $roles; + } + +} \ No newline at end of file diff --git a/web/modules/msqrole/src/Form/MasqueradeRoleForm.php b/web/modules/msqrole/src/Form/MasqueradeRoleForm.php index 4fd430d36edac124af809a460b21cc948b94653d..6bbc8839bf191097f645cdbca42ec205bb2be73e 100644 --- a/web/modules/msqrole/src/Form/MasqueradeRoleForm.php +++ b/web/modules/msqrole/src/Form/MasqueradeRoleForm.php @@ -22,7 +22,7 @@ class MasqueradeRoleForm extends FormBase implements ContainerInjectionInterface * * @var \Drupal\msqrole\RoleManagerInterface */ - protected $roleManager; + protected RoleManagerInterface $roleManager; /** * MasqueradeRoleForm constructor. diff --git a/web/modules/msqrole/src/Form/MasqueradeRoleSettings.php b/web/modules/msqrole/src/Form/MasqueradeRoleSettings.php index 09547f56b66b060bae274fbc82f6d61c1bd26d2e..8ceb966e1121a080b17d44f1f62f35bd5b27f13b 100644 --- a/web/modules/msqrole/src/Form/MasqueradeRoleSettings.php +++ b/web/modules/msqrole/src/Form/MasqueradeRoleSettings.php @@ -2,9 +2,12 @@ namespace Drupal\msqrole\Form; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Render\RendererInterface; use Drupal\msqrole\RoleManagerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Class MasqueradeRoleSettings @@ -13,6 +16,37 @@ */ class MasqueradeRoleSettings extends ConfigFormBase { + /** + * The renderer. + * + * @var \Drupal\Core\Render\RendererInterface + */ + protected RendererInterface $renderer; + + /** + * Constructs the settings form. + * + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The config factory. + * @param \Drupal\Core\Render\RendererInterface $renderer + * The renderer. + */ + public function __construct(ConfigFactoryInterface $config_factory, RendererInterface $renderer) { + parent::__construct($config_factory); + + $this->renderer = $renderer; + } + + /** + * {@inheritDoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('config.factory'), + $container->get('renderer') + ); + } + /** * {@inheritdoc} */ @@ -42,11 +76,27 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#type' => 'inline_template', '#template' => '<strong>Default/always enabled tags:</strong><pre>{{ tags }}</pre>', '#context' => [ - 'tags' => print_r(implode(PHP_EOL, - array_merge(RoleManagerInterface::TAGS_TO_INVALIDATE, ['user:{current_user.id}'])), TRUE) + 'tags' => print_r(implode(PHP_EOL, RoleManagerInterface::TAGS_TO_INVALIDATE), TRUE) ], ]; + $token_info = [ + '#theme' => 'token_tree_link', + '#token_types' => [ + 'current-date' => 'current-date', + 'current-user' => 'current-user', + 'current-page' => 'current-page', + 'site' => 'site', + 'random' => 'random', + 'user' => 'user', + ], + '#show_restricted' => TRUE, + '#weight' => 90, + ]; + + $form['tags']['#description'] .= '<br />' . $this->t('This field supports tokens. @browse_tokens_link', [ + '@browse_tokens_link' => $this->renderer->renderPlain($token_info), + ]); return $form; } diff --git a/web/modules/msqrole/src/MasqueradeAccountProxy.php b/web/modules/msqrole/src/MasqueradeAccountProxy.php index 90641a660c024fa070738adad1435d42653c15a6..78609c4eb09e267bf1de1e0056687b1b034277cd 100644 --- a/web/modules/msqrole/src/MasqueradeAccountProxy.php +++ b/web/modules/msqrole/src/MasqueradeAccountProxy.php @@ -21,7 +21,7 @@ class MasqueradeAccountProxy extends AccountProxy implements AccountProxyInterfa * * @var \Drupal\msqrole\RoleManagerInterface */ - protected $roleManager; + protected RoleManagerInterface $roleManager; /** * AccountProxy constructor. @@ -54,7 +54,7 @@ protected function getRoleStorage(): RoleStorageInterface { */ public function getRoles($exclude_locked_roles = FALSE) { if (!$this->roleManager->isActive($this->getAccount()->id())) { - return $this->getAccount()->getRoles($exclude_locked_roles); + return parent::getRoles($exclude_locked_roles); } return $this->roleManager->getRoles($this->getAccount()->id()); } @@ -63,7 +63,7 @@ public function getRoles($exclude_locked_roles = FALSE) { * {@inheritdoc} */ public function hasPermission($permission) { - $default = $this->getAccount()->hasPermission($permission); + $default = parent::hasPermission($permission); if (!$this->roleManager->isActive($this->getAccount()->id())) { return $default; } diff --git a/web/modules/msqrole/src/RoleManager.php b/web/modules/msqrole/src/RoleManager.php index eba6e5640e99d10c634363d1a04cd89fad83e8c9..7810aee59eccdc6f1330ff7986613bcf7bfe4184 100644 --- a/web/modules/msqrole/src/RoleManager.php +++ b/web/modules/msqrole/src/RoleManager.php @@ -4,7 +4,10 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Config\ImmutableConfig; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Utility\Token; +use Drupal\user\Entity\User; use Drupal\user\UserDataInterface; /** @@ -19,24 +22,38 @@ class RoleManager implements RoleManagerInterface { * * @var \Drupal\user\UserDataInterface */ - protected $userData; + protected UserDataInterface $userData; /** * The entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ - protected $entityTypeManager; + protected EntityTypeManagerInterface $entityTypeManager; /** - * The config factory. + * The msqrole config. * * @var \Drupal\Core\Config\ImmutableConfig */ - protected $config; + protected ImmutableConfig $config; /** - * RoleManager constructor. + * The theme config. + * + * @var \Drupal\Core\Config\ImmutableConfig + */ + protected ImmutableConfig $themeConfig; + + /** + * The token service. + * + * @var \Drupal\Core\Utility\Token + */ + protected Token $token; + + /** + * Constructs the RoleManager class. * * @param \Drupal\user\UserDataInterface $user_data * The user data object. @@ -45,10 +62,12 @@ class RoleManager implements RoleManagerInterface { * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The config factory. */ - public function __construct(UserDataInterface $user_data, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory) { + public function __construct(UserDataInterface $user_data, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, Token $token) { $this->userData = $user_data; $this->entityTypeManager = $entity_type_manager; $this->config = $config_factory->get('msqrole.settings'); + $this->themeConfig = $config_factory->get('system.theme'); + $this->token = $token; } /** @@ -60,7 +79,6 @@ public function isPermissionInRoles($permission, array $roles) { return FALSE; } - /** @var \Drupal\user\RoleInterface $role */ foreach ($roles as $role) { if ($role->hasPermission($permission)) { return TRUE; @@ -73,12 +91,13 @@ public function isPermissionInRoles($permission, array $roles) { /** * {@inheritDoc} */ - public function getAllRoles(?array $rids = NULL) { - if (is_array($rids)) { + public function getAllRoles(?array $role_ids = NULL) { + if (is_array($role_ids)) { return $this->entityTypeManager ->getStorage('user_role') - ->loadMultiple($rids); + ->loadMultiple($role_ids); } + return $this->entityTypeManager ->getStorage('user_role') ->loadMultiple(); @@ -164,13 +183,25 @@ public function removeData($uid, ?string $key = NULL) { * {@inheritDoc} */ public function invalidateTags($uid) { - $custom_tags = unserialize($this->config->get('tags_to_invalidate')) ?: []; - // Replace possible variables. - // @todo use tokens? - foreach ($custom_tags as &$tag) { - $tag = str_replace('{current_user.id}', $uid, $tag); + $user = User::load($uid); + $admin_theme = $this->themeConfig->get('admin'); + $default_theme = $this->themeConfig->get('default'); + + // Replace possible variables in the tags. + $tags = Cache::mergeTags( + RoleManagerInterface::TAGS_TO_INVALIDATE, + (unserialize($this->config->get('tags_to_invalidate')) ?: []) + ); + foreach ($tags as &$tag) { + $tag = $this->token->replace($tag, [ + 'user' => $user, + ]); + $tag = str_replace('[theme:admin]', $admin_theme, $tag); + $tag = str_replace('[theme:default]', $default_theme, $tag); } - Cache::invalidateTags(array_merge(RoleManagerInterface::TAGS_TO_INVALIDATE, ['user:' . $uid], $custom_tags)); + $tags = array_filter($tags); + + Cache::invalidateTags($tags); } } diff --git a/web/modules/msqrole/src/RoleManagerInterface.php b/web/modules/msqrole/src/RoleManagerInterface.php index 91940943bf33cae9c92977be9cf7b08d0c3e9772..2d695a563c3ca2a16ef90ed4066a55d5c04698ce 100644 --- a/web/modules/msqrole/src/RoleManagerInterface.php +++ b/web/modules/msqrole/src/RoleManagerInterface.php @@ -2,6 +2,8 @@ namespace Drupal\msqrole; +use Drupal\user\RoleInterface; + /** * Interface RoleManagerInterface. * @@ -13,12 +15,16 @@ interface RoleManagerInterface { * Tags to invalidate when masquerading as different role. */ const TAGS_TO_INVALIDATE = [ - 'config:block.block.bartik_local_actions', - 'config:block.block.bartik_local_tasks', + 'config:block.block.[theme:admin]_local_actions', + 'config:block.block.[theme:admin]_local_tasks', + 'config:block.block.[theme:default]_local_actions', + 'config:block.block.[theme:default]_local_tasks', 'config:system.menu.account', 'config:system.menu.admin', 'config:system.menu.tools', 'local_task', + 'local_action', + 'user:[user:uid]', ]; /** @@ -37,18 +43,18 @@ public function isPermissionInRoles($permission, array $roles); /** * Returns all existing roles or roles based on given ids. * - * @param array|null $rids + * @param array|null $role_ids * Array of role ids to load. * - * @return array + * @return \Drupal\user\RoleInterface[] * Array of roles. */ - public function getAllRoles(?array $rids = NULL); + public function getAllRoles(?array $role_ids = NULL); /** * Returns configurable roles. * - * @return array + * @return \Drupal\user\RoleInterface[] * The configurable roles. */ public function getConfigurableRoles(); @@ -57,7 +63,7 @@ public function getConfigurableRoles(); * Returns the role the current user is masquerading as. * * @return array - * User roles. + * User roles as an array of strings. */ public function getRoles($uid); diff --git a/web/modules/msqrole/templates/msqrole-status.html.twig b/web/modules/msqrole/templates/msqrole-status.html.twig index 705e81ca3a11c34aa8dbe6e76eee7b24166501de..d543d73c04f146a9dc855a9aab938583fa84f404 100644 --- a/web/modules/msqrole/templates/msqrole-status.html.twig +++ b/web/modules/msqrole/templates/msqrole-status.html.twig @@ -1,9 +1,7 @@ <div class="masquerade-role-status"> - <div class="content"> - <div class="roles"> - <label>{{ 'Current roles'|t }}:</label> - <br/>{{- roles|join(', ', ' and '|t) -}} - <div class="reset"><a href="{{ reset_url }}">{{ 'Reset roles'|t }}</a></div> - </div> + <div class="roles"> + <label>{{ 'Masquerade Role'|t }}</label> + <br />{{- roles|join(', ', ' and '|t) -}} + <div class="reset"><a href="{{ reset_url }}">{{ 'Reset roles'|t }}</a></div> </div> </div>