]> BookStack Code Mirror - bookstack/commitdiff
Fixed not being able to remove all user roles
authorDan Brown <redacted>
Fri, 16 Dec 2022 17:44:13 +0000 (17:44 +0000)
committerDan Brown <redacted>
Fri, 16 Dec 2022 17:44:13 +0000 (17:44 +0000)
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
resources/views/form/role-checkboxes.blade.php
tests/User/UserManagementTest.php

index 78bcb978ebc997f3346d0e8dfb8a319cbfe641a4..2c27f34a7e84d120f6aad811c4d4750804c08092 100644 (file)
@@ -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());
         }
index 7e5ca629a8598a4e9cb5b8603e53d08e0d6c9807..b7b969d8973425be7d416f59d235a24508d39aaf 100644 (file)
@@ -1,5 +1,6 @@
 
 <div class="toggle-switch-list dual-column-content">
+    <input type="hidden" name="{{ $name }}[0]" value="0">
     @foreach($roles as $role)
         <div>
             @include('form.custom-checkbox', [
index 4991e052a3bf121a969916bf2714e2ab99b0c8ce..b5cd764da13f4ac2a69cb112cbca42ee11baed3b 100644 (file)
@@ -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]"]');
+    }
 }
Morty Proxy This is a proxified and sanitized view of the page, visit original site.