]> BookStack Code Mirror - bookstack/blob - app/Permissions/PermissionsController.php
Perms: Added transactions around permission effecting actions
[bookstack] / app / Permissions / PermissionsController.php
1 <?php
2
3 namespace BookStack\Permissions;
4
5 use BookStack\Entities\Queries\EntityQueries;
6 use BookStack\Entities\Tools\PermissionsUpdater;
7 use BookStack\Http\Controller;
8 use BookStack\Permissions\Models\EntityPermission;
9 use BookStack\Users\Models\Role;
10 use BookStack\Util\DatabaseTransaction;
11 use Illuminate\Http\Request;
12
13 class PermissionsController extends Controller
14 {
15     public function __construct(
16         protected PermissionsUpdater $permissionsUpdater,
17         protected EntityQueries $queries,
18     ) {
19     }
20
21     /**
22      * Show the permissions view for a page.
23      */
24     public function showForPage(string $bookSlug, string $pageSlug)
25     {
26         $page = $this->queries->pages->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
27         $this->checkOwnablePermission('restrictions-manage', $page);
28
29         $this->setPageTitle(trans('entities.pages_permissions'));
30         return view('pages.permissions', [
31             'page' => $page,
32             'data' => new PermissionFormData($page),
33         ]);
34     }
35
36     /**
37      * Set the permissions for a page.
38      */
39     public function updateForPage(Request $request, string $bookSlug, string $pageSlug)
40     {
41         $page = $this->queries->pages->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
42         $this->checkOwnablePermission('restrictions-manage', $page);
43
44         (new DatabaseTransaction(function () use ($page, $request) {
45             $this->permissionsUpdater->updateFromPermissionsForm($page, $request);
46         }))->run();
47
48         $this->showSuccessNotification(trans('entities.pages_permissions_success'));
49
50         return redirect($page->getUrl());
51     }
52
53     /**
54      * Show the permissions view for a chapter.
55      */
56     public function showForChapter(string $bookSlug, string $chapterSlug)
57     {
58         $chapter = $this->queries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
59         $this->checkOwnablePermission('restrictions-manage', $chapter);
60
61         $this->setPageTitle(trans('entities.chapters_permissions'));
62         return view('chapters.permissions', [
63             'chapter' => $chapter,
64             'data' => new PermissionFormData($chapter),
65         ]);
66     }
67
68     /**
69      * Set the permissions for a chapter.
70      */
71     public function updateForChapter(Request $request, string $bookSlug, string $chapterSlug)
72     {
73         $chapter = $this->queries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
74         $this->checkOwnablePermission('restrictions-manage', $chapter);
75
76         (new DatabaseTransaction(function () use ($chapter, $request) {
77             $this->permissionsUpdater->updateFromPermissionsForm($chapter, $request);
78         }))->run();
79
80         $this->showSuccessNotification(trans('entities.chapters_permissions_success'));
81
82         return redirect($chapter->getUrl());
83     }
84
85     /**
86      * Show the permissions view for a book.
87      */
88     public function showForBook(string $slug)
89     {
90         $book = $this->queries->books->findVisibleBySlugOrFail($slug);
91         $this->checkOwnablePermission('restrictions-manage', $book);
92
93         $this->setPageTitle(trans('entities.books_permissions'));
94         return view('books.permissions', [
95             'book' => $book,
96             'data' => new PermissionFormData($book),
97         ]);
98     }
99
100     /**
101      * Set the permissions for a book.
102      */
103     public function updateForBook(Request $request, string $slug)
104     {
105         $book = $this->queries->books->findVisibleBySlugOrFail($slug);
106         $this->checkOwnablePermission('restrictions-manage', $book);
107
108         (new DatabaseTransaction(function () use ($book, $request) {
109             $this->permissionsUpdater->updateFromPermissionsForm($book, $request);
110         }))->run();
111
112         $this->showSuccessNotification(trans('entities.books_permissions_updated'));
113
114         return redirect($book->getUrl());
115     }
116
117     /**
118      * Show the permissions view for a shelf.
119      */
120     public function showForShelf(string $slug)
121     {
122         $shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
123         $this->checkOwnablePermission('restrictions-manage', $shelf);
124
125         $this->setPageTitle(trans('entities.shelves_permissions'));
126         return view('shelves.permissions', [
127             'shelf' => $shelf,
128             'data' => new PermissionFormData($shelf),
129         ]);
130     }
131
132     /**
133      * Set the permissions for a shelf.
134      */
135     public function updateForShelf(Request $request, string $slug)
136     {
137         $shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
138         $this->checkOwnablePermission('restrictions-manage', $shelf);
139
140         (new DatabaseTransaction(function () use ($shelf, $request) {
141             $this->permissionsUpdater->updateFromPermissionsForm($shelf, $request);
142         }))->run();
143
144         $this->showSuccessNotification(trans('entities.shelves_permissions_updated'));
145
146         return redirect($shelf->getUrl());
147     }
148
149     /**
150      * Copy the permissions of a bookshelf to the child books.
151      */
152     public function copyShelfPermissionsToBooks(string $slug)
153     {
154         $shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
155         $this->checkOwnablePermission('restrictions-manage', $shelf);
156
157         $updateCount = (new DatabaseTransaction(function () use ($shelf) {
158             return $this->permissionsUpdater->updateBookPermissionsFromShelf($shelf);
159         }))->run();
160
161         $this->showSuccessNotification(trans('entities.shelves_copy_permission_success', ['count' => $updateCount]));
162
163         return redirect($shelf->getUrl());
164     }
165
166     /**
167      * Get an empty entity permissions form row for the given role.
168      */
169     public function formRowForRole(string $entityType, string $roleId)
170     {
171         $this->checkPermissionOr('restrictions-manage-all', fn() => userCan('restrictions-manage-own'));
172
173         $role = Role::query()->findOrFail($roleId);
174
175         return view('form.entity-permissions-row', [
176             'role' => $role,
177             'permission' => new EntityPermission(),
178             'entityType' => $entityType,
179             'inheriting' => false,
180         ]);
181     }
182 }