3 class RestrictionsTest extends TestCase
8 public function setUp()
11 $this->user = $this->getNewUser();
12 $this->viewer = $this->getViewer();
15 protected function getViewer()
17 $role = \BookStack\Role::getRole('viewer');
18 $viewer = $this->getNewBlankUser();
19 $viewer->attachRole($role);;
24 * Manually set some restrictions on an entity.
25 * @param \BookStack\Entity $entity
28 protected function setEntityRestrictions(\BookStack\Entity $entity, $actions)
30 $entity->restricted = true;
31 $entity->restrictions()->delete();
32 $role = $this->user->roles->first();
33 $viewerRole = $this->viewer->roles->first();
34 foreach ($actions as $action) {
35 $entity->restrictions()->create([
36 'role_id' => $role->id,
37 'action' => strtolower($action)
39 $entity->restrictions()->create([
40 'role_id' => $viewerRole->id,
41 'action' => strtolower($action)
45 $entity->load('restrictions');
48 public function test_book_view_restriction()
50 $book = \BookStack\Book::first();
51 $bookPage = $book->pages->first();
52 $bookChapter = $book->chapters->first();
54 $bookUrl = $book->getUrl();
55 $this->actingAs($this->user)
57 ->seePageIs($bookUrl);
59 $this->setEntityRestrictions($book, []);
61 $this->forceVisit($bookUrl)
62 ->see('Book not found');
63 $this->forceVisit($bookPage->getUrl())
64 ->see('Book not found');
65 $this->forceVisit($bookChapter->getUrl())
66 ->see('Book not found');
68 $this->setEntityRestrictions($book, ['view']);
70 $this->visit($bookUrl)
72 $this->visit($bookPage->getUrl())
73 ->see($bookPage->name);
74 $this->visit($bookChapter->getUrl())
75 ->see($bookChapter->name);
78 public function test_book_create_restriction()
80 $book = \BookStack\Book::first();
82 $bookUrl = $book->getUrl();
83 $this->actingAs($this->viewer)
85 ->dontSeeInElement('.action-buttons', 'New Page')
86 ->dontSeeInElement('.action-buttons', 'New Chapter');
87 $this->actingAs($this->user)
89 ->seeInElement('.action-buttons', 'New Page')
90 ->seeInElement('.action-buttons', 'New Chapter');
92 $this->setEntityRestrictions($book, ['view', 'delete', 'update']);
94 $this->forceVisit($bookUrl . '/chapter/create')
95 ->see('You do not have permission')->seePageIs('/');
96 $this->forceVisit($bookUrl . '/page/create')
97 ->see('You do not have permission')->seePageIs('/');
98 $this->visit($bookUrl)->dontSeeInElement('.action-buttons', 'New Page')
99 ->dontSeeInElement('.action-buttons', 'New Chapter');
101 $this->setEntityRestrictions($book, ['view', 'create']);
103 $this->visit($bookUrl . '/chapter/create')
104 ->type('test chapter', 'name')
105 ->type('test description for chapter', 'description')
106 ->press('Save Chapter')
107 ->seePageIs($bookUrl . '/chapter/test-chapter');
108 $this->visit($bookUrl . '/page/create')
109 ->type('test page', 'name')
110 ->type('test content', 'html')
112 ->seePageIs($bookUrl . '/page/test-page');
113 $this->visit($bookUrl)->seeInElement('.action-buttons', 'New Page')
114 ->seeInElement('.action-buttons', 'New Chapter');
117 public function test_book_update_restriction()
119 $book = \BookStack\Book::first();
120 $bookPage = $book->pages->first();
121 $bookChapter = $book->chapters->first();
123 $bookUrl = $book->getUrl();
124 $this->actingAs($this->user)
125 ->visit($bookUrl . '/edit')
128 $this->setEntityRestrictions($book, ['view', 'delete']);
130 $this->forceVisit($bookUrl . '/edit')
131 ->see('You do not have permission')->seePageIs('/');
132 $this->forceVisit($bookPage->getUrl() . '/edit')
133 ->see('You do not have permission')->seePageIs('/');
134 $this->forceVisit($bookChapter->getUrl() . '/edit')
135 ->see('You do not have permission')->seePageIs('/');
137 $this->setEntityRestrictions($book, ['view', 'update']);
139 $this->visit($bookUrl . '/edit')
140 ->seePageIs($bookUrl . '/edit');
141 $this->visit($bookPage->getUrl() . '/edit')
142 ->seePageIs($bookPage->getUrl() . '/edit');
143 $this->visit($bookChapter->getUrl() . '/edit')
144 ->see('Edit Chapter');
147 public function test_book_delete_restriction()
149 $book = \BookStack\Book::first();
150 $bookPage = $book->pages->first();
151 $bookChapter = $book->chapters->first();
153 $bookUrl = $book->getUrl();
154 $this->actingAs($this->user)
155 ->visit($bookUrl . '/delete')
156 ->see('Delete Book');
158 $this->setEntityRestrictions($book, ['view', 'update']);
160 $this->forceVisit($bookUrl . '/delete')
161 ->see('You do not have permission')->seePageIs('/');
162 $this->forceVisit($bookPage->getUrl() . '/delete')
163 ->see('You do not have permission')->seePageIs('/');
164 $this->forceVisit($bookChapter->getUrl() . '/delete')
165 ->see('You do not have permission')->seePageIs('/');
167 $this->setEntityRestrictions($book, ['view', 'delete']);
169 $this->visit($bookUrl . '/delete')
170 ->seePageIs($bookUrl . '/delete')->see('Delete Book');
171 $this->visit($bookPage->getUrl() . '/delete')
172 ->seePageIs($bookPage->getUrl() . '/delete')->see('Delete Page');
173 $this->visit($bookChapter->getUrl() . '/delete')
174 ->see('Delete Chapter');
177 public function test_chapter_view_restriction()
179 $chapter = \BookStack\Chapter::first();
180 $chapterPage = $chapter->pages->first();
182 $chapterUrl = $chapter->getUrl();
183 $this->actingAs($this->user)
185 ->seePageIs($chapterUrl);
187 $this->setEntityRestrictions($chapter, []);
189 $this->forceVisit($chapterUrl)
190 ->see('Chapter not found');
191 $this->forceVisit($chapterPage->getUrl())
192 ->see('Page not found');
194 $this->setEntityRestrictions($chapter, ['view']);
196 $this->visit($chapterUrl)
197 ->see($chapter->name);
198 $this->visit($chapterPage->getUrl())
199 ->see($chapterPage->name);
202 public function test_chapter_create_restriction()
204 $chapter = \BookStack\Chapter::first();
206 $chapterUrl = $chapter->getUrl();
207 $this->actingAs($this->user)
209 ->seeInElement('.action-buttons', 'New Page');
211 $this->setEntityRestrictions($chapter, ['view', 'delete', 'update']);
213 $this->forceVisit($chapterUrl . '/create-page')
214 ->see('You do not have permission')->seePageIs('/');
215 $this->visit($chapterUrl)->dontSeeInElement('.action-buttons', 'New Page');
217 $this->setEntityRestrictions($chapter, ['view', 'create']);
220 $this->visit($chapterUrl . '/create-page')
221 ->type('test page', 'name')
222 ->type('test content', 'html')
224 ->seePageIs($chapter->book->getUrl() . '/page/test-page');
225 $this->visit($chapterUrl)->seeInElement('.action-buttons', 'New Page');
228 public function test_chapter_update_restriction()
230 $chapter = \BookStack\Chapter::first();
231 $chapterPage = $chapter->pages->first();
233 $chapterUrl = $chapter->getUrl();
234 $this->actingAs($this->user)
235 ->visit($chapterUrl . '/edit')
236 ->see('Edit Chapter');
238 $this->setEntityRestrictions($chapter, ['view', 'delete']);
240 $this->forceVisit($chapterUrl . '/edit')
241 ->see('You do not have permission')->seePageIs('/');
242 $this->forceVisit($chapterPage->getUrl() . '/edit')
243 ->see('You do not have permission')->seePageIs('/');
245 $this->setEntityRestrictions($chapter, ['view', 'update']);
247 $this->visit($chapterUrl . '/edit')
248 ->seePageIs($chapterUrl . '/edit')->see('Edit Chapter');
249 $this->visit($chapterPage->getUrl() . '/edit')
250 ->seePageIs($chapterPage->getUrl() . '/edit');
253 public function test_chapter_delete_restriction()
255 $chapter = \BookStack\Chapter::first();
256 $chapterPage = $chapter->pages->first();
258 $chapterUrl = $chapter->getUrl();
259 $this->actingAs($this->user)
260 ->visit($chapterUrl . '/delete')
261 ->see('Delete Chapter');
263 $this->setEntityRestrictions($chapter, ['view', 'update']);
265 $this->forceVisit($chapterUrl . '/delete')
266 ->see('You do not have permission')->seePageIs('/');
267 $this->forceVisit($chapterPage->getUrl() . '/delete')
268 ->see('You do not have permission')->seePageIs('/');
270 $this->setEntityRestrictions($chapter, ['view', 'delete']);
272 $this->visit($chapterUrl . '/delete')
273 ->seePageIs($chapterUrl . '/delete')->see('Delete Chapter');
274 $this->visit($chapterPage->getUrl() . '/delete')
275 ->seePageIs($chapterPage->getUrl() . '/delete')->see('Delete Page');
278 public function test_page_view_restriction()
280 $page = \BookStack\Page::first();
282 $pageUrl = $page->getUrl();
283 $this->actingAs($this->user)
285 ->seePageIs($pageUrl);
287 $this->setEntityRestrictions($page, ['update', 'delete']);
289 $this->forceVisit($pageUrl)
290 ->see('Page not found');
292 $this->setEntityRestrictions($page, ['view']);
294 $this->visit($pageUrl)
298 public function test_page_update_restriction()
300 $page = \BookStack\Chapter::first();
302 $pageUrl = $page->getUrl();
303 $this->actingAs($this->user)
304 ->visit($pageUrl . '/edit')
305 ->seeInField('name', $page->name);
307 $this->setEntityRestrictions($page, ['view', 'delete']);
309 $this->forceVisit($pageUrl . '/edit')
310 ->see('You do not have permission')->seePageIs('/');
312 $this->setEntityRestrictions($page, ['view', 'update']);
314 $this->visit($pageUrl . '/edit')
315 ->seePageIs($pageUrl . '/edit')->seeInField('name', $page->name);
318 public function test_page_delete_restriction()
320 $page = \BookStack\Page::first();
322 $pageUrl = $page->getUrl();
323 $this->actingAs($this->user)
324 ->visit($pageUrl . '/delete')
325 ->see('Delete Page');
327 $this->setEntityRestrictions($page, ['view', 'update']);
329 $this->forceVisit($pageUrl . '/delete')
330 ->see('You do not have permission')->seePageIs('/');
332 $this->setEntityRestrictions($page, ['view', 'delete']);
334 $this->visit($pageUrl . '/delete')
335 ->seePageIs($pageUrl . '/delete')->see('Delete Page');
338 public function test_book_restriction_form()
340 $book = \BookStack\Book::first();
341 $this->asAdmin()->visit($book->getUrl() . '/permissions')
342 ->see('Book Permissions')
343 ->check('restricted')
344 ->check('restrictions[2][view]')
345 ->press('Save Permissions')
346 ->seeInDatabase('books', ['id' => $book->id, 'restricted' => true])
347 ->seeInDatabase('restrictions', [
348 'restrictable_id' => $book->id,
349 'restrictable_type' => 'BookStack\Book',
355 public function test_chapter_restriction_form()
357 $chapter = \BookStack\Chapter::first();
358 $this->asAdmin()->visit($chapter->getUrl() . '/permissions')
359 ->see('Chapter Permissions')
360 ->check('restricted')
361 ->check('restrictions[2][update]')
362 ->press('Save Permissions')
363 ->seeInDatabase('chapters', ['id' => $chapter->id, 'restricted' => true])
364 ->seeInDatabase('restrictions', [
365 'restrictable_id' => $chapter->id,
366 'restrictable_type' => 'BookStack\Chapter',
372 public function test_page_restriction_form()
374 $page = \BookStack\Page::first();
375 $this->asAdmin()->visit($page->getUrl() . '/permissions')
376 ->see('Page Permissions')
377 ->check('restricted')
378 ->check('restrictions[2][delete]')
379 ->press('Save Permissions')
380 ->seeInDatabase('pages', ['id' => $page->id, 'restricted' => true])
381 ->seeInDatabase('restrictions', [
382 'restrictable_id' => $page->id,
383 'restrictable_type' => 'BookStack\Page',
389 public function test_restricted_pages_not_visible_in_book_navigation_on_pages()
391 $chapter = \BookStack\Chapter::first();
392 $page = $chapter->pages->first();
393 $page2 = $chapter->pages[2];
395 $this->setEntityRestrictions($page, []);
397 $this->actingAs($this->user)
398 ->visit($page2->getUrl())
399 ->dontSeeInElement('.sidebar-page-list', $page->name);
402 public function test_restricted_pages_not_visible_in_book_navigation_on_chapters()
404 $chapter = \BookStack\Chapter::first();
405 $page = $chapter->pages->first();
407 $this->setEntityRestrictions($page, []);
409 $this->actingAs($this->user)
410 ->visit($chapter->getUrl())
411 ->dontSeeInElement('.sidebar-page-list', $page->name);
414 public function test_restricted_pages_not_visible_on_chapter_pages()
416 $chapter = \BookStack\Chapter::first();
417 $page = $chapter->pages->first();
419 $this->setEntityRestrictions($page, []);
421 $this->actingAs($this->user)
422 ->visit($chapter->getUrl())
423 ->dontSee($page->name);
426 public function test_book_create_restriction_override()
428 $book = \BookStack\Book::first();
430 $bookUrl = $book->getUrl();
431 $this->actingAs($this->viewer)
433 ->dontSeeInElement('.action-buttons', 'New Page')
434 ->dontSeeInElement('.action-buttons', 'New Chapter');
436 $this->setEntityRestrictions($book, ['view', 'delete', 'update']);
438 $this->forceVisit($bookUrl . '/chapter/create')
439 ->see('You do not have permission')->seePageIs('/');
440 $this->forceVisit($bookUrl . '/page/create')
441 ->see('You do not have permission')->seePageIs('/');
442 $this->visit($bookUrl)->dontSeeInElement('.action-buttons', 'New Page')
443 ->dontSeeInElement('.action-buttons', 'New Chapter');
445 $this->setEntityRestrictions($book, ['view', 'create']);
447 $this->visit($bookUrl . '/chapter/create')
448 ->type('test chapter', 'name')
449 ->type('test description for chapter', 'description')
450 ->press('Save Chapter')
451 ->seePageIs($bookUrl . '/chapter/test-chapter');
452 $this->visit($bookUrl . '/page/create')
453 ->type('test page', 'name')
454 ->type('test content', 'html')
456 ->seePageIs($bookUrl . '/page/test-page');
457 $this->visit($bookUrl)->seeInElement('.action-buttons', 'New Page')
458 ->seeInElement('.action-buttons', 'New Chapter');
461 public function test_book_update_restriction_override()
463 $book = \BookStack\Book::first();
464 $bookPage = $book->pages->first();
465 $bookChapter = $book->chapters->first();
467 $bookUrl = $book->getUrl();
468 $this->actingAs($this->viewer)
469 ->visit($bookUrl . '/edit')
470 ->dontSee('Edit Book');
472 $this->setEntityRestrictions($book, ['view', 'delete']);
474 $this->forceVisit($bookUrl . '/edit')
475 ->see('You do not have permission')->seePageIs('/');
476 $this->forceVisit($bookPage->getUrl() . '/edit')
477 ->see('You do not have permission')->seePageIs('/');
478 $this->forceVisit($bookChapter->getUrl() . '/edit')
479 ->see('You do not have permission')->seePageIs('/');
481 $this->setEntityRestrictions($book, ['view', 'update']);
483 $this->visit($bookUrl . '/edit')
484 ->seePageIs($bookUrl . '/edit');
485 $this->visit($bookPage->getUrl() . '/edit')
486 ->seePageIs($bookPage->getUrl() . '/edit');
487 $this->visit($bookChapter->getUrl() . '/edit')
488 ->see('Edit Chapter');
491 public function test_book_delete_restriction_override()
493 $book = \BookStack\Book::first();
494 $bookPage = $book->pages->first();
495 $bookChapter = $book->chapters->first();
497 $bookUrl = $book->getUrl();
498 $this->actingAs($this->viewer)
499 ->visit($bookUrl . '/delete')
500 ->dontSee('Delete Book');
502 $this->setEntityRestrictions($book, ['view', 'update']);
504 $this->forceVisit($bookUrl . '/delete')
505 ->see('You do not have permission')->seePageIs('/');
506 $this->forceVisit($bookPage->getUrl() . '/delete')
507 ->see('You do not have permission')->seePageIs('/');
508 $this->forceVisit($bookChapter->getUrl() . '/delete')
509 ->see('You do not have permission')->seePageIs('/');
511 $this->setEntityRestrictions($book, ['view', 'delete']);
513 $this->visit($bookUrl . '/delete')
514 ->seePageIs($bookUrl . '/delete')->see('Delete Book');
515 $this->visit($bookPage->getUrl() . '/delete')
516 ->seePageIs($bookPage->getUrl() . '/delete')->see('Delete Page');
517 $this->visit($bookChapter->getUrl() . '/delete')
518 ->see('Delete Chapter');