Dan Brown

Updated entity restrictions to allow permissions, Not just restrict

Also changed wording from 'Restrictions' to 'Permissions' to keep things more familiar and to better reflect what they do.

Referenced in issue #89.
...@@ -19,8 +19,8 @@ Route::group(['middleware' => 'auth'], function () { ...@@ -19,8 +19,8 @@ Route::group(['middleware' => 'auth'], function () {
19 Route::delete('/{id}', 'BookController@destroy'); 19 Route::delete('/{id}', 'BookController@destroy');
20 Route::get('/{slug}/sort-item', 'BookController@getSortItem'); 20 Route::get('/{slug}/sort-item', 'BookController@getSortItem');
21 Route::get('/{slug}', 'BookController@show'); 21 Route::get('/{slug}', 'BookController@show');
22 - Route::get('/{bookSlug}/restrict', 'BookController@showRestrict'); 22 + Route::get('/{bookSlug}/permissions', 'BookController@showRestrict');
23 - Route::put('/{bookSlug}/restrict', 'BookController@restrict'); 23 + Route::put('/{bookSlug}/permissions', 'BookController@restrict');
24 Route::get('/{slug}/delete', 'BookController@showDelete'); 24 Route::get('/{slug}/delete', 'BookController@showDelete');
25 Route::get('/{bookSlug}/sort', 'BookController@sort'); 25 Route::get('/{bookSlug}/sort', 'BookController@sort');
26 Route::put('/{bookSlug}/sort', 'BookController@saveSort'); 26 Route::put('/{bookSlug}/sort', 'BookController@saveSort');
...@@ -36,8 +36,8 @@ Route::group(['middleware' => 'auth'], function () { ...@@ -36,8 +36,8 @@ Route::group(['middleware' => 'auth'], function () {
36 Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit'); 36 Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit');
37 Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete'); 37 Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete');
38 Route::get('/{bookSlug}/draft/{pageId}/delete', 'PageController@showDeleteDraft'); 38 Route::get('/{bookSlug}/draft/{pageId}/delete', 'PageController@showDeleteDraft');
39 - Route::get('/{bookSlug}/page/{pageSlug}/restrict', 'PageController@showRestrict'); 39 + Route::get('/{bookSlug}/page/{pageSlug}/permissions', 'PageController@showRestrict');
40 - Route::put('/{bookSlug}/page/{pageSlug}/restrict', 'PageController@restrict'); 40 + Route::put('/{bookSlug}/page/{pageSlug}/permissions', 'PageController@restrict');
41 Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update'); 41 Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update');
42 Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy'); 42 Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy');
43 Route::delete('/{bookSlug}/draft/{pageId}', 'PageController@destroyDraft'); 43 Route::delete('/{bookSlug}/draft/{pageId}', 'PageController@destroyDraft');
...@@ -54,8 +54,8 @@ Route::group(['middleware' => 'auth'], function () { ...@@ -54,8 +54,8 @@ Route::group(['middleware' => 'auth'], function () {
54 Route::get('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@show'); 54 Route::get('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@show');
55 Route::put('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@update'); 55 Route::put('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@update');
56 Route::get('/{bookSlug}/chapter/{chapterSlug}/edit', 'ChapterController@edit'); 56 Route::get('/{bookSlug}/chapter/{chapterSlug}/edit', 'ChapterController@edit');
57 - Route::get('/{bookSlug}/chapter/{chapterSlug}/restrict', 'ChapterController@showRestrict'); 57 + Route::get('/{bookSlug}/chapter/{chapterSlug}/permissions', 'ChapterController@showRestrict');
58 - Route::put('/{bookSlug}/chapter/{chapterSlug}/restrict', 'ChapterController@restrict'); 58 + Route::put('/{bookSlug}/chapter/{chapterSlug}/permissions', 'ChapterController@restrict');
59 Route::get('/{bookSlug}/chapter/{chapterSlug}/delete', 'ChapterController@showDelete'); 59 Route::get('/{bookSlug}/chapter/{chapterSlug}/delete', 'ChapterController@showDelete');
60 Route::delete('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@destroy'); 60 Route::delete('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@destroy');
61 61
......
...@@ -42,6 +42,25 @@ class RestrictionService ...@@ -42,6 +42,25 @@ class RestrictionService
42 } 42 }
43 43
44 /** 44 /**
45 + * Check if an entity has restrictions set on itself or its
46 + * parent tree.
47 + * @param Entity $entity
48 + * @param $action
49 + * @return bool|mixed
50 + */
51 + public function checkIfRestrictionsSet(Entity $entity, $action)
52 + {
53 + $this->currentAction = $action;
54 + if ($entity->isA('page')) {
55 + return $entity->restricted || ($entity->chapter && $entity->chapter->restricted) || $entity->book->restricted;
56 + } elseif ($entity->isA('chapter')) {
57 + return $entity->restricted || $entity->book->restricted;
58 + } elseif ($entity->isA('book')) {
59 + return $entity->restricted;
60 + }
61 + }
62 +
63 + /**
45 * Add restrictions for a page query 64 * Add restrictions for a page query
46 * @param $query 65 * @param $query
47 * @param string $action 66 * @param string $action
......
...@@ -52,12 +52,13 @@ function userCan($permission, \BookStack\Ownable $ownable = null) ...@@ -52,12 +52,13 @@ function userCan($permission, \BookStack\Ownable $ownable = null)
52 52
53 if (!$ownable instanceof \BookStack\Entity) return $hasPermission; 53 if (!$ownable instanceof \BookStack\Entity) return $hasPermission;
54 54
55 - // Check restrictions on the entitiy 55 + // Check restrictions on the entity
56 $restrictionService = app('BookStack\Services\RestrictionService'); 56 $restrictionService = app('BookStack\Services\RestrictionService');
57 $explodedPermission = explode('-', $permission); 57 $explodedPermission = explode('-', $permission);
58 $action = end($explodedPermission); 58 $action = end($explodedPermission);
59 $hasAccess = $restrictionService->checkIfEntityRestricted($ownable, $action); 59 $hasAccess = $restrictionService->checkIfEntityRestricted($ownable, $action);
60 - return $hasAccess && $hasPermission; 60 + $restrictionsSet = $restrictionService->checkIfRestrictionsSet($ownable, $action);
61 + return ($hasAccess && $restrictionsSet) || (!$restrictionsSet && $hasPermission);
61 } 62 }
62 63
63 /** 64 /**
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
16 16
17 17
18 <div class="container" ng-non-bindable> 18 <div class="container" ng-non-bindable>
19 - <h1>Book Restrictions</h1> 19 + <h1>Book Permissions</h1>
20 @include('form/restriction-form', ['model' => $book]) 20 @include('form/restriction-form', ['model' => $book])
21 </div> 21 </div>
22 22
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
24 <li><a href="{{ $book->getUrl() }}/sort" class="text-primary"><i class="zmdi zmdi-sort"></i>Sort</a></li> 24 <li><a href="{{ $book->getUrl() }}/sort" class="text-primary"><i class="zmdi zmdi-sort"></i>Sort</a></li>
25 @endif 25 @endif
26 @if(userCan('restrictions-manage', $book)) 26 @if(userCan('restrictions-manage', $book))
27 - <li><a href="{{$book->getUrl()}}/restrict" class="text-primary"><i class="zmdi zmdi-lock-outline"></i>Restrict</a></li> 27 + <li><a href="{{$book->getUrl()}}/permissions" class="text-primary"><i class="zmdi zmdi-lock-outline"></i>Permissions</a></li>
28 @endif 28 @endif
29 @if(userCan('book-delete', $book)) 29 @if(userCan('book-delete', $book))
30 <li><a href="{{ $book->getUrl() }}/delete" class="text-neg"><i class="zmdi zmdi-delete"></i>Delete</a></li> 30 <li><a href="{{ $book->getUrl() }}/delete" class="text-neg"><i class="zmdi zmdi-delete"></i>Delete</a></li>
...@@ -90,9 +90,9 @@ ...@@ -90,9 +90,9 @@
90 @if($book->restricted) 90 @if($book->restricted)
91 <p class="text-muted"> 91 <p class="text-muted">
92 @if(userCan('restrictions-manage', $book)) 92 @if(userCan('restrictions-manage', $book))
93 - <a href="{{ $book->getUrl() }}/restrict"><i class="zmdi zmdi-lock-outline"></i>Book Restricted</a> 93 + <a href="{{ $book->getUrl() }}/permissions"><i class="zmdi zmdi-lock-outline"></i>Book Permissions Active</a>
94 @else 94 @else
95 - <i class="zmdi zmdi-lock-outline"></i>Book Restricted 95 + <i class="zmdi zmdi-lock-outline"></i>Book Permissions Active
96 @endif 96 @endif
97 </p> 97 </p>
98 @endif 98 @endif
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 </div> 17 </div>
18 18
19 <div class="container" ng-non-bindable> 19 <div class="container" ng-non-bindable>
20 - <h1>Chapter Restrictions</h1> 20 + <h1>Chapter Permissions</h1>
21 @include('form/restriction-form', ['model' => $chapter]) 21 @include('form/restriction-form', ['model' => $chapter])
22 </div> 22 </div>
23 23
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 <a href="{{$chapter->getUrl() . '/edit'}}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>Edit</a> 19 <a href="{{$chapter->getUrl() . '/edit'}}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>Edit</a>
20 @endif 20 @endif
21 @if(userCan('restrictions-manage', $chapter)) 21 @if(userCan('restrictions-manage', $chapter))
22 - <a href="{{$chapter->getUrl()}}/restrict" class="text-primary text-button"><i class="zmdi zmdi-lock-outline"></i>Restrict</a> 22 + <a href="{{$chapter->getUrl()}}/permissions" class="text-primary text-button"><i class="zmdi zmdi-lock-outline"></i>Permissions</a>
23 @endif 23 @endif
24 @if(userCan('chapter-delete', $chapter)) 24 @if(userCan('chapter-delete', $chapter))
25 <a href="{{$chapter->getUrl() . '/delete'}}" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a> 25 <a href="{{$chapter->getUrl() . '/delete'}}" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a>
...@@ -69,18 +69,18 @@ ...@@ -69,18 +69,18 @@
69 69
70 @if($book->restricted) 70 @if($book->restricted)
71 @if(userCan('restrictions-manage', $book)) 71 @if(userCan('restrictions-manage', $book))
72 - <a href="{{ $book->getUrl() }}/restrict"><i class="zmdi zmdi-lock-outline"></i>Book Restricted</a> 72 + <a href="{{ $book->getUrl() }}/permissions"><i class="zmdi zmdi-lock-outline"></i>Book Permissions Active</a>
73 @else 73 @else
74 - <i class="zmdi zmdi-lock-outline"></i>Book Restricted 74 + <i class="zmdi zmdi-lock-outline"></i>Book Permissions Active
75 @endif 75 @endif
76 <br> 76 <br>
77 @endif 77 @endif
78 78
79 @if($chapter->restricted) 79 @if($chapter->restricted)
80 @if(userCan('restrictions-manage', $chapter)) 80 @if(userCan('restrictions-manage', $chapter))
81 - <a href="{{ $chapter->getUrl() }}/restrict"><i class="zmdi zmdi-lock-outline"></i>Chapter Restricted</a> 81 + <a href="{{ $chapter->getUrl() }}/permissions"><i class="zmdi zmdi-lock-outline"></i>Chapter Permissions Active</a>
82 @else 82 @else
83 - <i class="zmdi zmdi-lock-outline"></i>Chapter Restricted 83 + <i class="zmdi zmdi-lock-outline"></i>Chapter Permissions Active
84 @endif 84 @endif
85 @endif 85 @endif
86 </div> 86 </div>
......
1 -<form action="{{ $model->getUrl() }}/restrict" method="POST"> 1 +<form action="{{ $model->getUrl() }}/permissions" method="POST">
2 {!! csrf_field() !!} 2 {!! csrf_field() !!}
3 <input type="hidden" name="_method" value="PUT"> 3 <input type="hidden" name="_method" value="PUT">
4 4
5 + <p>Once enabled, These permissions will take priority over any set role permissions.</p>
6 +
5 <div class="form-group"> 7 <div class="form-group">
6 - @include('form/checkbox', ['name' => 'restricted', 'label' => 'Restrict this ' . $model->getClassName()]) 8 + @include('form/checkbox', ['name' => 'restricted', 'label' => 'Enable custom permissions'])
7 </div> 9 </div>
8 10
11 +
9 <table class="table"> 12 <table class="table">
10 <tr> 13 <tr>
11 <th>Role</th> 14 <th>Role</th>
...@@ -25,5 +28,5 @@ ...@@ -25,5 +28,5 @@
25 </table> 28 </table>
26 29
27 <a href="{{ $model->getUrl() }}" class="button muted">Cancel</a> 30 <a href="{{ $model->getUrl() }}" class="button muted">Cancel</a>
28 - <button type="submit" class="button pos">Save Restrictions</button> 31 + <button type="submit" class="button pos">Save Permissions</button>
29 </form> 32 </form>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
24 </div> 24 </div>
25 25
26 <div class="container" ng-non-bindable> 26 <div class="container" ng-non-bindable>
27 - <h1>Page Restrictions</h1> 27 + <h1>Page Permissions</h1>
28 @include('form/restriction-form', ['model' => $page]) 28 @include('form/restriction-form', ['model' => $page])
29 </div> 29 </div>
30 30
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
32 <a href="{{$page->getUrl()}}/edit" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>Edit</a> 32 <a href="{{$page->getUrl()}}/edit" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>Edit</a>
33 @endif 33 @endif
34 @if(userCan('restrictions-manage', $page)) 34 @if(userCan('restrictions-manage', $page))
35 - <a href="{{$page->getUrl()}}/restrict" class="text-primary text-button"><i class="zmdi zmdi-lock-outline"></i>Restrict</a> 35 + <a href="{{$page->getUrl()}}/permissions" class="text-primary text-button"><i class="zmdi zmdi-lock-outline"></i>Permissions</a>
36 @endif 36 @endif
37 @if(userCan('page-delete', $page)) 37 @if(userCan('page-delete', $page))
38 <a href="{{$page->getUrl()}}/delete" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a> 38 <a href="{{$page->getUrl()}}/delete" class="text-neg text-button"><i class="zmdi zmdi-delete"></i>Delete</a>
...@@ -76,27 +76,27 @@ ...@@ -76,27 +76,27 @@
76 76
77 @if($book->restricted) 77 @if($book->restricted)
78 @if(userCan('restrictions-manage', $book)) 78 @if(userCan('restrictions-manage', $book))
79 - <a href="{{ $book->getUrl() }}/restrict"><i class="zmdi zmdi-lock-outline"></i>Book restricted</a> 79 + <a href="{{ $book->getUrl() }}/permissions"><i class="zmdi zmdi-lock-outline"></i>Book Permissions Active</a>
80 @else 80 @else
81 - <i class="zmdi zmdi-lock-outline"></i>Book restricted 81 + <i class="zmdi zmdi-lock-outline"></i>Book Permissions Active
82 @endif 82 @endif
83 <br> 83 <br>
84 @endif 84 @endif
85 85
86 @if($page->chapter && $page->chapter->restricted) 86 @if($page->chapter && $page->chapter->restricted)
87 @if(userCan('restrictions-manage', $page->chapter)) 87 @if(userCan('restrictions-manage', $page->chapter))
88 - <a href="{{ $page->chapter->getUrl() }}/restrict"><i class="zmdi zmdi-lock-outline"></i>Chapter restricted</a> 88 + <a href="{{ $page->chapter->getUrl() }}/permissions"><i class="zmdi zmdi-lock-outline"></i>Chapter Permissions Active</a>
89 @else 89 @else
90 - <i class="zmdi zmdi-lock-outline"></i>Chapter restricted 90 + <i class="zmdi zmdi-lock-outline"></i>Chapter Permissions Active
91 @endif 91 @endif
92 <br> 92 <br>
93 @endif 93 @endif
94 94
95 @if($page->restricted) 95 @if($page->restricted)
96 @if(userCan('restrictions-manage', $page)) 96 @if(userCan('restrictions-manage', $page))
97 - <a href="{{ $page->getUrl() }}/restrict"><i class="zmdi zmdi-lock-outline"></i>Page restricted</a> 97 + <a href="{{ $page->getUrl() }}/permissions"><i class="zmdi zmdi-lock-outline"></i>Page Permissions Active</a>
98 @else 98 @else
99 - <i class="zmdi zmdi-lock-outline"></i>Page restricted 99 + <i class="zmdi zmdi-lock-outline"></i>Page Permissions Active
100 @endif 100 @endif
101 <br> 101 <br>
102 @endif 102 @endif
......
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
24 <hr class="even"> 24 <hr class="even">
25 <div class="row"> 25 <div class="row">
26 <div class="col-md-6"> 26 <div class="col-md-6">
27 - <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-all']) Manage all restrictions</label> 27 + <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-all']) Manage all Book, Chapter & Page permissions</label>
28 </div> 28 </div>
29 <div class="col-md-6"> 29 <div class="col-md-6">
30 - <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-own']) Manage restrictions on own content</label> 30 + <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-own']) Manage permissions on own Book, Chapter & Pages</label>
31 </div> 31 </div>
32 </div> 32 </div>
33 <hr class="even"> 33 <hr class="even">
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
43 <h3>Asset Permissions</h3> 43 <h3>Asset Permissions</h3>
44 <p> 44 <p>
45 These permissions control default access to the assets within the system. <br> 45 These permissions control default access to the assets within the system. <br>
46 - Restrictions on Books, Chapters and Pages will override these permissions. 46 + Permissions on Books, Chapters and Pages will override these permissions.
47 </p> 47 </p>
48 <table class="table"> 48 <table class="table">
49 <tr> 49 <tr>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
10 <form action="/settings/users/{{$user->id}}" method="POST"> 10 <form action="/settings/users/{{$user->id}}" method="POST">
11 {!! csrf_field() !!} 11 {!! csrf_field() !!}
12 <input type="hidden" name="_method" value="DELETE"> 12 <input type="hidden" name="_method" value="DELETE">
13 - <a href="/users/{{$user->id}}" class="button muted">Cancel</a> 13 + <a href="/settings/users/{{$user->id}}" class="button muted">Cancel</a>
14 <button type="submit" class="button neg">Confirm</button> 14 <button type="submit" class="button neg">Confirm</button>
15 </form> 15 </form>
16 </div> 16 </div>
......
...@@ -3,11 +3,21 @@ ...@@ -3,11 +3,21 @@
3 class RestrictionsTest extends TestCase 3 class RestrictionsTest extends TestCase
4 { 4 {
5 protected $user; 5 protected $user;
6 + protected $viewer;
6 7
7 public function setUp() 8 public function setUp()
8 { 9 {
9 parent::setUp(); 10 parent::setUp();
10 $this->user = $this->getNewUser(); 11 $this->user = $this->getNewUser();
12 + $this->viewer = $this->getViewer();
13 + }
14 +
15 + protected function getViewer()
16 + {
17 + $role = \BookStack\Role::getRole('viewer');
18 + $viewer = $this->getNewBlankUser();
19 + $viewer->attachRole($role);;
20 + return $viewer;
11 } 21 }
12 22
13 /** 23 /**
...@@ -20,11 +30,16 @@ class RestrictionsTest extends TestCase ...@@ -20,11 +30,16 @@ class RestrictionsTest extends TestCase
20 $entity->restricted = true; 30 $entity->restricted = true;
21 $entity->restrictions()->delete(); 31 $entity->restrictions()->delete();
22 $role = $this->user->roles->first(); 32 $role = $this->user->roles->first();
33 + $viewerRole = $this->viewer->roles->first();
23 foreach ($actions as $action) { 34 foreach ($actions as $action) {
24 $entity->restrictions()->create([ 35 $entity->restrictions()->create([
25 'role_id' => $role->id, 36 'role_id' => $role->id,
26 'action' => strtolower($action) 37 'action' => strtolower($action)
27 ]); 38 ]);
39 + $entity->restrictions()->create([
40 + 'role_id' => $viewerRole->id,
41 + 'action' => strtolower($action)
42 + ]);
28 } 43 }
29 $entity->save(); 44 $entity->save();
30 $entity->load('restrictions'); 45 $entity->load('restrictions');
...@@ -65,6 +80,10 @@ class RestrictionsTest extends TestCase ...@@ -65,6 +80,10 @@ class RestrictionsTest extends TestCase
65 $book = \BookStack\Book::first(); 80 $book = \BookStack\Book::first();
66 81
67 $bookUrl = $book->getUrl(); 82 $bookUrl = $book->getUrl();
83 + $this->actingAs($this->viewer)
84 + ->visit($bookUrl)
85 + ->dontSeeInElement('.action-buttons', 'New Page')
86 + ->dontSeeInElement('.action-buttons', 'New Chapter');
68 $this->actingAs($this->user) 87 $this->actingAs($this->user)
69 ->visit($bookUrl) 88 ->visit($bookUrl)
70 ->seeInElement('.action-buttons', 'New Page') 89 ->seeInElement('.action-buttons', 'New Page')
...@@ -319,11 +338,11 @@ class RestrictionsTest extends TestCase ...@@ -319,11 +338,11 @@ class RestrictionsTest extends TestCase
319 public function test_book_restriction_form() 338 public function test_book_restriction_form()
320 { 339 {
321 $book = \BookStack\Book::first(); 340 $book = \BookStack\Book::first();
322 - $this->asAdmin()->visit($book->getUrl() . '/restrict') 341 + $this->asAdmin()->visit($book->getUrl() . '/permissions')
323 - ->see('Book Restrictions') 342 + ->see('Book Permissions')
324 ->check('restricted') 343 ->check('restricted')
325 ->check('restrictions[2][view]') 344 ->check('restrictions[2][view]')
326 - ->press('Save Restrictions') 345 + ->press('Save Permissions')
327 ->seeInDatabase('books', ['id' => $book->id, 'restricted' => true]) 346 ->seeInDatabase('books', ['id' => $book->id, 'restricted' => true])
328 ->seeInDatabase('restrictions', [ 347 ->seeInDatabase('restrictions', [
329 'restrictable_id' => $book->id, 348 'restrictable_id' => $book->id,
...@@ -336,11 +355,11 @@ class RestrictionsTest extends TestCase ...@@ -336,11 +355,11 @@ class RestrictionsTest extends TestCase
336 public function test_chapter_restriction_form() 355 public function test_chapter_restriction_form()
337 { 356 {
338 $chapter = \BookStack\Chapter::first(); 357 $chapter = \BookStack\Chapter::first();
339 - $this->asAdmin()->visit($chapter->getUrl() . '/restrict') 358 + $this->asAdmin()->visit($chapter->getUrl() . '/permissions')
340 - ->see('Chapter Restrictions') 359 + ->see('Chapter Permissions')
341 ->check('restricted') 360 ->check('restricted')
342 ->check('restrictions[2][update]') 361 ->check('restrictions[2][update]')
343 - ->press('Save Restrictions') 362 + ->press('Save Permissions')
344 ->seeInDatabase('chapters', ['id' => $chapter->id, 'restricted' => true]) 363 ->seeInDatabase('chapters', ['id' => $chapter->id, 'restricted' => true])
345 ->seeInDatabase('restrictions', [ 364 ->seeInDatabase('restrictions', [
346 'restrictable_id' => $chapter->id, 365 'restrictable_id' => $chapter->id,
...@@ -353,11 +372,11 @@ class RestrictionsTest extends TestCase ...@@ -353,11 +372,11 @@ class RestrictionsTest extends TestCase
353 public function test_page_restriction_form() 372 public function test_page_restriction_form()
354 { 373 {
355 $page = \BookStack\Page::first(); 374 $page = \BookStack\Page::first();
356 - $this->asAdmin()->visit($page->getUrl() . '/restrict') 375 + $this->asAdmin()->visit($page->getUrl() . '/permissions')
357 - ->see('Page Restrictions') 376 + ->see('Page Permissions')
358 ->check('restricted') 377 ->check('restricted')
359 ->check('restrictions[2][delete]') 378 ->check('restrictions[2][delete]')
360 - ->press('Save Restrictions') 379 + ->press('Save Permissions')
361 ->seeInDatabase('pages', ['id' => $page->id, 'restricted' => true]) 380 ->seeInDatabase('pages', ['id' => $page->id, 'restricted' => true])
362 ->seeInDatabase('restrictions', [ 381 ->seeInDatabase('restrictions', [
363 'restrictable_id' => $page->id, 382 'restrictable_id' => $page->id,
...@@ -404,4 +423,99 @@ class RestrictionsTest extends TestCase ...@@ -404,4 +423,99 @@ class RestrictionsTest extends TestCase
404 ->dontSee($page->name); 423 ->dontSee($page->name);
405 } 424 }
406 425
426 + public function test_book_create_restriction_override()
427 + {
428 + $book = \BookStack\Book::first();
429 +
430 + $bookUrl = $book->getUrl();
431 + $this->actingAs($this->viewer)
432 + ->visit($bookUrl)
433 + ->dontSeeInElement('.action-buttons', 'New Page')
434 + ->dontSeeInElement('.action-buttons', 'New Chapter');
435 +
436 + $this->setEntityRestrictions($book, ['view', 'delete', 'update']);
437 +
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');
444 +
445 + $this->setEntityRestrictions($book, ['view', 'create']);
446 +
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')
455 + ->press('Save Page')
456 + ->seePageIs($bookUrl . '/page/test-page');
457 + $this->visit($bookUrl)->seeInElement('.action-buttons', 'New Page')
458 + ->seeInElement('.action-buttons', 'New Chapter');
459 + }
460 +
461 + public function test_book_update_restriction_override()
462 + {
463 + $book = \BookStack\Book::first();
464 + $bookPage = $book->pages->first();
465 + $bookChapter = $book->chapters->first();
466 +
467 + $bookUrl = $book->getUrl();
468 + $this->actingAs($this->viewer)
469 + ->visit($bookUrl . '/edit')
470 + ->dontSee('Edit Book');
471 +
472 + $this->setEntityRestrictions($book, ['view', 'delete']);
473 +
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('/');
480 +
481 + $this->setEntityRestrictions($book, ['view', 'update']);
482 +
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');
489 + }
490 +
491 + public function test_book_delete_restriction_override()
492 + {
493 + $book = \BookStack\Book::first();
494 + $bookPage = $book->pages->first();
495 + $bookChapter = $book->chapters->first();
496 +
497 + $bookUrl = $book->getUrl();
498 + $this->actingAs($this->viewer)
499 + ->visit($bookUrl . '/delete')
500 + ->dontSee('Delete Book');
501 +
502 + $this->setEntityRestrictions($book, ['view', 'update']);
503 +
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('/');
510 +
511 + $this->setEntityRestrictions($book, ['view', 'delete']);
512 +
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');
519 + }
520 +
407 } 521 }
......
...@@ -129,14 +129,14 @@ class RolesTest extends TestCase ...@@ -129,14 +129,14 @@ class RolesTest extends TestCase
129 { 129 {
130 $page = \BookStack\Page::take(1)->get()->first(); 130 $page = \BookStack\Page::take(1)->get()->first();
131 $this->actingAs($this->user)->visit($page->getUrl()) 131 $this->actingAs($this->user)->visit($page->getUrl())
132 - ->dontSee('Restrict') 132 + ->dontSee('Permissions')
133 - ->visit($page->getUrl() . '/restrict') 133 + ->visit($page->getUrl() . '/permissions')
134 ->seePageIs('/'); 134 ->seePageIs('/');
135 $this->giveUserPermissions($this->user, ['restrictions-manage-all']); 135 $this->giveUserPermissions($this->user, ['restrictions-manage-all']);
136 $this->actingAs($this->user)->visit($page->getUrl()) 136 $this->actingAs($this->user)->visit($page->getUrl())
137 - ->see('Restrict') 137 + ->see('Permissions')
138 - ->click('Restrict') 138 + ->click('Permissions')
139 - ->see('Page Restrictions')->seePageIs($page->getUrl() . '/restrict'); 139 + ->see('Page Permissions')->seePageIs($page->getUrl() . '/permissions');
140 } 140 }
141 141
142 public function test_restrictions_manage_own_permission() 142 public function test_restrictions_manage_own_permission()
...@@ -145,27 +145,27 @@ class RolesTest extends TestCase ...@@ -145,27 +145,27 @@ class RolesTest extends TestCase
145 $content = $this->createEntityChainBelongingToUser($this->user); 145 $content = $this->createEntityChainBelongingToUser($this->user);
146 // Check can't restrict other's content 146 // Check can't restrict other's content
147 $this->actingAs($this->user)->visit($otherUsersPage->getUrl()) 147 $this->actingAs($this->user)->visit($otherUsersPage->getUrl())
148 - ->dontSee('Restrict') 148 + ->dontSee('Permissions')
149 - ->visit($otherUsersPage->getUrl() . '/restrict') 149 + ->visit($otherUsersPage->getUrl() . '/permissions')
150 ->seePageIs('/'); 150 ->seePageIs('/');
151 // Check can't restrict own content 151 // Check can't restrict own content
152 $this->actingAs($this->user)->visit($content['page']->getUrl()) 152 $this->actingAs($this->user)->visit($content['page']->getUrl())
153 - ->dontSee('Restrict') 153 + ->dontSee('Permissions')
154 - ->visit($content['page']->getUrl() . '/restrict') 154 + ->visit($content['page']->getUrl() . '/permissions')
155 ->seePageIs('/'); 155 ->seePageIs('/');
156 156
157 $this->giveUserPermissions($this->user, ['restrictions-manage-own']); 157 $this->giveUserPermissions($this->user, ['restrictions-manage-own']);
158 158
159 // Check can't restrict other's content 159 // Check can't restrict other's content
160 $this->actingAs($this->user)->visit($otherUsersPage->getUrl()) 160 $this->actingAs($this->user)->visit($otherUsersPage->getUrl())
161 - ->dontSee('Restrict') 161 + ->dontSee('Permissions')
162 - ->visit($otherUsersPage->getUrl() . '/restrict') 162 + ->visit($otherUsersPage->getUrl() . '/permissions')
163 ->seePageIs('/'); 163 ->seePageIs('/');
164 // Check can restrict own content 164 // Check can restrict own content
165 $this->actingAs($this->user)->visit($content['page']->getUrl()) 165 $this->actingAs($this->user)->visit($content['page']->getUrl())
166 - ->see('Restrict') 166 + ->see('Permissions')
167 - ->click('Restrict') 167 + ->click('Permissions')
168 - ->seePageIs($content['page']->getUrl() . '/restrict'); 168 + ->seePageIs($content['page']->getUrl() . '/permissions');
169 } 169 }
170 170
171 /** 171 /**
......
...@@ -170,4 +170,12 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase ...@@ -170,4 +170,12 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase
170 $this->visit($link->link()->getUri()); 170 $this->visit($link->link()->getUri());
171 return $this; 171 return $this;
172 } 172 }
173 +
174 + protected function actingAsUsers($usersArray, $callback)
175 + {
176 + foreach ($usersArray as $user) {
177 + $this->actingAs($user);
178 + $callback($user);
179 + }
180 + }
173 } 181 }
......