3 class RestrictionsTest extends BrowserKitTest
7 protected $restrictionService;
9 public function setUp()
12 $this->user = $this->getEditor();
13 $this->viewer = $this->getViewer();
14 $this->restrictionService = $this->app[\BookStack\Services\PermissionService::class];
17 protected function getViewer()
19 $role = \BookStack\Role::getRole('viewer');
20 $viewer = $this->getNewBlankUser();
21 $viewer->attachRole($role);;
26 * Manually set some permissions on an entity.
27 * @param \BookStack\Entity $entity
30 protected function setEntityRestrictions(\BookStack\Entity $entity, $actions)
32 $entity->restricted = true;
33 $entity->permissions()->delete();
34 $role = $this->user->roles->first();
35 $viewerRole = $this->viewer->roles->first();
36 foreach ($actions as $action) {
37 $entity->permissions()->create([
38 'role_id' => $role->id,
39 'action' => strtolower($action)
41 $entity->permissions()->create([
42 'role_id' => $viewerRole->id,
43 'action' => strtolower($action)
47 $entity->load('permissions');
48 $this->restrictionService->buildJointPermissionsForEntity($entity);
49 $entity->load('jointPermissions');
52 public function test_book_view_restriction()
54 $book = \BookStack\Book::first();
55 $bookPage = $book->pages->first();
56 $bookChapter = $book->chapters->first();
58 $bookUrl = $book->getUrl();
59 $this->actingAs($this->user)
61 ->seePageIs($bookUrl);
63 $this->setEntityRestrictions($book, []);
65 $this->forceVisit($bookUrl)
66 ->see('Book not found');
67 $this->forceVisit($bookPage->getUrl())
68 ->see('Page not found');
69 $this->forceVisit($bookChapter->getUrl())
70 ->see('Chapter not found');
72 $this->setEntityRestrictions($book, ['view']);
74 $this->visit($bookUrl)
76 $this->visit($bookPage->getUrl())
77 ->see($bookPage->name);
78 $this->visit($bookChapter->getUrl())
79 ->see($bookChapter->name);
82 public function test_book_create_restriction()
84 $book = \BookStack\Book::first();
86 $bookUrl = $book->getUrl();
87 $this->actingAs($this->viewer)
89 ->dontSeeInElement('.action-buttons', 'New Page')
90 ->dontSeeInElement('.action-buttons', 'New Chapter');
91 $this->actingAs($this->user)
93 ->seeInElement('.action-buttons', 'New Page')
94 ->seeInElement('.action-buttons', 'New Chapter');
96 $this->setEntityRestrictions($book, ['view', 'delete', 'update']);
98 $this->forceVisit($bookUrl . '/chapter/create')
99 ->see('You do not have permission')->seePageIs('/');
100 $this->forceVisit($bookUrl . '/page/create')
101 ->see('You do not have permission')->seePageIs('/');
102 $this->visit($bookUrl)->dontSeeInElement('.action-buttons', 'New Page')
103 ->dontSeeInElement('.action-buttons', 'New Chapter');
105 $this->setEntityRestrictions($book, ['view', 'create']);
107 $this->visit($bookUrl . '/chapter/create')
108 ->type('test chapter', 'name')
109 ->type('test description for chapter', 'description')
110 ->press('Save Chapter')
111 ->seePageIs($bookUrl . '/chapter/test-chapter');
112 $this->visit($bookUrl . '/page/create')
113 ->type('test page', 'name')
114 ->type('test content', 'html')
116 ->seePageIs($bookUrl . '/page/test-page');
117 $this->visit($bookUrl)->seeInElement('.action-buttons', 'New Page')
118 ->seeInElement('.action-buttons', 'New Chapter');
121 public function test_book_update_restriction()
123 $book = \BookStack\Book::first();
124 $bookPage = $book->pages->first();
125 $bookChapter = $book->chapters->first();
127 $bookUrl = $book->getUrl();
128 $this->actingAs($this->user)
129 ->visit($bookUrl . '/edit')
132 $this->setEntityRestrictions($book, ['view', 'delete']);
134 $this->forceVisit($bookUrl . '/edit')
135 ->see('You do not have permission')->seePageIs('/');
136 $this->forceVisit($bookPage->getUrl() . '/edit')
137 ->see('You do not have permission')->seePageIs('/');
138 $this->forceVisit($bookChapter->getUrl() . '/edit')
139 ->see('You do not have permission')->seePageIs('/');
141 $this->setEntityRestrictions($book, ['view', 'update']);
143 $this->visit($bookUrl . '/edit')
144 ->seePageIs($bookUrl . '/edit');
145 $this->visit($bookPage->getUrl() . '/edit')
146 ->seePageIs($bookPage->getUrl() . '/edit');
147 $this->visit($bookChapter->getUrl() . '/edit')
148 ->see('Edit Chapter');
151 public function test_book_delete_restriction()
153 $book = \BookStack\Book::first();
154 $bookPage = $book->pages->first();
155 $bookChapter = $book->chapters->first();
157 $bookUrl = $book->getUrl();
158 $this->actingAs($this->user)
159 ->visit($bookUrl . '/delete')
160 ->see('Delete Book');
162 $this->setEntityRestrictions($book, ['view', 'update']);
164 $this->forceVisit($bookUrl . '/delete')
165 ->see('You do not have permission')->seePageIs('/');
166 $this->forceVisit($bookPage->getUrl() . '/delete')
167 ->see('You do not have permission')->seePageIs('/');
168 $this->forceVisit($bookChapter->getUrl() . '/delete')
169 ->see('You do not have permission')->seePageIs('/');
171 $this->setEntityRestrictions($book, ['view', 'delete']);
173 $this->visit($bookUrl . '/delete')
174 ->seePageIs($bookUrl . '/delete')->see('Delete Book');
175 $this->visit($bookPage->getUrl() . '/delete')
176 ->seePageIs($bookPage->getUrl() . '/delete')->see('Delete Page');
177 $this->visit($bookChapter->getUrl() . '/delete')
178 ->see('Delete Chapter');
181 public function test_chapter_view_restriction()
183 $chapter = \BookStack\Chapter::first();
184 $chapterPage = $chapter->pages->first();
186 $chapterUrl = $chapter->getUrl();
187 $this->actingAs($this->user)
189 ->seePageIs($chapterUrl);
191 $this->setEntityRestrictions($chapter, []);
193 $this->forceVisit($chapterUrl)
194 ->see('Chapter not found');
195 $this->forceVisit($chapterPage->getUrl())
196 ->see('Page not found');
198 $this->setEntityRestrictions($chapter, ['view']);
200 $this->visit($chapterUrl)
201 ->see($chapter->name);
202 $this->visit($chapterPage->getUrl())
203 ->see($chapterPage->name);
206 public function test_chapter_create_restriction()
208 $chapter = \BookStack\Chapter::first();
210 $chapterUrl = $chapter->getUrl();
211 $this->actingAs($this->user)
213 ->seeInElement('.action-buttons', 'New Page');
215 $this->setEntityRestrictions($chapter, ['view', 'delete', 'update']);
217 $this->forceVisit($chapterUrl . '/create-page')
218 ->see('You do not have permission')->seePageIs('/');
219 $this->visit($chapterUrl)->dontSeeInElement('.action-buttons', 'New Page');
221 $this->setEntityRestrictions($chapter, ['view', 'create']);
224 $this->visit($chapterUrl . '/create-page')
225 ->type('test page', 'name')
226 ->type('test content', 'html')
228 ->seePageIs($chapter->book->getUrl() . '/page/test-page');
229 $this->visit($chapterUrl)->seeInElement('.action-buttons', 'New Page');
232 public function test_chapter_update_restriction()
234 $chapter = \BookStack\Chapter::first();
235 $chapterPage = $chapter->pages->first();
237 $chapterUrl = $chapter->getUrl();
238 $this->actingAs($this->user)
239 ->visit($chapterUrl . '/edit')
240 ->see('Edit Chapter');
242 $this->setEntityRestrictions($chapter, ['view', 'delete']);
244 $this->forceVisit($chapterUrl . '/edit')
245 ->see('You do not have permission')->seePageIs('/');
246 $this->forceVisit($chapterPage->getUrl() . '/edit')
247 ->see('You do not have permission')->seePageIs('/');
249 $this->setEntityRestrictions($chapter, ['view', 'update']);
251 $this->visit($chapterUrl . '/edit')
252 ->seePageIs($chapterUrl . '/edit')->see('Edit Chapter');
253 $this->visit($chapterPage->getUrl() . '/edit')
254 ->seePageIs($chapterPage->getUrl() . '/edit');
257 public function test_chapter_delete_restriction()
259 $chapter = \BookStack\Chapter::first();
260 $chapterPage = $chapter->pages->first();
262 $chapterUrl = $chapter->getUrl();
263 $this->actingAs($this->user)
264 ->visit($chapterUrl . '/delete')
265 ->see('Delete Chapter');
267 $this->setEntityRestrictions($chapter, ['view', 'update']);
269 $this->forceVisit($chapterUrl . '/delete')
270 ->see('You do not have permission')->seePageIs('/');
271 $this->forceVisit($chapterPage->getUrl() . '/delete')
272 ->see('You do not have permission')->seePageIs('/');
274 $this->setEntityRestrictions($chapter, ['view', 'delete']);
276 $this->visit($chapterUrl . '/delete')
277 ->seePageIs($chapterUrl . '/delete')->see('Delete Chapter');
278 $this->visit($chapterPage->getUrl() . '/delete')
279 ->seePageIs($chapterPage->getUrl() . '/delete')->see('Delete Page');
282 public function test_page_view_restriction()
284 $page = \BookStack\Page::first();
286 $pageUrl = $page->getUrl();
287 $this->actingAs($this->user)
289 ->seePageIs($pageUrl);
291 $this->setEntityRestrictions($page, ['update', 'delete']);
293 $this->forceVisit($pageUrl)
294 ->see('Page not found');
296 $this->setEntityRestrictions($page, ['view']);
298 $this->visit($pageUrl)
302 public function test_page_update_restriction()
304 $page = \BookStack\Chapter::first();
306 $pageUrl = $page->getUrl();
307 $this->actingAs($this->user)
308 ->visit($pageUrl . '/edit')
309 ->seeInField('name', $page->name);
311 $this->setEntityRestrictions($page, ['view', 'delete']);
313 $this->forceVisit($pageUrl . '/edit')
314 ->see('You do not have permission')->seePageIs('/');
316 $this->setEntityRestrictions($page, ['view', 'update']);
318 $this->visit($pageUrl . '/edit')
319 ->seePageIs($pageUrl . '/edit')->seeInField('name', $page->name);
322 public function test_page_delete_restriction()
324 $page = \BookStack\Page::first();
326 $pageUrl = $page->getUrl();
327 $this->actingAs($this->user)
328 ->visit($pageUrl . '/delete')
329 ->see('Delete Page');
331 $this->setEntityRestrictions($page, ['view', 'update']);
333 $this->forceVisit($pageUrl . '/delete')
334 ->see('You do not have permission')->seePageIs('/');
336 $this->setEntityRestrictions($page, ['view', 'delete']);
338 $this->visit($pageUrl . '/delete')
339 ->seePageIs($pageUrl . '/delete')->see('Delete Page');
342 public function test_book_restriction_form()
344 $book = \BookStack\Book::first();
345 $this->asAdmin()->visit($book->getUrl() . '/permissions')
346 ->see('Book Permissions')
347 ->check('restricted')
348 ->check('restrictions[2][view]')
349 ->press('Save Permissions')
350 ->seeInDatabase('books', ['id' => $book->id, 'restricted' => true])
351 ->seeInDatabase('entity_permissions', [
352 'restrictable_id' => $book->id,
353 'restrictable_type' => 'BookStack\Book',
359 public function test_chapter_restriction_form()
361 $chapter = \BookStack\Chapter::first();
362 $this->asAdmin()->visit($chapter->getUrl() . '/permissions')
363 ->see('Chapter Permissions')
364 ->check('restricted')
365 ->check('restrictions[2][update]')
366 ->press('Save Permissions')
367 ->seeInDatabase('chapters', ['id' => $chapter->id, 'restricted' => true])
368 ->seeInDatabase('entity_permissions', [
369 'restrictable_id' => $chapter->id,
370 'restrictable_type' => 'BookStack\Chapter',
376 public function test_page_restriction_form()
378 $page = \BookStack\Page::first();
379 $this->asAdmin()->visit($page->getUrl() . '/permissions')
380 ->see('Page Permissions')
381 ->check('restricted')
382 ->check('restrictions[2][delete]')
383 ->press('Save Permissions')
384 ->seeInDatabase('pages', ['id' => $page->id, 'restricted' => true])
385 ->seeInDatabase('entity_permissions', [
386 'restrictable_id' => $page->id,
387 'restrictable_type' => 'BookStack\Page',
393 public function test_restricted_pages_not_visible_in_book_navigation_on_pages()
395 $chapter = \BookStack\Chapter::first();
396 $page = $chapter->pages->first();
397 $page2 = $chapter->pages[2];
399 $this->setEntityRestrictions($page, []);
401 $this->actingAs($this->user)
402 ->visit($page2->getUrl())
403 ->dontSeeInElement('.sidebar-page-list', $page->name);
406 public function test_restricted_pages_not_visible_in_book_navigation_on_chapters()
408 $chapter = \BookStack\Chapter::first();
409 $page = $chapter->pages->first();
411 $this->setEntityRestrictions($page, []);
413 $this->actingAs($this->user)
414 ->visit($chapter->getUrl())
415 ->dontSeeInElement('.sidebar-page-list', $page->name);
418 public function test_restricted_pages_not_visible_on_chapter_pages()
420 $chapter = \BookStack\Chapter::first();
421 $page = $chapter->pages->first();
423 $this->setEntityRestrictions($page, []);
425 $this->actingAs($this->user)
426 ->visit($chapter->getUrl())
427 ->dontSee($page->name);
430 public function test_book_create_restriction_override()
432 $book = \BookStack\Book::first();
434 $bookUrl = $book->getUrl();
435 $this->actingAs($this->viewer)
437 ->dontSeeInElement('.action-buttons', 'New Page')
438 ->dontSeeInElement('.action-buttons', 'New Chapter');
440 $this->setEntityRestrictions($book, ['view', 'delete', 'update']);
442 $this->forceVisit($bookUrl . '/chapter/create')
443 ->see('You do not have permission')->seePageIs('/');
444 $this->forceVisit($bookUrl . '/page/create')
445 ->see('You do not have permission')->seePageIs('/');
446 $this->visit($bookUrl)->dontSeeInElement('.action-buttons', 'New Page')
447 ->dontSeeInElement('.action-buttons', 'New Chapter');
449 $this->setEntityRestrictions($book, ['view', 'create']);
451 $this->visit($bookUrl . '/chapter/create')
452 ->type('test chapter', 'name')
453 ->type('test description for chapter', 'description')
454 ->press('Save Chapter')
455 ->seePageIs($bookUrl . '/chapter/test-chapter');
456 $this->visit($bookUrl . '/page/create')
457 ->type('test page', 'name')
458 ->type('test content', 'html')
460 ->seePageIs($bookUrl . '/page/test-page');
461 $this->visit($bookUrl)->seeInElement('.action-buttons', 'New Page')
462 ->seeInElement('.action-buttons', 'New Chapter');
465 public function test_book_update_restriction_override()
467 $book = \BookStack\Book::first();
468 $bookPage = $book->pages->first();
469 $bookChapter = $book->chapters->first();
471 $bookUrl = $book->getUrl();
472 $this->actingAs($this->viewer)
473 ->visit($bookUrl . '/edit')
474 ->dontSee('Edit Book');
476 $this->setEntityRestrictions($book, ['view', 'delete']);
478 $this->forceVisit($bookUrl . '/edit')
479 ->see('You do not have permission')->seePageIs('/');
480 $this->forceVisit($bookPage->getUrl() . '/edit')
481 ->see('You do not have permission')->seePageIs('/');
482 $this->forceVisit($bookChapter->getUrl() . '/edit')
483 ->see('You do not have permission')->seePageIs('/');
485 $this->setEntityRestrictions($book, ['view', 'update']);
487 $this->visit($bookUrl . '/edit')
488 ->seePageIs($bookUrl . '/edit');
489 $this->visit($bookPage->getUrl() . '/edit')
490 ->seePageIs($bookPage->getUrl() . '/edit');
491 $this->visit($bookChapter->getUrl() . '/edit')
492 ->see('Edit Chapter');
495 public function test_book_delete_restriction_override()
497 $book = \BookStack\Book::first();
498 $bookPage = $book->pages->first();
499 $bookChapter = $book->chapters->first();
501 $bookUrl = $book->getUrl();
502 $this->actingAs($this->viewer)
503 ->visit($bookUrl . '/delete')
504 ->dontSee('Delete Book');
506 $this->setEntityRestrictions($book, ['view', 'update']);
508 $this->forceVisit($bookUrl . '/delete')
509 ->see('You do not have permission')->seePageIs('/');
510 $this->forceVisit($bookPage->getUrl() . '/delete')
511 ->see('You do not have permission')->seePageIs('/');
512 $this->forceVisit($bookChapter->getUrl() . '/delete')
513 ->see('You do not have permission')->seePageIs('/');
515 $this->setEntityRestrictions($book, ['view', 'delete']);
517 $this->visit($bookUrl . '/delete')
518 ->seePageIs($bookUrl . '/delete')->see('Delete Book');
519 $this->visit($bookPage->getUrl() . '/delete')
520 ->seePageIs($bookPage->getUrl() . '/delete')->see('Delete Page');
521 $this->visit($bookChapter->getUrl() . '/delete')
522 ->see('Delete Chapter');