From 0123d83fb27f286d8ad4a0a865d82974ad099a94 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 16 Dec 2022 17:44:13 +0000 Subject: [PATCH] Fixed not being able to remove all user roles User roles would only be actioned if they existed in the form request, hence removal of all roles would have no data to action upon. This adds a placeholder 0-id role to ensure there is always role data to send, even when no roles are selected. This field value is latter filtered out. Added test to cover. Likely related to #3922. --- app/Auth/UserRepo.php | 2 ++ .../views/form/role-checkboxes.blade.php | 1 + tests/User/UserManagementTest.php | 30 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/app/Auth/UserRepo.php b/app/Auth/UserRepo.php index 78bcb978e..2c27f34a7 100644 --- a/app/Auth/UserRepo.php +++ b/app/Auth/UserRepo.php @@ -234,6 +234,8 @@ class UserRepo */ protected function setUserRoles(User $user, array $roles) { + $roles = array_filter(array_values($roles)); + if ($this->demotingLastAdmin($user, $roles)) { throw new UserUpdateException(trans('errors.role_cannot_remove_only_admin'), $user->getEditUrl()); } diff --git a/resources/views/form/role-checkboxes.blade.php b/resources/views/form/role-checkboxes.blade.php index 7e5ca629a..b7b969d89 100644 --- a/resources/views/form/role-checkboxes.blade.php +++ b/resources/views/form/role-checkboxes.blade.php @@ -1,5 +1,6 @@
+ @foreach($roles as $role)
@include('form.custom-checkbox', [ diff --git a/tests/User/UserManagementTest.php b/tests/User/UserManagementTest.php index 4991e052a..b5cd764da 100644 --- a/tests/User/UserManagementTest.php +++ b/tests/User/UserManagementTest.php @@ -274,4 +274,34 @@ class UserManagementTest extends TestCase $resp->assertSessionHasErrors(['language' => 'The language may not be greater than 15 characters.']); $resp->assertSessionHasErrors(['language' => 'The language may only contain letters, numbers, dashes and underscores.']); } + + public function test_role_removal_on_user_edit_removes_all_role_assignments() + { + $user = $this->getEditor(); + + $this->assertEquals(1, $user->roles()->count()); + + // A roles[0] hidden fields is used to indicate the existence of role selection in the submission + // of the user edit form. We check that field is used and emulate its submission. + $resp = $this->asAdmin()->get("/settings/users/{$user->id}"); + $this->withHtml($resp)->assertElementExists('input[type="hidden"][name="roles[0]"][value="0"]'); + + $resp = $this->asAdmin()->put("/settings/users/{$user->id}", [ + 'name' => $user->name, + 'email' => $user->email, + 'roles' => ['0' => '0'], + ]); + $resp->assertRedirect("/settings/users"); + + $this->assertEquals(0, $user->roles()->count()); + } + + public function test_role_form_hidden_indicator_field_does_not_exist_where_roles_cannot_be_managed() + { + $user = $this->getEditor(); + $resp = $this->actingAs($user)->get("/settings/users/{$user->id}"); + $html = $this->withHtml($resp); + $html->assertElementExists('input[name="email"]'); + $html->assertElementNotExists('input[type="hidden"][name="roles[0]"]'); + } }