From e4b656af745b9e2b299d0a0550e7a3ebdd0f58ca Mon Sep 17 00:00:00 2001 From: Michael Stenta Date: Fri, 1 Sep 2023 11:32:51 -0400 Subject: [PATCH] Add a setting for allowing Account Admins to assign Account Admin role. --- .../schema/farm_role_account_admin.schema.yml | 7 +++ .../farm_role_account_admin.links.task.yml | 5 ++ .../farm_role_account_admin.routing.yml | 7 +++ .../src/AccountAdminPermissions.php | 25 +++++++- .../src/Form/AccountAdminSettingsForm.php | 63 +++++++++++++++++++ .../Kernel/AccountAdminPermissionsTest.php | 18 +++++- 6 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 modules/core/role/modules/account_admin/config/schema/farm_role_account_admin.schema.yml create mode 100644 modules/core/role/modules/account_admin/farm_role_account_admin.links.task.yml create mode 100644 modules/core/role/modules/account_admin/farm_role_account_admin.routing.yml create mode 100644 modules/core/role/modules/account_admin/src/Form/AccountAdminSettingsForm.php diff --git a/modules/core/role/modules/account_admin/config/schema/farm_role_account_admin.schema.yml b/modules/core/role/modules/account_admin/config/schema/farm_role_account_admin.schema.yml new file mode 100644 index 000000000..e802eccf0 --- /dev/null +++ b/modules/core/role/modules/account_admin/config/schema/farm_role_account_admin.schema.yml @@ -0,0 +1,7 @@ +farm_role_account_admin.settings: + type: config_object + label: 'farmOS Account Admin Role settings' + mapping: + allow_peer_role_assignment: + type: boolean + label: 'Allow users with the Account Admin role to assign/revoke the Account Admin role.' diff --git a/modules/core/role/modules/account_admin/farm_role_account_admin.links.task.yml b/modules/core/role/modules/account_admin/farm_role_account_admin.links.task.yml new file mode 100644 index 000000000..9cd209159 --- /dev/null +++ b/modules/core/role/modules/account_admin/farm_role_account_admin.links.task.yml @@ -0,0 +1,5 @@ +farm_role_account_admin.settings: + base_route: farm_settings.settings_page + route_name: farm_role_account_admin.settings + title: 'Account Admin' + weight: 5 diff --git a/modules/core/role/modules/account_admin/farm_role_account_admin.routing.yml b/modules/core/role/modules/account_admin/farm_role_account_admin.routing.yml new file mode 100644 index 000000000..760ab0126 --- /dev/null +++ b/modules/core/role/modules/account_admin/farm_role_account_admin.routing.yml @@ -0,0 +1,7 @@ +farm_role_account_admin.settings: + path: 'farm/settings/account-admin' + defaults: + _form: '\Drupal\farm_role_account_admin\Form\AccountAdminSettingsForm' + _title: 'Account Admin Role settings' + requirements: + _permission: 'administer farm settings' diff --git a/modules/core/role/modules/account_admin/src/AccountAdminPermissions.php b/modules/core/role/modules/account_admin/src/AccountAdminPermissions.php index 26bfe23d1..e2da8574b 100644 --- a/modules/core/role/modules/account_admin/src/AccountAdminPermissions.php +++ b/modules/core/role/modules/account_admin/src/AccountAdminPermissions.php @@ -2,6 +2,7 @@ namespace Drupal\farm_role_account_admin; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\farm_role\ManagedRolePermissionsManagerInterface; use Drupal\user\RoleInterface; @@ -19,14 +20,24 @@ class AccountAdminPermissions implements ContainerInjectionInterface { */ protected $managedRolePermissionsManager; + /** + * The config factory service. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + /** * Constructs an AccountAdminPermissions object. * * @param \Drupal\farm_role\ManagedRolePermissionsManagerInterface $managed_role_permissions_manager * The managed role permissions manager. + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The config factory service. */ - public function __construct(ManagedRolePermissionsManagerInterface $managed_role_permissions_manager) { + public function __construct(ManagedRolePermissionsManagerInterface $managed_role_permissions_manager, ConfigFactoryInterface $config_factory) { $this->managedRolePermissionsManager = $managed_role_permissions_manager; + $this->configFactory = $config_factory; } /** @@ -35,6 +46,7 @@ class AccountAdminPermissions implements ContainerInjectionInterface { public static function create(ContainerInterface $container) { return new static( $container->get('plugin.manager.managed_role_permissions'), + $container->get('config.factory'), ); } @@ -53,9 +65,20 @@ class AccountAdminPermissions implements ContainerInjectionInterface { // Add permissions to the farm_account_admin role. if ($role->id() == 'farm_account_admin') { + // Load the module settings. + $settings = $this->configFactory->get('farm_role_account_admin.settings'); + // Grant the ability to assign managed farmOS roles. $roles = $this->managedRolePermissionsManager->getMangedRoles(); foreach ($roles as $role) { + + // Do not allow assigning the "Account Admin" role if + // allow_peer_role_assignment is disabled. + if ($role->id() == 'farm_account_admin' && !$settings->get('allow_peer_role_assignment', FALSE)) { + continue; + } + + // Add permission to assign the role. $perms[] = 'assign ' . $role->id() . ' role'; } } diff --git a/modules/core/role/modules/account_admin/src/Form/AccountAdminSettingsForm.php b/modules/core/role/modules/account_admin/src/Form/AccountAdminSettingsForm.php new file mode 100644 index 000000000..0519862e8 --- /dev/null +++ b/modules/core/role/modules/account_admin/src/Form/AccountAdminSettingsForm.php @@ -0,0 +1,63 @@ +config(static::SETTINGS); + + $form['allow_peer_role_assignment'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Allow peer role assignment'), + '#description' => $this->t('Allow users with the Account Admin role to assign/revoke the Account Admin role.'), + '#default_value' => $config->get('allow_peer_role_assignment'), + ]; + + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $this->configFactory->getEditable(static::SETTINGS) + ->set('allow_peer_role_assignment', $form_state->getValue('allow_peer_role_assignment')) + ->save(); + + parent::submitForm($form, $form_state); + } + +} diff --git a/modules/core/role/modules/account_admin/tests/src/Kernel/AccountAdminPermissionsTest.php b/modules/core/role/modules/account_admin/tests/src/Kernel/AccountAdminPermissionsTest.php index fb23f59c3..ebad83452 100644 --- a/modules/core/role/modules/account_admin/tests/src/Kernel/AccountAdminPermissionsTest.php +++ b/modules/core/role/modules/account_admin/tests/src/Kernel/AccountAdminPermissionsTest.php @@ -49,7 +49,6 @@ class AccountAdminPermissionsTest extends KernelTestBase { $account_admin_permissions = [ 'administer farm settings', 'administer users', - 'assign farm_account_admin role', 'assign farm_manager role', 'assign farm_worker role', 'assign farm_viewer role', @@ -67,6 +66,23 @@ class AccountAdminPermissionsTest extends KernelTestBase { foreach ($account_admin_permissions as $permission) { $this->assertTrue($user->hasPermission($permission)); } + + // Ensure the user does not have the "assign farm_account_admin role" + // permission. + $this->assertFalse($user->hasPermission('assign farm_account_admin role')); + + // Enable the allow_peer_role_assignment setting. + $settings = \Drupal::configFactory()->getEditable('farm_role_account_admin.settings'); + $settings->set('allow_peer_role_assignment', TRUE); + $settings->save(); + + // Rebuild the container so the configuration change takes effect. + $kernel = \Drupal::service('kernel'); + $kernel->invalidateContainer(); + $kernel->rebuildContainer(); + + // Ensure the user has the "assign farm_account_admin role" permission. + $this->assertTrue($user->hasPermission('assign farm_account_admin role')); } }