Showing
17 changed files
with
211 additions
and
63 deletions
| ... | @@ -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 | ... | ... |
| ... | @@ -162,4 +162,19 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon | ... | @@ -162,4 +162,19 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon |
| 162 | { | 162 | { |
| 163 | return '/settings/users/' . $this->id; | 163 | return '/settings/users/' . $this->id; |
| 164 | } | 164 | } |
| 165 | + | ||
| 166 | + /** | ||
| 167 | + * Get a shortened version of the user's name. | ||
| 168 | + * @param int $chars | ||
| 169 | + * @return string | ||
| 170 | + */ | ||
| 171 | + public function getShortName($chars = 8) | ||
| 172 | + { | ||
| 173 | + if (strlen($this->name) <= $chars) return $this->name; | ||
| 174 | + | ||
| 175 | + $splitName = explode(' ', $this->name); | ||
| 176 | + if (strlen($splitName[0]) <= $chars) return $splitName[0]; | ||
| 177 | + | ||
| 178 | + return ''; | ||
| 179 | + } | ||
| 165 | } | 180 | } | ... | ... |
| ... | @@ -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 | /** | ... | ... |
| ... | @@ -56,18 +56,14 @@ header { | ... | @@ -56,18 +56,14 @@ header { |
| 56 | padding-top: $-xxs; | 56 | padding-top: $-xxs; |
| 57 | } | 57 | } |
| 58 | > i { | 58 | > i { |
| 59 | - padding-top: $-xs*1.2; | 59 | + padding-top: 4px; |
| 60 | + font-size: 18px; | ||
| 60 | } | 61 | } |
| 61 | @include smaller-than($screen-md) { | 62 | @include smaller-than($screen-md) { |
| 62 | padding-left: $-xs; | 63 | padding-left: $-xs; |
| 63 | .name { | 64 | .name { |
| 64 | display: none; | 65 | display: none; |
| 65 | } | 66 | } |
| 66 | - i { | ||
| 67 | - font-size: 2em; | ||
| 68 | - padding-left: 0; | ||
| 69 | - padding-top: 0; | ||
| 70 | - } | ||
| 71 | } | 67 | } |
| 72 | } | 68 | } |
| 73 | @include smaller-than($screen-md) { | 69 | @include smaller-than($screen-md) { | ... | ... |
| ... | @@ -56,7 +56,7 @@ | ... | @@ -56,7 +56,7 @@ |
| 56 | <div class="dropdown-container" dropdown> | 56 | <div class="dropdown-container" dropdown> |
| 57 | <span class="user-name" dropdown-toggle> | 57 | <span class="user-name" dropdown-toggle> |
| 58 | <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}"> | 58 | <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}"> |
| 59 | - <span class="name" ng-non-bindable>{{ $currentUser->name }}</span> <i class="zmdi zmdi-caret-down"></i> | 59 | + <span class="name" ng-non-bindable>{{ $currentUser->getShortName(9) }}</span> <i class="zmdi zmdi-caret-down"></i> |
| 60 | </span> | 60 | </span> |
| 61 | <ul> | 61 | <ul> |
| 62 | <li> | 62 | <li> | ... | ... |
| ... | @@ -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 | /** | ... | ... |
-
Please register or sign in to post a comment