diff --git a/helfi_platform_config.module b/helfi_platform_config.module index 87c463628..f8aff87ab 100644 --- a/helfi_platform_config.module +++ b/helfi_platform_config.module @@ -462,3 +462,28 @@ function helfi_platform_config_config_ignore_settings_alter(array &$settings) { array_push($settings, $config); } } + +/** + * Implements hook_user_cancel_methods_alter(). + */ +function helfi_platform_config_user_cancel_methods_alter(array &$methods): void { + /** @var \Drupal\Core\Session\AccountInterface $account */ + $account = \Drupal::currentUser(); + + // Only allow user to disable user accounts if the user doesn't have + // a permission to delete user accounts. + $white_listed_methods = [ + 'user_cancel_block', + 'user_cancel_block_unpublish', + ]; + + // Deny access to all non-whitelisted methods if user doesn't have + // the 'delete user accounts' permission. + if (!$account->hasPermission('delete user accounts')) { + foreach ($methods as $name => &$method) { + if (!in_array($name, $white_listed_methods)) { + $method['access'] = FALSE; + } + } + } +} diff --git a/helfi_platform_config.permissions.yml b/helfi_platform_config.permissions.yml new file mode 100644 index 000000000..65cb8132e --- /dev/null +++ b/helfi_platform_config.permissions.yml @@ -0,0 +1,2 @@ +delete user accounts: + title: Delete user accounts diff --git a/tests/src/Functional/UserCancelFormTest.php b/tests/src/Functional/UserCancelFormTest.php new file mode 100644 index 000000000..1aad023ac --- /dev/null +++ b/tests/src/Functional/UserCancelFormTest.php @@ -0,0 +1,72 @@ +drupalCreateUser([], 'superAdminUser', TRUE); + $adminUser = $this->drupalCreateUser([ + 'access user profiles', + 'administer users', + 'cancel account', + ], 'superUser'); + $editorUser = $this->drupalCreateUser([ + 'access user profiles', + 'cancel account', + ], 'editorUser'); + $testUser = $this->drupalCreateUser([], 'testUser'); + + // Test that the superAdminUser can see all cancellation methods + // for the testUser account. + $this->drupalLogin($superAdminUser); + $this->drupalGet('/user/' . $testUser->id() . '/cancel'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->elementExists('xpath', '//input[@value="user_cancel_block"]'); + $this->assertSession()->elementExists('xpath', '//input[@value="user_cancel_block_unpublish"]'); + $this->assertSession()->elementExists('xpath', '//input[@value="user_cancel_reassign"]'); + $this->assertSession()->elementExists('xpath', '//input[@value="user_cancel_delete"]'); + + // Test that the adminUser can see all only cancellation methods, but not + // deletion methods for the testUser account. + $this->drupalLogin($adminUser); + $this->drupalGet('/user/' . $testUser->id() . '/cancel'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->elementExists('xpath', '//input[@value="user_cancel_block"]'); + $this->assertSession()->elementExists('xpath', '//input[@value="user_cancel_block_unpublish"]'); + $this->assertSession()->elementNotExists('xpath', '//input[@value="user_cancel_reassign"]'); + $this->assertSession()->elementNotExists('xpath', '//input[@value="user_cancel_delete"]'); + + // Test that the editorUser cannot access the cancel page. + $this->drupalLogin($editorUser); + $this->drupalGet('/user/' . $testUser->id() . '/cancel'); + $this->assertSession()->statusCodeEquals(403); + } + +}