Dan Brown

Tied entity restriction system into userCan checks

...@@ -68,7 +68,7 @@ abstract class Controller extends BaseController ...@@ -68,7 +68,7 @@ abstract class Controller extends BaseController
68 protected function showPermissionError() 68 protected function showPermissionError()
69 { 69 {
70 Session::flash('error', trans('errors.permission')); 70 Session::flash('error', trans('errors.permission'));
71 - $response = request()->wantsJson() ? response()->json(['error' => trans('errors.permissionJson')], 403) : redirect('/', 403); 71 + $response = request()->wantsJson() ? response()->json(['error' => trans('errors.permissionJson')], 403) : redirect('/');
72 throw new HttpResponseException($response); 72 throw new HttpResponseException($response);
73 } 73 }
74 74
...@@ -93,10 +93,8 @@ abstract class Controller extends BaseController ...@@ -93,10 +93,8 @@ abstract class Controller extends BaseController
93 */ 93 */
94 protected function checkOwnablePermission($permission, Ownable $ownable) 94 protected function checkOwnablePermission($permission, Ownable $ownable)
95 { 95 {
96 - $permissionBaseName = strtolower($permission) . '-'; 96 + if (userCan($permission, $ownable)) return true;
97 - if (userCan($permissionBaseName . 'all')) return true; 97 + return $this->showPermissionError();
98 - if (userCan($permissionBaseName . 'own') && $ownable->createdBy->id === $this->currentUser->id) return true;
99 - $this->showPermissionError();
100 } 98 }
101 99
102 /** 100 /**
......
1 <?php namespace BookStack\Services; 1 <?php namespace BookStack\Services;
2 2
3 +use BookStack\Entity;
4 +
3 class RestrictionService 5 class RestrictionService
4 { 6 {
5 7
...@@ -12,8 +14,24 @@ class RestrictionService ...@@ -12,8 +14,24 @@ class RestrictionService
12 */ 14 */
13 public function __construct() 15 public function __construct()
14 { 16 {
15 - $this->userRoles = auth()->user()->roles->pluck('id'); 17 + $user = auth()->user();
16 - $this->isAdmin = auth()->user()->hasRole('admin'); 18 + $this->userRoles = $user ? auth()->user()->roles->pluck('id') : false;
19 + $this->isAdmin = $user ? auth()->user()->hasRole('admin') : false;
20 + }
21 +
22 + public function checkIfEntityRestricted(Entity $entity, $action)
23 + {
24 + if ($this->isAdmin) return true;
25 + $this->currentAction = $action;
26 + $baseQuery = $entity->where('id', '=', $entity->id);
27 + if ($entity->isA('page')) {
28 + return $this->pageRestrictionQuery($baseQuery)->count() > 0;
29 + } elseif ($entity->isA('chapter')) {
30 + return $this->chapterRestrictionQuery($baseQuery)->count() > 0;
31 + } elseif ($entity->isA('book')) {
32 + return $this->bookRestrictionQuery($baseQuery)->count() > 0;
33 + }
34 + return false;
17 } 35 }
18 36
19 /** 37 /**
...@@ -184,25 +202,25 @@ class RestrictionService ...@@ -184,25 +202,25 @@ class RestrictionService
184 if ($this->isAdmin) return $query; 202 if ($this->isAdmin) return $query;
185 $this->currentAction = 'view'; 203 $this->currentAction = 'view';
186 $tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn]; 204 $tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn];
187 - return $query->where(function($query) use ($tableDetails) { 205 + return $query->where(function ($query) use ($tableDetails) {
188 $query->where(function ($query) use (&$tableDetails) { 206 $query->where(function ($query) use (&$tableDetails) {
189 $query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Page') 207 $query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Page')
190 ->whereExists(function ($query) use (&$tableDetails) { 208 ->whereExists(function ($query) use (&$tableDetails) {
191 - $query->select('*')->from('pages')->whereRaw('pages.id='.$tableDetails['tableName'].'.'.$tableDetails['entityIdColumn']) 209 + $query->select('*')->from('pages')->whereRaw('pages.id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
192 ->where(function ($query) { 210 ->where(function ($query) {
193 $this->pageRestrictionQuery($query); 211 $this->pageRestrictionQuery($query);
194 }); 212 });
195 }); 213 });
196 })->orWhere(function ($query) use (&$tableDetails) { 214 })->orWhere(function ($query) use (&$tableDetails) {
197 $query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Book')->whereExists(function ($query) use (&$tableDetails) { 215 $query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Book')->whereExists(function ($query) use (&$tableDetails) {
198 - $query->select('*')->from('books')->whereRaw('books.id='.$tableDetails['tableName'].'.'.$tableDetails['entityIdColumn']) 216 + $query->select('*')->from('books')->whereRaw('books.id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
199 ->where(function ($query) { 217 ->where(function ($query) {
200 $this->bookRestrictionQuery($query); 218 $this->bookRestrictionQuery($query);
201 }); 219 });
202 }); 220 });
203 })->orWhere(function ($query) use (&$tableDetails) { 221 })->orWhere(function ($query) use (&$tableDetails) {
204 $query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Chapter')->whereExists(function ($query) use (&$tableDetails) { 222 $query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Chapter')->whereExists(function ($query) use (&$tableDetails) {
205 - $query->select('*')->from('chapters')->whereRaw('chapters.id='.$tableDetails['tableName'].'.'.$tableDetails['entityIdColumn']) 223 + $query->select('*')->from('chapters')->whereRaw('chapters.id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
206 ->where(function ($query) { 224 ->where(function ($query) {
207 $this->chapterRestrictionQuery($query); 225 $this->chapterRestrictionQuery($query);
208 }); 226 });
......
...@@ -43,8 +43,18 @@ function userCan($permission, \BookStack\Ownable $ownable = null) ...@@ -43,8 +43,18 @@ function userCan($permission, \BookStack\Ownable $ownable = null)
43 return auth()->user() && auth()->user()->can($permission); 43 return auth()->user() && auth()->user()->can($permission);
44 } 44 }
45 45
46 + // Check permission on ownable item
46 $permissionBaseName = strtolower($permission) . '-'; 47 $permissionBaseName = strtolower($permission) . '-';
47 - if (userCan($permissionBaseName . 'all')) return true; 48 + $hasPermission = false;
48 - if (userCan($permissionBaseName . 'own') && $ownable->createdBy->id === auth()->user()->id) return true; 49 + if (auth()->user()->can($permissionBaseName . 'all')) $hasPermission = true;
49 - return false; 50 + if (auth()->user()->can($permissionBaseName . 'own') && $ownable->createdBy->id === auth()->user()->id) $hasPermission = true;
51 +
52 + if(!$ownable instanceof \BookStack\Entity) return $hasPermission;
53 +
54 + // Check restrictions on the entitiy
55 + $restrictionService = app('BookStack\Services\RestrictionService');
56 + $explodedPermission = explode('-', $permission);
57 + $action = end($explodedPermission);
58 + $hasAccess = $restrictionService->checkIfEntityRestricted($ownable, $action);
59 + return $hasAccess && $hasPermission;
50 } 60 }
...\ No newline at end of file ...\ No newline at end of file
......