]> BookStack Code Mirror - bookstack/commitdiff
Reorgranised permission routes into their own controller
authorDan Brown <redacted>
Sun, 9 Oct 2022 15:36:03 +0000 (16:36 +0100)
committerDan Brown <redacted>
Sun, 9 Oct 2022 15:36:03 +0000 (16:36 +0100)
Also introduced helpers for getting entities by slugs since we do it in
so many places.

14 files changed:
app/Console/Commands/CopyShelfPermissions.php
app/Entities/Models/Book.php
app/Entities/Models/Bookshelf.php
app/Entities/Models/Chapter.php
app/Entities/Models/Page.php
app/Entities/Repos/BookshelfRepo.php
app/Entities/Tools/PermissionsUpdater.php
app/Http/Controllers/BookController.php
app/Http/Controllers/BookshelfController.php
app/Http/Controllers/ChapterController.php
app/Http/Controllers/PageController.php
app/Http/Controllers/PermissionsController.php [new file with mode: 0644]
app/Http/Controllers/ReferenceController.php
routes/web.php

index 32adf06839c82d8a78acb8f8ab6e02c621c3d298..18719ae2efeb482f6ae6c245626f8863a332a1cd 100644 (file)
@@ -3,7 +3,7 @@
 namespace BookStack\Console\Commands;
 
 use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Repos\BookshelfRepo;
+use BookStack\Entities\Tools\PermissionsUpdater;
 use Illuminate\Console\Command;
 
 class CopyShelfPermissions extends Command
@@ -25,19 +25,16 @@ class CopyShelfPermissions extends Command
      */
     protected $description = 'Copy shelf permissions to all child books';
 
-    /**
-     * @var BookshelfRepo
-     */
-    protected $bookshelfRepo;
+    protected PermissionsUpdater $permissionsUpdater;
 
     /**
      * Create a new command instance.
      *
      * @return void
      */
-    public function __construct(BookshelfRepo $repo)
+    public function __construct(PermissionsUpdater $permissionsUpdater)
     {
-        $this->bookshelfRepo = $repo;
+        $this->permissionsUpdater = $permissionsUpdater;
         parent::__construct();
     }
 
@@ -80,7 +77,7 @@ class CopyShelfPermissions extends Command
         }
 
         foreach ($shelves as $shelf) {
-            $this->bookshelfRepo->copyDownPermissions($shelf, false);
+            $this->permissionsUpdater->updateBookPermissionsFromShelf($shelf, false);
             $this->info('Copied permissions for shelf [' . $shelf->id . ']');
         }
 
index bf42f20088919a4376a1ce86be548ceff2750f54..4ced9248e64e8b813a5f9a03692ad22d8371a4ae 100644 (file)
@@ -120,4 +120,13 @@ class Book extends Entity implements HasCoverImage
 
         return $pages->concat($chapters)->sortBy('priority')->sortByDesc('draft');
     }
+
+    /**
+     * Get a visible book by its slug.
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+     */
+    public static function getBySlug(string $slug): self
+    {
+        return static::visible()->where('slug', '=', $slug)->firstOrFail();
+    }
 }
index cdc6648f96cddb43109eb0eade96dd91726bc0a7..6310e616f1dc9a42f4729e72a35eb2e07014893b 100644 (file)
@@ -109,4 +109,13 @@ class Bookshelf extends Entity implements HasCoverImage
         $maxOrder = $this->books()->max('order');
         $this->books()->attach($book->id, ['order' => $maxOrder + 1]);
     }
+
+    /**
+     * Get a visible shelf by its slug.
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+     */
+    public static function getBySlug(string $slug): self
+    {
+        return static::visible()->where('slug', '=', $slug)->firstOrFail();
+    }
 }
index af4bbd8e3a66238d722272358086aa45f4aa970d..53eb5091f736cc958a8b09c82e1e9845cbaf2da8 100644 (file)
@@ -58,4 +58,13 @@ class Chapter extends BookChild
         ->orderBy('priority', 'asc')
         ->get();
     }
+
+    /**
+     * Get a visible chapter by its book and page slugs.
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+     */
+    public static function getBySlugs(string $bookSlug, string $chapterSlug): self
+    {
+        return static::visible()->whereSlugs($bookSlug, $chapterSlug)->firstOrFail();
+    }
 }
index 93729d7f26177f679bf02eafcdc3b1d6b238716e..8dd769e1cdb25d2c8dc7db3905e9500b6ca50823 100644 (file)
@@ -145,4 +145,13 @@ class Page extends BookChild
 
         return $refreshed;
     }
+
+    /**
+     * Get a visible page by its book and page slugs.
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+     */
+    public static function getBySlugs(string $bookSlug, string $pageSlug): self
+    {
+        return static::visible()->whereSlugs($bookSlug, $pageSlug)->firstOrFail();
+    }
 }
index 556ded017b659ea506a54774242c30e798b2baa2..d7759deb43c41a66178e1ffb16e5f16f10422dbf 100644 (file)
@@ -134,31 +134,6 @@ class BookshelfRepo
         $shelf->books()->sync($syncData);
     }
 
-    /**
-     * Copy down the permissions of the given shelf to all child books.
-     */
-    public function copyDownPermissions(Bookshelf $shelf, $checkUserPermissions = true): int
-    {
-        $shelfPermissions = $shelf->permissions()->get(['role_id', 'view', 'create', 'update', 'delete'])->toArray();
-        $shelfBooks = $shelf->books()->get(['id', 'restricted', 'owned_by']);
-        $updatedBookCount = 0;
-
-        /** @var Book $book */
-        foreach ($shelfBooks as $book) {
-            if ($checkUserPermissions && !userCan('restrictions-manage', $book)) {
-                continue;
-            }
-            $book->permissions()->delete();
-            $book->restricted = $shelf->restricted;
-            $book->permissions()->createMany($shelfPermissions);
-            $book->save();
-            $book->rebuildPermissions();
-            $updatedBookCount++;
-        }
-
-        return $updatedBookCount;
-    }
-
     /**
      * Remove a bookshelf from the system.
      *
index a547cd0a8f40473429273aa62b9c0fb95ddd44fc..2747def18df1daf723d8777ec3f89506e74a5f1f 100644 (file)
@@ -5,6 +5,8 @@ namespace BookStack\Entities\Tools;
 use BookStack\Actions\ActivityType;
 use BookStack\Auth\Permissions\EntityPermission;
 use BookStack\Auth\User;
+use BookStack\Entities\Models\Book;
+use BookStack\Entities\Models\Bookshelf;
 use BookStack\Entities\Models\Entity;
 use BookStack\Facades\Activity;
 use Illuminate\Http\Request;
@@ -67,4 +69,30 @@ class PermissionsUpdater
 
         return $formatted;
     }
+
+    /**
+     * Copy down the permissions of the given shelf to all child books.
+     */
+    public function updateBookPermissionsFromShelf(Bookshelf $shelf, $checkUserPermissions = true): int
+    {
+        // TODO - Fix for new format
+        $shelfPermissions = $shelf->permissions()->get(['role_id', 'view', 'create', 'update', 'delete'])->toArray();
+        $shelfBooks = $shelf->books()->get(['id', 'restricted', 'owned_by']);
+        $updatedBookCount = 0;
+
+        /** @var Book $book */
+        foreach ($shelfBooks as $book) {
+            if ($checkUserPermissions && !userCan('restrictions-manage', $book)) {
+                continue;
+            }
+            $book->permissions()->delete();
+            $book->restricted = $shelf->restricted;
+            $book->permissions()->createMany($shelfPermissions);
+            $book->save();
+            $book->rebuildPermissions();
+            $updatedBookCount++;
+        }
+
+        return $updatedBookCount;
+    }
 }
index cc2f6f534b9f86264564601e896087a0e18e23e6..b323ae496e42586a1702c9dafea528a0810837e5 100644 (file)
@@ -10,7 +10,6 @@ use BookStack\Entities\Repos\BookRepo;
 use BookStack\Entities\Tools\BookContents;
 use BookStack\Entities\Tools\Cloner;
 use BookStack\Entities\Tools\HierarchyTransformer;
-use BookStack\Entities\Tools\PermissionsUpdater;
 use BookStack\Entities\Tools\ShelfContext;
 use BookStack\Exceptions\ImageUploadException;
 use BookStack\Exceptions\NotFoundException;
@@ -209,36 +208,6 @@ class BookController extends Controller
         return redirect('/books');
     }
 
-    /**
-     * Show the permissions view.
-     */
-    public function showPermissions(string $bookSlug)
-    {
-        $book = $this->bookRepo->getBySlug($bookSlug);
-        $this->checkOwnablePermission('restrictions-manage', $book);
-
-        return view('books.permissions', [
-            'book' => $book,
-        ]);
-    }
-
-    /**
-     * Set the restrictions for this book.
-     *
-     * @throws Throwable
-     */
-    public function permissions(Request $request, PermissionsUpdater $permissionsUpdater, string $bookSlug)
-    {
-        $book = $this->bookRepo->getBySlug($bookSlug);
-        $this->checkOwnablePermission('restrictions-manage', $book);
-
-        $permissionsUpdater->updateFromPermissionsForm($book, $request);
-
-        $this->showSuccessNotification(trans('entities.books_permissions_updated'));
-
-        return redirect($book->getUrl());
-    }
-
     /**
      * Show the view to copy a book.
      *
index 2143b876a517dc10dd8df31f09101af8ef97e90e..3c63be6318b92b28e1c5ed3e6584538d0bfad6df 100644 (file)
@@ -6,7 +6,6 @@ use BookStack\Actions\ActivityQueries;
 use BookStack\Actions\View;
 use BookStack\Entities\Models\Book;
 use BookStack\Entities\Repos\BookshelfRepo;
-use BookStack\Entities\Tools\PermissionsUpdater;
 use BookStack\Entities\Tools\ShelfContext;
 use BookStack\Exceptions\ImageUploadException;
 use BookStack\Exceptions\NotFoundException;
@@ -207,46 +206,4 @@ class BookshelfController extends Controller
 
         return redirect('/shelves');
     }
-
-    /**
-     * Show the permissions view.
-     */
-    public function showPermissions(string $slug)
-    {
-        $shelf = $this->shelfRepo->getBySlug($slug);
-        $this->checkOwnablePermission('restrictions-manage', $shelf);
-
-        return view('shelves.permissions', [
-            'shelf' => $shelf,
-        ]);
-    }
-
-    /**
-     * Set the permissions for this bookshelf.
-     */
-    public function permissions(Request $request, PermissionsUpdater $permissionsUpdater, string $slug)
-    {
-        $shelf = $this->shelfRepo->getBySlug($slug);
-        $this->checkOwnablePermission('restrictions-manage', $shelf);
-
-        $permissionsUpdater->updateFromPermissionsForm($shelf, $request);
-
-        $this->showSuccessNotification(trans('entities.shelves_permissions_updated'));
-
-        return redirect($shelf->getUrl());
-    }
-
-    /**
-     * Copy the permissions of a bookshelf to the child books.
-     */
-    public function copyPermissions(string $slug)
-    {
-        $shelf = $this->shelfRepo->getBySlug($slug);
-        $this->checkOwnablePermission('restrictions-manage', $shelf);
-
-        $updateCount = $this->shelfRepo->copyDownPermissions($shelf);
-        $this->showSuccessNotification(trans('entities.shelves_copy_permission_success', ['count' => $updateCount]));
-
-        return redirect($shelf->getUrl());
-    }
 }
index 6695c28681c69507c07a1c52eb03294023cf582a..4d2bcb2f1d444057daf8dff40fd4060bf7cf0fe4 100644 (file)
@@ -9,7 +9,6 @@ use BookStack\Entities\Tools\BookContents;
 use BookStack\Entities\Tools\Cloner;
 use BookStack\Entities\Tools\HierarchyTransformer;
 use BookStack\Entities\Tools\NextPreviousContentLocator;
-use BookStack\Entities\Tools\PermissionsUpdater;
 use BookStack\Exceptions\MoveOperationException;
 use BookStack\Exceptions\NotFoundException;
 use BookStack\Exceptions\PermissionsException;
@@ -243,38 +242,6 @@ class ChapterController extends Controller
         return redirect($chapterCopy->getUrl());
     }
 
-    /**
-     * Show the Restrictions view.
-     *
-     * @throws NotFoundException
-     */
-    public function showPermissions(string $bookSlug, string $chapterSlug)
-    {
-        $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
-        $this->checkOwnablePermission('restrictions-manage', $chapter);
-
-        return view('chapters.permissions', [
-            'chapter' => $chapter,
-        ]);
-    }
-
-    /**
-     * Set the restrictions for this chapter.
-     *
-     * @throws NotFoundException
-     */
-    public function permissions(Request $request, PermissionsUpdater $permissionsUpdater, string $bookSlug, string $chapterSlug)
-    {
-        $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
-        $this->checkOwnablePermission('restrictions-manage', $chapter);
-
-        $permissionsUpdater->updateFromPermissionsForm($chapter, $request);
-
-        $this->showSuccessNotification(trans('entities.chapters_permissions_success'));
-
-        return redirect($chapter->getUrl());
-    }
-
     /**
      * Convert the chapter to a book.
      */
index 748468b211fd1939e8d211861936dec3afca1078..9e09aed16c1a1ee767171cae27fdc29b4c4d6564 100644 (file)
@@ -11,7 +11,6 @@ use BookStack\Entities\Tools\NextPreviousContentLocator;
 use BookStack\Entities\Tools\PageContent;
 use BookStack\Entities\Tools\PageEditActivity;
 use BookStack\Entities\Tools\PageEditorData;
-use BookStack\Entities\Tools\PermissionsUpdater;
 use BookStack\Exceptions\NotFoundException;
 use BookStack\Exceptions\PermissionsException;
 use BookStack\References\ReferenceFetcher;
@@ -452,37 +451,4 @@ class PageController extends Controller
 
         return redirect($pageCopy->getUrl());
     }
-
-    /**
-     * Show the Permissions view.
-     *
-     * @throws NotFoundException
-     */
-    public function showPermissions(string $bookSlug, string $pageSlug)
-    {
-        $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
-        $this->checkOwnablePermission('restrictions-manage', $page);
-
-        return view('pages.permissions', [
-            'page' => $page,
-        ]);
-    }
-
-    /**
-     * Set the permissions for this page.
-     *
-     * @throws NotFoundException
-     * @throws Throwable
-     */
-    public function permissions(Request $request, PermissionsUpdater $permissionsUpdater, string $bookSlug, string $pageSlug)
-    {
-        $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
-        $this->checkOwnablePermission('restrictions-manage', $page);
-
-        $permissionsUpdater->updateFromPermissionsForm($page, $request);
-
-        $this->showSuccessNotification(trans('entities.pages_permissions_success'));
-
-        return redirect($page->getUrl());
-    }
 }
diff --git a/app/Http/Controllers/PermissionsController.php b/app/Http/Controllers/PermissionsController.php
new file mode 100644 (file)
index 0000000..92f994b
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+
+namespace BookStack\Http\Controllers;
+
+use BookStack\Entities\Models\Book;
+use BookStack\Entities\Models\Bookshelf;
+use BookStack\Entities\Models\Chapter;
+use BookStack\Entities\Models\Page;
+use BookStack\Entities\Tools\PermissionsUpdater;
+use Illuminate\Http\Request;
+
+class PermissionsController extends Controller
+{
+    protected PermissionsUpdater $permissionsUpdater;
+
+    public function __construct(PermissionsUpdater $permissionsUpdater)
+    {
+        $this->permissionsUpdater = $permissionsUpdater;
+    }
+
+    /**
+     * Show the Permissions view for a page.
+     */
+    public function showForPage(string $bookSlug, string $pageSlug)
+    {
+        $page = Page::getBySlugs($bookSlug, $pageSlug);
+        $this->checkOwnablePermission('restrictions-manage', $page);
+
+        return view('pages.permissions', [
+            'page' => $page,
+        ]);
+    }
+
+    /**
+     * Set the permissions for a page.
+     */
+    public function updateForPage(Request $request, string $bookSlug, string $pageSlug)
+    {
+        $page = Page::getBySlugs($bookSlug, $pageSlug);
+        $this->checkOwnablePermission('restrictions-manage', $page);
+
+        $this->permissionsUpdater->updateFromPermissionsForm($page, $request);
+
+        $this->showSuccessNotification(trans('entities.pages_permissions_success'));
+
+        return redirect($page->getUrl());
+    }
+
+    /**
+     * Show the Restrictions view for a chapter.
+     */
+    public function showForChapter(string $bookSlug, string $chapterSlug)
+    {
+        $chapter = Chapter::getBySlugs($bookSlug, $chapterSlug);
+        $this->checkOwnablePermission('restrictions-manage', $chapter);
+
+        return view('chapters.permissions', [
+            'chapter' => $chapter,
+        ]);
+    }
+
+    /**
+     * Set the restrictions for a chapter.
+     */
+    public function updateForChapter(Request $request, string $bookSlug, string $chapterSlug)
+    {
+        $chapter = Chapter::getBySlugs($bookSlug, $chapterSlug);
+        $this->checkOwnablePermission('restrictions-manage', $chapter);
+
+        $this->permissionsUpdater->updateFromPermissionsForm($chapter, $request);
+
+        $this->showSuccessNotification(trans('entities.chapters_permissions_success'));
+
+        return redirect($chapter->getUrl());
+    }
+
+    /**
+     * Show the permissions view for a book.
+     */
+    public function showForBook(string $slug)
+    {
+        $book = Book::getBySlug($slug);
+        $this->checkOwnablePermission('restrictions-manage', $book);
+
+        return view('books.permissions', [
+            'book' => $book,
+        ]);
+    }
+
+    /**
+     * Set the restrictions for a book.
+     */
+    public function updateForBook(Request $request, string $slug)
+    {
+        $book = Book::getBySlug($slug);
+        $this->checkOwnablePermission('restrictions-manage', $book);
+
+        $this->permissionsUpdater->updateFromPermissionsForm($book, $request);
+
+        $this->showSuccessNotification(trans('entities.books_permissions_updated'));
+
+        return redirect($book->getUrl());
+    }
+
+    /**
+     * Show the permissions view for a shelf.
+     */
+    public function showForShelf(string $slug)
+    {
+        $shelf = Bookshelf::getBySlug($slug);
+        $this->checkOwnablePermission('restrictions-manage', $shelf);
+
+        return view('shelves.permissions', [
+            'shelf' => $shelf,
+        ]);
+    }
+
+    /**
+     * Set the permissions for a shelf.
+     */
+    public function updateForShelf(Request $request, string $slug)
+    {
+        $shelf = Bookshelf::getBySlug($slug);
+        $this->checkOwnablePermission('restrictions-manage', $shelf);
+
+        $this->permissionsUpdater->updateFromPermissionsForm($shelf, $request);
+
+        $this->showSuccessNotification(trans('entities.shelves_permissions_updated'));
+
+        return redirect($shelf->getUrl());
+    }
+
+    /**
+     * Copy the permissions of a bookshelf to the child books.
+     */
+    public function copyShelfPermissionsToBooks(string $slug)
+    {
+        $shelf = Bookshelf::getBySlug($slug);
+        $this->checkOwnablePermission('restrictions-manage', $shelf);
+
+        $updateCount = $this->permissionsUpdater->updateBookPermissionsFromShelf($shelf);
+        $this->showSuccessNotification(trans('entities.shelves_copy_permission_success', ['count' => $updateCount]));
+
+        return redirect($shelf->getUrl());
+    }
+}
index 1daf1818cd04aae2028bb89d18c5e17aeeb77247..b9b3e0eab9613e243a0dd7d67c718c1ef81fd8ec 100644 (file)
@@ -22,8 +22,7 @@ class ReferenceController extends Controller
      */
     public function page(string $bookSlug, string $pageSlug)
     {
-        /** @var Page $page */
-        $page = Page::visible()->whereSlugs($bookSlug, $pageSlug)->firstOrFail();
+        $page = Page::getBySlugs($bookSlug, $pageSlug);
         $references = $this->referenceFetcher->getPageReferencesToEntity($page);
 
         return view('pages.references', [
@@ -37,8 +36,7 @@ class ReferenceController extends Controller
      */
     public function chapter(string $bookSlug, string $chapterSlug)
     {
-        /** @var Chapter $chapter */
-        $chapter = Chapter::visible()->whereSlugs($bookSlug, $chapterSlug)->firstOrFail();
+        $chapter = Chapter::getBySlugs($bookSlug, $chapterSlug);
         $references = $this->referenceFetcher->getPageReferencesToEntity($chapter);
 
         return view('chapters.references', [
@@ -52,7 +50,7 @@ class ReferenceController extends Controller
      */
     public function book(string $slug)
     {
-        $book = Book::visible()->where('slug', '=', $slug)->firstOrFail();
+        $book = Book::getBySlug($slug);
         $references = $this->referenceFetcher->getPageReferencesToEntity($book);
 
         return view('books.references', [
@@ -66,7 +64,7 @@ class ReferenceController extends Controller
      */
     public function shelf(string $slug)
     {
-        $shelf = Bookshelf::visible()->where('slug', '=', $slug)->firstOrFail();
+        $shelf = Bookshelf::getBySlug($slug);
         $references = $this->referenceFetcher->getPageReferencesToEntity($shelf);
 
         return view('shelves.references', [
index 26d4b6f133b39618f6836d42e6235770633f9141..8ee5d073930b27eb7184eb0797eb7d340c55371e 100644 (file)
@@ -19,6 +19,7 @@ use BookStack\Http\Controllers\PageController;
 use BookStack\Http\Controllers\PageExportController;
 use BookStack\Http\Controllers\PageRevisionController;
 use BookStack\Http\Controllers\PageTemplateController;
+use BookStack\Http\Controllers\PermissionsController;
 use BookStack\Http\Controllers\RecycleBinController;
 use BookStack\Http\Controllers\ReferenceController;
 use BookStack\Http\Controllers\RoleController;
@@ -61,9 +62,9 @@ Route::middleware('auth')->group(function () {
     Route::get('/shelves/{slug}', [BookshelfController::class, 'show']);
     Route::put('/shelves/{slug}', [BookshelfController::class, 'update']);
     Route::delete('/shelves/{slug}', [BookshelfController::class, 'destroy']);
-    Route::get('/shelves/{slug}/permissions', [BookshelfController::class, 'showPermissions']);
-    Route::put('/shelves/{slug}/permissions', [BookshelfController::class, 'permissions']);
-    Route::post('/shelves/{slug}/copy-permissions', [BookshelfController::class, 'copyPermissions']);
+    Route::get('/shelves/{slug}/permissions', [PermissionsController::class, 'showForShelf']);
+    Route::put('/shelves/{slug}/permissions', [PermissionsController::class, 'updateForShelf']);
+    Route::post('/shelves/{slug}/copy-permissions', [PermissionsController::class, 'copyShelfPermissionsToBooks']);
     Route::get('/shelves/{slug}/references', [ReferenceController::class, 'shelf']);
 
     // Book Creation
@@ -79,8 +80,8 @@ Route::middleware('auth')->group(function () {
     Route::delete('/books/{id}', [BookController::class, 'destroy']);
     Route::get('/books/{slug}/sort-item', [BookSortController::class, 'showItem']);
     Route::get('/books/{slug}', [BookController::class, 'show']);
-    Route::get('/books/{bookSlug}/permissions', [BookController::class, 'showPermissions']);
-    Route::put('/books/{bookSlug}/permissions', [BookController::class, 'permissions']);
+    Route::get('/books/{bookSlug}/permissions', [PermissionsController::class, 'showForBook']);
+    Route::put('/books/{bookSlug}/permissions', [PermissionsController::class, 'updateForBook']);
     Route::get('/books/{slug}/delete', [BookController::class, 'showDelete']);
     Route::get('/books/{bookSlug}/copy', [BookController::class, 'showCopy']);
     Route::post('/books/{bookSlug}/copy', [BookController::class, 'copy']);
@@ -111,8 +112,8 @@ Route::middleware('auth')->group(function () {
     Route::post('/books/{bookSlug}/page/{pageSlug}/copy', [PageController::class, 'copy']);
     Route::get('/books/{bookSlug}/page/{pageSlug}/delete', [PageController::class, 'showDelete']);
     Route::get('/books/{bookSlug}/draft/{pageId}/delete', [PageController::class, 'showDeleteDraft']);
-    Route::get('/books/{bookSlug}/page/{pageSlug}/permissions', [PageController::class, 'showPermissions']);
-    Route::put('/books/{bookSlug}/page/{pageSlug}/permissions', [PageController::class, 'permissions']);
+    Route::get('/books/{bookSlug}/page/{pageSlug}/permissions', [PermissionsController::class, 'showForPage']);
+    Route::put('/books/{bookSlug}/page/{pageSlug}/permissions', [PermissionsController::class, 'updateForPage']);
     Route::get('/books/{bookSlug}/page/{pageSlug}/references', [ReferenceController::class, 'page']);
     Route::put('/books/{bookSlug}/page/{pageSlug}', [PageController::class, 'update']);
     Route::delete('/books/{bookSlug}/page/{pageSlug}', [PageController::class, 'destroy']);
@@ -138,12 +139,12 @@ Route::middleware('auth')->group(function () {
     Route::post('/books/{bookSlug}/chapter/{chapterSlug}/copy', [ChapterController::class, 'copy']);
     Route::get('/books/{bookSlug}/chapter/{chapterSlug}/edit', [ChapterController::class, 'edit']);
     Route::post('/books/{bookSlug}/chapter/{chapterSlug}/convert-to-book', [ChapterController::class, 'convertToBook']);
-    Route::get('/books/{bookSlug}/chapter/{chapterSlug}/permissions', [ChapterController::class, 'showPermissions']);
+    Route::get('/books/{bookSlug}/chapter/{chapterSlug}/permissions', [PermissionsController::class, 'showForPage']);
     Route::get('/books/{bookSlug}/chapter/{chapterSlug}/export/pdf', [ChapterExportController::class, 'pdf']);
     Route::get('/books/{bookSlug}/chapter/{chapterSlug}/export/html', [ChapterExportController::class, 'html']);
     Route::get('/books/{bookSlug}/chapter/{chapterSlug}/export/markdown', [ChapterExportController::class, 'markdown']);
     Route::get('/books/{bookSlug}/chapter/{chapterSlug}/export/plaintext', [ChapterExportController::class, 'plainText']);
-    Route::put('/books/{bookSlug}/chapter/{chapterSlug}/permissions', [ChapterController::class, 'permissions']);
+    Route::put('/books/{bookSlug}/chapter/{chapterSlug}/permissions', [PermissionsController::class, 'updateForPage']);
     Route::get('/books/{bookSlug}/chapter/{chapterSlug}/references', [ReferenceController::class, 'chapter']);
     Route::get('/books/{bookSlug}/chapter/{chapterSlug}/delete', [ChapterController::class, 'showDelete']);
     Route::delete('/books/{bookSlug}/chapter/{chapterSlug}', [ChapterController::class, 'destroy']);