Dan Brown

Worked around create permission quirks

...@@ -69,7 +69,7 @@ class PageController extends Controller ...@@ -69,7 +69,7 @@ class PageController extends Controller
69 { 69 {
70 $book = $this->bookRepo->getBySlug($bookSlug); 70 $book = $this->bookRepo->getBySlug($bookSlug);
71 $draft = $this->pageRepo->getById($pageId, true); 71 $draft = $this->pageRepo->getById($pageId, true);
72 - $this->checkOwnablePermission('page-create', $draft); 72 + $this->checkOwnablePermission('page-create', $book);
73 $this->setPageTitle('Edit Page Draft'); 73 $this->setPageTitle('Edit Page Draft');
74 74
75 return view('pages/create', ['draft' => $draft, 'book' => $book]); 75 return view('pages/create', ['draft' => $draft, 'book' => $book]);
......
...@@ -6,6 +6,7 @@ use BookStack\Entity; ...@@ -6,6 +6,7 @@ use BookStack\Entity;
6 use BookStack\EntityPermission; 6 use BookStack\EntityPermission;
7 use BookStack\Page; 7 use BookStack\Page;
8 use BookStack\Role; 8 use BookStack\Role;
9 +use BookStack\User;
9 use Illuminate\Database\Eloquent\Collection; 10 use Illuminate\Database\Eloquent\Collection;
10 11
11 class RestrictionService 12 class RestrictionService
...@@ -24,12 +25,6 @@ class RestrictionService ...@@ -24,12 +25,6 @@ class RestrictionService
24 protected $role; 25 protected $role;
25 26
26 /** 27 /**
27 - * The actions that have permissions attached throughout the application.
28 - * @var array
29 - */
30 - protected $actions = ['view', 'create', 'update', 'delete'];
31 -
32 - /**
33 * RestrictionService constructor. 28 * RestrictionService constructor.
34 * @param EntityPermission $entityPermission 29 * @param EntityPermission $entityPermission
35 * @param Book $book 30 * @param Book $book
...@@ -40,6 +35,7 @@ class RestrictionService ...@@ -40,6 +35,7 @@ class RestrictionService
40 public function __construct(EntityPermission $entityPermission, Book $book, Chapter $chapter, Page $page, Role $role) 35 public function __construct(EntityPermission $entityPermission, Book $book, Chapter $chapter, Page $page, Role $role)
41 { 36 {
42 $this->currentUser = auth()->user(); 37 $this->currentUser = auth()->user();
38 + if ($this->currentUser === null) $this->currentUser = new User(['id' => 0]);
43 $this->userRoles = $this->currentUser ? $this->currentUser->roles->pluck('id') : []; 39 $this->userRoles = $this->currentUser ? $this->currentUser->roles->pluck('id') : [];
44 $this->isAdmin = $this->currentUser ? $this->currentUser->hasRole('admin') : false; 40 $this->isAdmin = $this->currentUser ? $this->currentUser->hasRole('admin') : false;
45 41
...@@ -172,15 +168,34 @@ class RestrictionService ...@@ -172,15 +168,34 @@ class RestrictionService
172 $entityPermissions = []; 168 $entityPermissions = [];
173 foreach ($entities as $entity) { 169 foreach ($entities as $entity) {
174 foreach ($roles as $role) { 170 foreach ($roles as $role) {
175 - foreach ($this->actions as $action) { 171 + foreach ($this->getActions($entity) as $action) {
176 $entityPermissions[] = $this->createEntityPermissionData($entity, $role, $action); 172 $entityPermissions[] = $this->createEntityPermissionData($entity, $role, $action);
177 } 173 }
178 } 174 }
179 } 175 }
180 - \Log::info(collect($entityPermissions)->where('entity_id', 1)->where('entity_type', 'BookStack\\Page')->where('role_id', 2)->all());
181 $this->entityPermission->insert($entityPermissions); 176 $this->entityPermission->insert($entityPermissions);
182 } 177 }
183 178
179 +
180 + /**
181 + * Get the actions related to an entity.
182 + * @param $entity
183 + * @return array
184 + */
185 + protected function getActions($entity)
186 + {
187 + $baseActions = ['view', 'update', 'delete'];
188 +
189 + if ($entity->isA('chapter')) {
190 + $baseActions[] = 'page-create';
191 + } else if ($entity->isA('book')) {
192 + $baseActions[] = 'page-create';
193 + $baseActions[] = 'chapter-create';
194 + }
195 +
196 + return $baseActions;
197 + }
198 +
184 /** 199 /**
185 * Create entity permission data for an entity and role 200 * Create entity permission data for an entity and role
186 * for a particular action. 201 * for a particular action.
...@@ -191,38 +206,40 @@ class RestrictionService ...@@ -191,38 +206,40 @@ class RestrictionService
191 */ 206 */
192 protected function createEntityPermissionData(Entity $entity, Role $role, $action) 207 protected function createEntityPermissionData(Entity $entity, Role $role, $action)
193 { 208 {
194 - $permissionPrefix = $entity->getType() . '-' . $action; 209 + $permissionPrefix = (strpos($action, '-') === false ? ($entity->getType() . '-') : '') . $action;
195 $roleHasPermission = $role->hasPermission($permissionPrefix . '-all'); 210 $roleHasPermission = $role->hasPermission($permissionPrefix . '-all');
196 $roleHasPermissionOwn = $role->hasPermission($permissionPrefix . '-own'); 211 $roleHasPermissionOwn = $role->hasPermission($permissionPrefix . '-own');
212 + $explodedAction = explode('-', $action);
213 + $restrictionAction = end($explodedAction);
197 214
198 if ($entity->isA('book')) { 215 if ($entity->isA('book')) {
199 216
200 if (!$entity->restricted) { 217 if (!$entity->restricted) {
201 return $this->createEntityPermissionDataArray($entity, $role, $action, $roleHasPermission, $roleHasPermissionOwn); 218 return $this->createEntityPermissionDataArray($entity, $role, $action, $roleHasPermission, $roleHasPermissionOwn);
202 } else { 219 } else {
203 - $hasAccess = $entity->hasActiveRestriction($role->id, $action); 220 + $hasAccess = $entity->hasActiveRestriction($role->id, $restrictionAction);
204 return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess); 221 return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
205 } 222 }
206 223
207 } elseif ($entity->isA('chapter')) { 224 } elseif ($entity->isA('chapter')) {
208 225
209 if (!$entity->restricted) { 226 if (!$entity->restricted) {
210 - $hasExplicitAccessToBook = $entity->book->hasActiveRestriction($role->id, $action); 227 + $hasExplicitAccessToBook = $entity->book->hasActiveRestriction($role->id, $restrictionAction);
211 $hasPermissiveAccessToBook = !$entity->book->restricted; 228 $hasPermissiveAccessToBook = !$entity->book->restricted;
212 return $this->createEntityPermissionDataArray($entity, $role, $action, 229 return $this->createEntityPermissionDataArray($entity, $role, $action,
213 ($hasExplicitAccessToBook || ($roleHasPermission && $hasPermissiveAccessToBook)), 230 ($hasExplicitAccessToBook || ($roleHasPermission && $hasPermissiveAccessToBook)),
214 ($hasExplicitAccessToBook || ($roleHasPermissionOwn && $hasPermissiveAccessToBook))); 231 ($hasExplicitAccessToBook || ($roleHasPermissionOwn && $hasPermissiveAccessToBook)));
215 } else { 232 } else {
216 - $hasAccess = $entity->hasActiveRestriction($role->id, $action); 233 + $hasAccess = $entity->hasActiveRestriction($role->id, $restrictionAction);
217 return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess); 234 return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
218 } 235 }
219 236
220 } elseif ($entity->isA('page')) { 237 } elseif ($entity->isA('page')) {
221 238
222 if (!$entity->restricted) { 239 if (!$entity->restricted) {
223 - $hasExplicitAccessToBook = $entity->book->hasActiveRestriction($role->id, $action); 240 + $hasExplicitAccessToBook = $entity->book->hasActiveRestriction($role->id, $restrictionAction);
224 $hasPermissiveAccessToBook = !$entity->book->restricted; 241 $hasPermissiveAccessToBook = !$entity->book->restricted;
225 - $hasExplicitAccessToChapter = $entity->chapter && $entity->chapter->hasActiveRestriction($role->id, $action); 242 + $hasExplicitAccessToChapter = $entity->chapter && $entity->chapter->hasActiveRestriction($role->id, $restrictionAction);
226 $hasPermissiveAccessToChapter = $entity->chapter && !$entity->chapter->restricted; 243 $hasPermissiveAccessToChapter = $entity->chapter && !$entity->chapter->restricted;
227 $acknowledgeChapter = ($entity->chapter && $entity->chapter->restricted); 244 $acknowledgeChapter = ($entity->chapter && $entity->chapter->restricted);
228 245
...@@ -277,6 +294,8 @@ class RestrictionService ...@@ -277,6 +294,8 @@ class RestrictionService
277 $explodedPermission = explode('-', $permission); 294 $explodedPermission = explode('-', $permission);
278 295
279 $baseQuery = $entity->where('id', '=', $entity->id); 296 $baseQuery = $entity->where('id', '=', $entity->id);
297 + $action = end($explodedPermission);
298 + $this->currentAction = $action;
280 299
281 $nonEntityPermissions = ['restrictions']; 300 $nonEntityPermissions = ['restrictions'];
282 301
...@@ -289,8 +308,12 @@ class RestrictionService ...@@ -289,8 +308,12 @@ class RestrictionService
289 return ($allPermission || ($isOwner && $ownPermission)); 308 return ($allPermission || ($isOwner && $ownPermission));
290 } 309 }
291 310
292 - $action = end($explodedPermission); 311 + // Handle abnormal create permissions
293 - $this->currentAction = $action; 312 + if ($action === 'create') {
313 + $this->currentAction = $permission;
314 + }
315 +
316 +
294 return $this->entityRestrictionQuery($baseQuery)->count() > 0; 317 return $this->entityRestrictionQuery($baseQuery)->count() > 0;
295 } 318 }
296 319
...@@ -441,7 +464,7 @@ class RestrictionService ...@@ -441,7 +464,7 @@ class RestrictionService
441 ->where(function ($query) { 464 ->where(function ($query) {
442 $query->where('has_permission', '=', true)->orWhere(function ($query) { 465 $query->where('has_permission', '=', true)->orWhere(function ($query) {
443 $query->where('has_permission_own', '=', true) 466 $query->where('has_permission_own', '=', true)
444 - ->where('created_by', '=', $this->currentUser ? $this->currentUser->id : 0); 467 + ->where('created_by', '=', $this->currentUser->id);
445 }); 468 });
446 }); 469 });
447 }); 470 });
......
...@@ -20,12 +20,15 @@ class DummyContentSeeder extends Seeder ...@@ -20,12 +20,15 @@ class DummyContentSeeder extends Seeder
20 ->each(function($book) use ($user) { 20 ->each(function($book) use ($user) {
21 $chapters = factory(BookStack\Chapter::class, 5)->create(['created_by' => $user->id, 'updated_by' => $user->id]) 21 $chapters = factory(BookStack\Chapter::class, 5)->create(['created_by' => $user->id, 'updated_by' => $user->id])
22 ->each(function($chapter) use ($user, $book){ 22 ->each(function($chapter) use ($user, $book){
23 - $pages = factory(\BookStack\Page::class, 10)->make(['created_by' => $user->id, 'updated_by' => $user->id, 'book_id' => $book->id]); 23 + $pages = factory(\BookStack\Page::class, 5)->make(['created_by' => $user->id, 'updated_by' => $user->id, 'book_id' => $book->id]);
24 $chapter->pages()->saveMany($pages); 24 $chapter->pages()->saveMany($pages);
25 }); 25 });
26 $pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $user->id, 'updated_by' => $user->id]); 26 $pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $user->id, 'updated_by' => $user->id]);
27 $book->chapters()->saveMany($chapters); 27 $book->chapters()->saveMany($chapters);
28 $book->pages()->saveMany($pages); 28 $book->pages()->saveMany($pages);
29 }); 29 });
30 +
31 + $restrictionService = app(\BookStack\Services\RestrictionService::class);
32 + $restrictionService->buildEntityPermissions();
30 } 33 }
31 } 34 }
......