]> BookStack Code Mirror - bookstack/commitdiff
Permissions: Updated guest user handling so additional roles apply
authorDan Brown <redacted>
Sat, 10 Jun 2023 10:37:01 +0000 (11:37 +0100)
committerDan Brown <redacted>
Sat, 10 Jun 2023 10:37:01 +0000 (11:37 +0100)
Previously additional roles would only partially apply (system or "all"
permissions). This aligns the query-handling of permissions so that
additional roles will be used for permission queries.

Adds migration to detach existing roles as a safety precaution since
this is likely to widen permissions in scenarios that the public user
has other roles assigned already.

For #1229

app/Permissions/PermissionApplicator.php
database/migrations/2023_06_10_071823_remove_guest_user_secondary_roles.php [new file with mode: 0644]
tests/PublicActionTest.php

index 8a02f82e89bef03bd6297add1feeae921a49b5b7..b4fafaa9ee1756f6604d5cc20f46e2091ed5f787 100644 (file)
@@ -183,10 +183,6 @@ class PermissionApplicator
      */
     protected function getCurrentUserRoleIds(): array
     {
-        if (auth()->guest()) {
-            return [Role::getSystemRole('public')->id];
-        }
-
         return $this->currentUser()->roles->pluck('id')->values()->all();
     }
 
diff --git a/database/migrations/2023_06_10_071823_remove_guest_user_secondary_roles.php b/database/migrations/2023_06_10_071823_remove_guest_user_secondary_roles.php
new file mode 100644 (file)
index 0000000..8d04efd
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Support\Facades\DB;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        $guestUserId = DB::table('users')
+            ->where('system_name', '=', 'public')
+            ->first(['id'])->id;
+        $publicRoleId = DB::table('roles')
+            ->where('system_name', '=', 'public')
+            ->first(['id'])->id;
+
+        // This migration deletes secondary "Guest" user role assignments
+        // as a safety precaution upon upgrade since the logic is changing
+        // within the release this is introduced in, which could result in wider
+        // permissions being provided upon upgrade without this intervention.
+
+        // Previously, added roles would only partially apply their permissions
+        // since some permission checks would only consider the originally assigned
+        // public role, and not added roles. Within this release, additional roles
+        // will fully apply.
+        DB::table('role_user')
+            ->where('user_id', '=', $guestUserId)
+            ->where('role_id', '!=', $publicRoleId)
+            ->delete();
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        // No structural changes to make, and we cannot know the role ids to re-assign.
+    }
+};
index 97299f7570b5c21fb5149d5edca59acb8df50ac0..6f0e2f1d3bb4d886684af5e7ee3863926a552460 100644 (file)
@@ -193,4 +193,18 @@ class PublicActionTest extends TestCase
         $resp->assertRedirect($book->getUrl());
         $this->followRedirects($resp)->assertSee($book->name);
     }
+
+    public function test_public_view_can_take_on_other_roles()
+    {
+        $this->setSettings(['app-public' => 'true']);
+        $newRole = $this->users->attachNewRole(User::getDefault(), []);
+        $page = $this->entities->page();
+        $this->permissions->disableEntityInheritedPermissions($page);
+        $this->permissions->addEntityPermission($page, ['view', 'update'], $newRole);
+
+        $resp = $this->get($page->getUrl());
+        $resp->assertOk();
+
+        $this->withHtml($resp)->assertLinkExists($page->getUrl('/edit'));
+    }
 }