| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  | <?php namespace BookStack\Services; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  | use BookStack\Book; | 
					
						
							|  |  |  | use BookStack\Chapter; | 
					
						
							| 
									
										
										
										
											2016-03-01 04:31:21 +08:00
										 |  |  | use BookStack\Entity; | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  | use BookStack\JointPermission; | 
					
						
							| 
									
										
										
										
											2016-07-02 03:11:49 +08:00
										 |  |  | use BookStack\Ownable; | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  | use BookStack\Page; | 
					
						
							|  |  |  | use BookStack\Role; | 
					
						
							| 
									
										
										
										
											2016-04-27 04:48:17 +08:00
										 |  |  | use BookStack\User; | 
					
						
							| 
									
										
										
										
											2017-01-02 05:21:11 +08:00
										 |  |  | use Illuminate\Database\Connection; | 
					
						
							| 
									
										
										
										
											2017-01-02 00:05:44 +08:00
										 |  |  | use Illuminate\Database\Eloquent\Builder; | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  | use Illuminate\Support\Collection; | 
					
						
							| 
									
										
										
										
											2016-03-01 04:31:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  | class PermissionService | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected $currentAction; | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |     protected $isAdminUser; | 
					
						
							|  |  |  |     protected $userRoles = false; | 
					
						
							|  |  |  |     protected $currentUserModel = false; | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |     public $book; | 
					
						
							|  |  |  |     public $chapter; | 
					
						
							|  |  |  |     public $page; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 05:21:11 +08:00
										 |  |  |     protected $db; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     protected $jointPermission; | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |     protected $role; | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |     protected $entityCache; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |      * PermissionService constructor. | 
					
						
							|  |  |  |      * @param JointPermission $jointPermission | 
					
						
							| 
									
										
										
										
											2017-01-02 05:21:11 +08:00
										 |  |  |      * @param Connection $db | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |      * @param Book $book | 
					
						
							|  |  |  |      * @param Chapter $chapter | 
					
						
							|  |  |  |      * @param Page $page | 
					
						
							|  |  |  |      * @param Role $role | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-01-02 05:21:11 +08:00
										 |  |  |     public function __construct(JointPermission $jointPermission, Connection $db, Book $book, Chapter $chapter, Page $page, Role $role) | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-01-02 05:21:11 +08:00
										 |  |  |         $this->db = $db; | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->jointPermission = $jointPermission; | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |         $this->role = $role; | 
					
						
							|  |  |  |         $this->book = $book; | 
					
						
							|  |  |  |         $this->chapter = $chapter; | 
					
						
							|  |  |  |         $this->page = $page; | 
					
						
							| 
									
										
										
										
											2017-01-02 05:21:11 +08:00
										 |  |  |         // TODO - Update so admin still goes through filters
 | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Prepare the local entity cache and ensure it's empty | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function readyEntityCache() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->entityCache = [ | 
					
						
							|  |  |  |             'books' => collect(), | 
					
						
							|  |  |  |             'chapters' => collect() | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get a book via ID, Checks local cache | 
					
						
							|  |  |  |      * @param $bookId | 
					
						
							|  |  |  |      * @return Book | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getBook($bookId) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (isset($this->entityCache['books']) && $this->entityCache['books']->has($bookId)) { | 
					
						
							|  |  |  |             return $this->entityCache['books']->get($bookId); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $book = $this->book->find($bookId); | 
					
						
							|  |  |  |         if ($book === null) $book = false; | 
					
						
							|  |  |  |         if (isset($this->entityCache['books'])) { | 
					
						
							|  |  |  |             $this->entityCache['books']->put($bookId, $book); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $book; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get a chapter via ID, Checks local cache | 
					
						
							|  |  |  |      * @param $chapterId | 
					
						
							|  |  |  |      * @return Book | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getChapter($chapterId) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (isset($this->entityCache['chapters']) && $this->entityCache['chapters']->has($chapterId)) { | 
					
						
							|  |  |  |             return $this->entityCache['chapters']->get($chapterId); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $chapter = $this->chapter->find($chapterId); | 
					
						
							|  |  |  |         if ($chapter === null) $chapter = false; | 
					
						
							|  |  |  |         if (isset($this->entityCache['chapters'])) { | 
					
						
							|  |  |  |             $this->entityCache['chapters']->put($chapterId, $chapter); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $chapter; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 02:36:53 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the roles for the current user; | 
					
						
							|  |  |  |      * @return array|bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getRoles() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($this->userRoles !== false) return $this->userRoles; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $roles = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (auth()->guest()) { | 
					
						
							|  |  |  |             $roles[] = $this->role->getSystemRole('public')->id; | 
					
						
							|  |  |  |             return $roles; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         foreach ($this->currentUser()->roles as $role) { | 
					
						
							| 
									
										
										
										
											2016-05-02 02:36:53 +08:00
										 |  |  |             $roles[] = $role->id; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return $roles; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Re-generate all entity permission from scratch. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     public function buildJointPermissions() | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->jointPermission->truncate(); | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |         $this->readyEntityCache(); | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Get all roles (Should be the most limited dimension)
 | 
					
						
							| 
									
										
										
										
											2016-05-01 00:16:06 +08:00
										 |  |  |         $roles = $this->role->with('permissions')->get(); | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Chunk through all books
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->book->with('permissions')->chunk(500, function ($books) use ($roles) { | 
					
						
							|  |  |  |             $this->createManyJointPermissions($books, $roles); | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Chunk through all chapters
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->chapter->with('book', 'permissions')->chunk(500, function ($chapters) use ($roles) { | 
					
						
							|  |  |  |             $this->createManyJointPermissions($chapters, $roles); | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Chunk through all pages
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->page->with('book', 'chapter', 'permissions')->chunk(500, function ($pages) use ($roles) { | 
					
						
							|  |  |  |             $this->createManyJointPermissions($pages, $roles); | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |      * Rebuild the entity jointPermissions for a particular entity. | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |      * @param Entity $entity | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     public function buildJointPermissionsForEntity(Entity $entity) | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $roles = $this->role->with('jointPermissions')->get(); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |         $entities = collect([$entity]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($entity->isA('book')) { | 
					
						
							|  |  |  |             $entities = $entities->merge($entity->chapters); | 
					
						
							|  |  |  |             $entities = $entities->merge($entity->pages); | 
					
						
							|  |  |  |         } elseif ($entity->isA('chapter')) { | 
					
						
							|  |  |  |             $entities = $entities->merge($entity->pages); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->deleteManyJointPermissionsForEntities($entities); | 
					
						
							|  |  |  |         $this->createManyJointPermissions($entities, $roles); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Rebuild the entity jointPermissions for a collection of entities. | 
					
						
							|  |  |  |      * @param Collection $entities | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function buildJointPermissionsForEntities(Collection $entities) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $roles = $this->role->with('jointPermissions')->get(); | 
					
						
							|  |  |  |         $this->deleteManyJointPermissionsForEntities($entities); | 
					
						
							|  |  |  |         $this->createManyJointPermissions($entities, $roles); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |      * Build the entity jointPermissions for a particular role. | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |      * @param Role $role | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     public function buildJointPermissionForRole(Role $role) | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $roles = collect([$role]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->deleteManyJointPermissionsForRoles($roles); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Chunk through all books
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->book->with('permissions')->chunk(500, function ($books) use ($roles) { | 
					
						
							|  |  |  |             $this->createManyJointPermissions($books, $roles); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Chunk through all chapters
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->chapter->with('book', 'permissions')->chunk(500, function ($books) use ($roles) { | 
					
						
							|  |  |  |             $this->createManyJointPermissions($books, $roles); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Chunk through all pages
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->page->with('book', 'chapter', 'permissions')->chunk(500, function ($books) use ($roles) { | 
					
						
							|  |  |  |             $this->createManyJointPermissions($books, $roles); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |      * Delete the entity jointPermissions attached to a particular role. | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |      * @param Role $role | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     public function deleteJointPermissionsForRole(Role $role) | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->deleteManyJointPermissionsForRoles([$role]); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |      * Delete all of the entity jointPermissions for a list of entities. | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |      * @param Role[] $roles | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     protected function deleteManyJointPermissionsForRoles($roles) | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         foreach ($roles as $role) { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |             $role->jointPermissions()->delete(); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |      * Delete the entity jointPermissions for a particular entity. | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |      * @param Entity $entity | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     public function deleteJointPermissionsForEntity(Entity $entity) | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->deleteManyJointPermissionsForEntities([$entity]); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |      * Delete all of the entity jointPermissions for a list of entities. | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |      * @param Entity[] $entities | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     protected function deleteManyJointPermissionsForEntities($entities) | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |         $query = $this->jointPermission->newQuery(); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |         foreach ($entities as $entity) { | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |             $query->orWhere(function($query) use ($entity) { | 
					
						
							|  |  |  |                 $query->where('entity_id', '=', $entity->id) | 
					
						
							|  |  |  |                     ->where('entity_type', '=', $entity->getMorphClass()); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |         $query->delete(); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |      * Create & Save entity jointPermissions for many entities and jointPermissions. | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |      * @param Collection $entities | 
					
						
							|  |  |  |      * @param Collection $roles | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     protected function createManyJointPermissions($entities, $roles) | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |         $this->readyEntityCache(); | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $jointPermissions = []; | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |         foreach ($entities as $entity) { | 
					
						
							|  |  |  |             foreach ($roles as $role) { | 
					
						
							| 
									
										
										
										
											2016-04-27 04:48:17 +08:00
										 |  |  |                 foreach ($this->getActions($entity) as $action) { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |                     $jointPermissions[] = $this->createJointPermissionData($entity, $role, $action); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $this->jointPermission->insert($jointPermissions); | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-27 04:48:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the actions related to an entity. | 
					
						
							|  |  |  |      * @param $entity | 
					
						
							|  |  |  |      * @return array | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getActions($entity) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $baseActions = ['view', 'update', 'delete']; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($entity->isA('chapter')) { | 
					
						
							|  |  |  |             $baseActions[] = 'page-create'; | 
					
						
							|  |  |  |         } else if ($entity->isA('book')) { | 
					
						
							|  |  |  |             $baseActions[] = 'page-create'; | 
					
						
							|  |  |  |             $baseActions[] = 'chapter-create'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          return $baseActions; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Create entity permission data for an entity and role | 
					
						
							|  |  |  |      * for a particular action. | 
					
						
							|  |  |  |      * @param Entity $entity | 
					
						
							|  |  |  |      * @param Role $role | 
					
						
							|  |  |  |      * @param $action | 
					
						
							|  |  |  |      * @return array | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     protected function createJointPermissionData(Entity $entity, Role $role, $action) | 
					
						
							| 
									
										
										
										
											2016-04-21 04:37:57 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-04-27 04:48:17 +08:00
										 |  |  |         $permissionPrefix = (strpos($action, '-') === false ? ($entity->getType() . '-') : '') . $action; | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |         $roleHasPermission = $role->hasPermission($permissionPrefix . '-all'); | 
					
						
							|  |  |  |         $roleHasPermissionOwn = $role->hasPermission($permissionPrefix . '-own'); | 
					
						
							| 
									
										
										
										
											2016-04-27 04:48:17 +08:00
										 |  |  |         $explodedAction = explode('-', $action); | 
					
						
							|  |  |  |         $restrictionAction = end($explodedAction); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 05:21:11 +08:00
										 |  |  |         if ($role->system_name === 'admin') { | 
					
						
							|  |  |  |             return $this->createJointPermissionDataArray($entity, $role, $action, true, true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |         if ($entity->isA('book')) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!$entity->restricted) { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |                 return $this->createJointPermissionDataArray($entity, $role, $action, $roleHasPermission, $roleHasPermissionOwn); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2016-04-27 04:48:17 +08:00
										 |  |  |                 $hasAccess = $entity->hasActiveRestriction($role->id, $restrictionAction); | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |                 return $this->createJointPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } elseif ($entity->isA('chapter')) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!$entity->restricted) { | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |                 $book = $this->getBook($entity->book_id); | 
					
						
							|  |  |  |                 $hasExplicitAccessToBook = $book->hasActiveRestriction($role->id, $restrictionAction); | 
					
						
							|  |  |  |                 $hasPermissiveAccessToBook = !$book->restricted; | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |                 return $this->createJointPermissionDataArray($entity, $role, $action, | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |                     ($hasExplicitAccessToBook || ($roleHasPermission && $hasPermissiveAccessToBook)), | 
					
						
							|  |  |  |                     ($hasExplicitAccessToBook || ($roleHasPermissionOwn && $hasPermissiveAccessToBook))); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2016-04-27 04:48:17 +08:00
										 |  |  |                 $hasAccess = $entity->hasActiveRestriction($role->id, $restrictionAction); | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |                 return $this->createJointPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } elseif ($entity->isA('page')) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!$entity->restricted) { | 
					
						
							| 
									
										
										
										
											2016-08-27 03:20:58 +08:00
										 |  |  |                 $book = $this->getBook($entity->book_id); | 
					
						
							|  |  |  |                 $hasExplicitAccessToBook = $book->hasActiveRestriction($role->id, $restrictionAction); | 
					
						
							|  |  |  |                 $hasPermissiveAccessToBook = !$book->restricted; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 $chapter = $this->getChapter($entity->chapter_id); | 
					
						
							|  |  |  |                 $hasExplicitAccessToChapter = $chapter && $chapter->hasActiveRestriction($role->id, $restrictionAction); | 
					
						
							|  |  |  |                 $hasPermissiveAccessToChapter = $chapter && !$chapter->restricted; | 
					
						
							|  |  |  |                 $acknowledgeChapter = ($chapter && $chapter->restricted); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 $hasExplicitAccessToParents = $acknowledgeChapter ? $hasExplicitAccessToChapter : $hasExplicitAccessToBook; | 
					
						
							|  |  |  |                 $hasPermissiveAccessToParents = $acknowledgeChapter ? $hasPermissiveAccessToChapter : $hasPermissiveAccessToBook; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |                 return $this->createJointPermissionDataArray($entity, $role, $action, | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |                     ($hasExplicitAccessToParents || ($roleHasPermission && $hasPermissiveAccessToParents)), | 
					
						
							|  |  |  |                     ($hasExplicitAccessToParents || ($roleHasPermissionOwn && $hasPermissiveAccessToParents)) | 
					
						
							|  |  |  |                 ); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |             } else { | 
					
						
							|  |  |  |                 $hasAccess = $entity->hasRestriction($role->id, $action); | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |                 return $this->createJointPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |      * Create an array of data with the information of an entity jointPermissions. | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |      * Used to build data for bulk insertion. | 
					
						
							|  |  |  |      * @param Entity $entity | 
					
						
							|  |  |  |      * @param Role $role | 
					
						
							|  |  |  |      * @param $action | 
					
						
							|  |  |  |      * @param $permissionAll | 
					
						
							|  |  |  |      * @param $permissionOwn | 
					
						
							|  |  |  |      * @return array | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     protected function createJointPermissionDataArray(Entity $entity, Role $role, $action, $permissionAll, $permissionOwn) | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $entityClass = get_class($entity); | 
					
						
							|  |  |  |         return [ | 
					
						
							| 
									
										
										
										
											2016-05-01 00:16:06 +08:00
										 |  |  |             'role_id'            => $role->getRawAttribute('id'), | 
					
						
							|  |  |  |             'entity_id'          => $entity->getRawAttribute('id'), | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |             'entity_type'        => $entityClass, | 
					
						
							|  |  |  |             'action'             => $action, | 
					
						
							|  |  |  |             'has_permission'     => $permissionAll, | 
					
						
							|  |  |  |             'has_permission_own' => $permissionOwn, | 
					
						
							| 
									
										
										
										
											2016-05-01 00:16:06 +08:00
										 |  |  |             'created_by'         => $entity->getRawAttribute('created_by') | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2016-03-01 04:31:21 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-06 02:09:21 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Checks if an entity has a restriction set upon it. | 
					
						
							| 
									
										
										
										
											2016-07-02 03:11:49 +08:00
										 |  |  |      * @param Ownable $ownable | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |      * @param $permission | 
					
						
							| 
									
										
										
										
											2016-03-06 02:09:21 +08:00
										 |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-07-02 03:11:49 +08:00
										 |  |  |     public function checkOwnableUserAccess(Ownable $ownable, $permission) | 
					
						
							| 
									
										
										
										
											2016-03-01 04:31:21 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         if ($this->isAdmin()) { | 
					
						
							|  |  |  |             $this->clean(); | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |         $explodedPermission = explode('-', $permission); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-02 03:11:49 +08:00
										 |  |  |         $baseQuery = $ownable->where('id', '=', $ownable->id); | 
					
						
							| 
									
										
										
										
											2016-04-27 04:48:17 +08:00
										 |  |  |         $action = end($explodedPermission); | 
					
						
							|  |  |  |         $this->currentAction = $action; | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         $nonJointPermissions = ['restrictions']; | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         // Handle non entity specific jointPermissions
 | 
					
						
							|  |  |  |         if (in_array($explodedPermission[0], $nonJointPermissions)) { | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |             $allPermission = $this->currentUser() && $this->currentUser()->can($permission . '-all'); | 
					
						
							|  |  |  |             $ownPermission = $this->currentUser() && $this->currentUser()->can($permission . '-own'); | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |             $this->currentAction = 'view'; | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |             $isOwner = $this->currentUser() && $this->currentUser()->id === $ownable->created_by; | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |             return ($allPermission || ($isOwner && $ownPermission)); | 
					
						
							| 
									
										
										
										
											2016-03-01 04:31:21 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         // Handle abnormal create jointPermissions
 | 
					
						
							| 
									
										
										
										
											2016-04-27 04:48:17 +08:00
										 |  |  |         if ($action === 'create') { | 
					
						
							|  |  |  |             $this->currentAction = $permission; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         $q = $this->entityRestrictionQuery($baseQuery)->count() > 0; | 
					
						
							|  |  |  |         $this->clean(); | 
					
						
							|  |  |  |         return $q; | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-31 03:15:44 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Check if an entity has restrictions set on itself or its | 
					
						
							|  |  |  |      * parent tree. | 
					
						
							|  |  |  |      * @param Entity $entity | 
					
						
							|  |  |  |      * @param $action | 
					
						
							|  |  |  |      * @return bool|mixed | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function checkIfRestrictionsSet(Entity $entity, $action) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->currentAction = $action; | 
					
						
							|  |  |  |         if ($entity->isA('page')) { | 
					
						
							|  |  |  |             return $entity->restricted || ($entity->chapter && $entity->chapter->restricted) || $entity->book->restricted; | 
					
						
							|  |  |  |         } elseif ($entity->isA('chapter')) { | 
					
						
							|  |  |  |             return $entity->restricted || $entity->book->restricted; | 
					
						
							|  |  |  |         } elseif ($entity->isA('book')) { | 
					
						
							|  |  |  |             return $entity->restricted; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |      * The general query filter to remove all entities | 
					
						
							|  |  |  |      * that the current user does not have access to. | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |      * @param $query | 
					
						
							|  |  |  |      * @return mixed | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |     protected function entityRestrictionQuery($query) | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         $q = $query->where(function ($parentQuery) { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |             $parentQuery->whereHas('jointPermissions', function ($permissionQuery) { | 
					
						
							| 
									
										
										
										
											2016-05-02 02:36:53 +08:00
										 |  |  |                 $permissionQuery->whereIn('role_id', $this->getRoles()) | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                     ->where('action', '=', $this->currentAction) | 
					
						
							|  |  |  |                     ->where(function ($query) { | 
					
						
							|  |  |  |                         $query->where('has_permission', '=', true) | 
					
						
							|  |  |  |                             ->orWhere(function ($query) { | 
					
						
							|  |  |  |                                 $query->where('has_permission_own', '=', true) | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |                                     ->where('created_by', '=', $this->currentUser()->id); | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |                             }); | 
					
						
							|  |  |  |                     }); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         $this->clean(); | 
					
						
							|  |  |  |         return $q; | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-02 05:21:11 +08:00
										 |  |  |     public function bookChildrenQuery($book_id, $filterDrafts = false) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Draft setup
 | 
					
						
							|  |  |  |         $params = [ | 
					
						
							|  |  |  |             'userId' => $this->currentUser()->id, | 
					
						
							|  |  |  |             'bookIdPage' => $book_id, | 
					
						
							|  |  |  |             'bookIdChapter' => $book_id | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  |         if (!$filterDrafts) { | 
					
						
							|  |  |  |             $params['userIdDrafts'] = $this->currentUser()->id; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // Role setup
 | 
					
						
							|  |  |  |         $userRoles = $this->getRoles(); | 
					
						
							|  |  |  |         $roleBindings = []; | 
					
						
							|  |  |  |         $roleValues = []; | 
					
						
							|  |  |  |         foreach ($userRoles as $index => $roleId) { | 
					
						
							|  |  |  |             $roleBindings[':role'.$index] = $roleId; | 
					
						
							|  |  |  |             $roleValues['role'.$index] = $roleId; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // TODO - Clean this up, Maybe extract into a nice class for doing these kind of manual things
 | 
					
						
							|  |  |  |         // Something which will handle the above role crap in a nice clean way
 | 
					
						
							|  |  |  |         $roleBindingString = implode(',', array_keys($roleBindings)); | 
					
						
							|  |  |  |         $query = "SELECT * from (
 | 
					
						
							|  |  |  | (SELECT 'Bookstack\\\Page' as entity_type, id, slug, name, text, '' as description, book_id, priority, chapter_id, draft FROM {$this->page->getTable()} | 
					
						
							|  |  |  |     where book_id = :bookIdPage AND ". ($filterDrafts ? '(draft = 0)' : '(draft = 0 OR (draft = 1 AND created_by = :userIdDrafts))') .") | 
					
						
							|  |  |  | UNION | 
					
						
							|  |  |  | (SELECT 'Bookstack\\\Chapter' as entity_type, id, slug, name, '' as text, description, book_id, priority, 0 as chapter_id, 0 as draft FROM {$this->chapter->getTable()} WHERE book_id = :bookIdChapter) | 
					
						
							|  |  |  | ) as U  WHERE ( | 
					
						
							|  |  |  | 	SELECT COUNT(*) FROM {$this->jointPermission->getTable()} jp | 
					
						
							|  |  |  |     WHERE | 
					
						
							|  |  |  | 		jp.entity_id=U.id AND | 
					
						
							|  |  |  |         jp.entity_type=U.entity_type AND | 
					
						
							|  |  |  | 		jp.action = 'view' AND | 
					
						
							|  |  |  |         jp.role_id IN ({$roleBindingString}) AND | 
					
						
							|  |  |  |         ( | 
					
						
							|  |  |  | 			jp.has_permission = 1 OR | 
					
						
							|  |  |  |             (jp.has_permission_own = 1 AND jp.created_by = :userId) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | ) > 0 | 
					
						
							|  |  |  | ORDER BY draft desc, priority asc";
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->clean(); | 
					
						
							|  |  |  |         return $this->db->select($query, array_replace($roleValues, $params)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 03:33:08 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Add restrictions for a generic entity | 
					
						
							| 
									
										
										
										
											2017-01-02 00:05:44 +08:00
										 |  |  |      * @param string $entityType | 
					
						
							|  |  |  |      * @param Builder|Entity $query | 
					
						
							| 
									
										
										
										
											2016-05-07 03:33:08 +08:00
										 |  |  |      * @param string $action | 
					
						
							|  |  |  |      * @return mixed | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-01-02 00:05:44 +08:00
										 |  |  |     public function enforceEntityRestrictions($entityType, $query, $action = 'view') | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-01-02 00:05:44 +08:00
										 |  |  |         if (strtolower($entityType) === 'page') { | 
					
						
							|  |  |  |             // Prevent drafts being visible to others.
 | 
					
						
							|  |  |  |             $query = $query->where(function ($query) { | 
					
						
							|  |  |  |                 $query->where('draft', '=', false); | 
					
						
							|  |  |  |                 if ($this->currentUser()) { | 
					
						
							|  |  |  |                     $query->orWhere(function ($query) { | 
					
						
							|  |  |  |                         $query->where('draft', '=', true)->where('created_by', '=', $this->currentUser()->id); | 
					
						
							|  |  |  |                     }); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         if ($this->isAdmin()) { | 
					
						
							|  |  |  |             $this->clean(); | 
					
						
							|  |  |  |             return $query; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-01-02 00:05:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |         $this->currentAction = $action; | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |         return $this->entityRestrictionQuery($query); | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Filter items that have entities set a a polymorphic relation. | 
					
						
							|  |  |  |      * @param $query | 
					
						
							|  |  |  |      * @param string $tableName | 
					
						
							|  |  |  |      * @param string $entityIdColumn | 
					
						
							|  |  |  |      * @param string $entityTypeColumn | 
					
						
							|  |  |  |      * @return mixed | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function filterRestrictedEntityRelations($query, $tableName, $entityIdColumn, $entityTypeColumn) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         if ($this->isAdmin()) { | 
					
						
							|  |  |  |             $this->clean(); | 
					
						
							|  |  |  |             return $query; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |         $this->currentAction = 'view'; | 
					
						
							|  |  |  |         $tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn]; | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         $q = $query->where(function ($query) use ($tableDetails) { | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |             $query->whereExists(function ($permissionQuery) use (&$tableDetails) { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |                 $permissionQuery->select('id')->from('joint_permissions') | 
					
						
							|  |  |  |                     ->whereRaw('joint_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn']) | 
					
						
							|  |  |  |                     ->whereRaw('joint_permissions.entity_type=' . $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn']) | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                     ->where('action', '=', $this->currentAction) | 
					
						
							| 
									
										
										
										
											2016-05-02 02:36:53 +08:00
										 |  |  |                     ->whereIn('role_id', $this->getRoles()) | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                     ->where(function ($query) { | 
					
						
							|  |  |  |                         $query->where('has_permission', '=', true)->orWhere(function ($query) { | 
					
						
							|  |  |  |                             $query->where('has_permission_own', '=', true) | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |                                 ->where('created_by', '=', $this->currentUser()->id); | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |                         }); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                     }); | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |             }); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         return $q; | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-13 21:30:47 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Filters pages that are a direct relation to another item. | 
					
						
							|  |  |  |      * @param $query | 
					
						
							|  |  |  |      * @param $tableName | 
					
						
							|  |  |  |      * @param $entityIdColumn | 
					
						
							|  |  |  |      * @return mixed | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function filterRelatedPages($query, $tableName, $entityIdColumn) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         if ($this->isAdmin()) { | 
					
						
							|  |  |  |             $this->clean(); | 
					
						
							|  |  |  |             return $query; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-13 21:30:47 +08:00
										 |  |  |         $this->currentAction = 'view'; | 
					
						
							|  |  |  |         $tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn]; | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         $q = $query->where(function ($query) use ($tableDetails) { | 
					
						
							| 
									
										
										
										
											2016-03-13 21:30:47 +08:00
										 |  |  |             $query->where(function ($query) use (&$tableDetails) { | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                 $query->whereExists(function ($permissionQuery) use (&$tableDetails) { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |                     $permissionQuery->select('id')->from('joint_permissions') | 
					
						
							|  |  |  |                         ->whereRaw('joint_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn']) | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                         ->where('entity_type', '=', 'Bookstack\\Page') | 
					
						
							|  |  |  |                         ->where('action', '=', $this->currentAction) | 
					
						
							| 
									
										
										
										
											2016-05-02 02:36:53 +08:00
										 |  |  |                         ->whereIn('role_id', $this->getRoles()) | 
					
						
							| 
									
										
										
										
											2016-03-13 21:30:47 +08:00
										 |  |  |                         ->where(function ($query) { | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                             $query->where('has_permission', '=', true)->orWhere(function ($query) { | 
					
						
							|  |  |  |                                 $query->where('has_permission_own', '=', true) | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |                                     ->where('created_by', '=', $this->currentUser()->id); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                             }); | 
					
						
							| 
									
										
										
										
											2016-03-13 21:30:47 +08:00
										 |  |  |                         }); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |                 }); | 
					
						
							|  |  |  |             })->orWhere($tableDetails['entityIdColumn'], '=', 0); | 
					
						
							| 
									
										
										
										
											2016-03-13 21:30:47 +08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         $this->clean(); | 
					
						
							|  |  |  |         return $q; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Check if the current user is an admin. | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function isAdmin() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($this->isAdminUser === null) { | 
					
						
							| 
									
										
										
										
											2017-01-02 05:21:11 +08:00
										 |  |  |             $this->isAdminUser = ($this->currentUser()->id !== null) ? $this->currentUser()->hasSystemRole('admin') : false; | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this->isAdminUser; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the current user | 
					
						
							|  |  |  |      * @return User | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function currentUser() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($this->currentUserModel === false) { | 
					
						
							| 
									
										
										
										
											2016-09-29 19:43:46 +08:00
										 |  |  |             $this->currentUserModel = user(); | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this->currentUserModel; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Clean the cached user elements. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function clean() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->currentUserModel = false; | 
					
						
							|  |  |  |         $this->userRoles = false; | 
					
						
							|  |  |  |         $this->isAdminUser = null; | 
					
						
							| 
									
										
										
										
											2016-03-13 21:30:47 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 03:03:04 +08:00
										 |  |  | } |