| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | namespace BookStack\Permissions; | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | use BookStack\Entities\EntityProvider; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Entity; | 
					
						
							|  |  |  | use BookStack\Entities\Tools\PermissionsUpdater; | 
					
						
							| 
									
										
										
										
											2023-05-19 03:53:39 +08:00
										 |  |  | use BookStack\Http\ApiController; | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  | use Illuminate\Http\Request; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-14 20:19:19 +08:00
										 |  |  | class ContentPermissionApiController extends ApiController | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     public function __construct( | 
					
						
							|  |  |  |         protected PermissionsUpdater $permissionsUpdater, | 
					
						
							|  |  |  |         protected EntityProvider $entities | 
					
						
							|  |  |  |     ) { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected $rules = [ | 
					
						
							|  |  |  |         'update' => [ | 
					
						
							|  |  |  |             'owner_id'  => ['int'], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-14 04:06:52 +08:00
										 |  |  |             'role_permissions' => ['array'], | 
					
						
							|  |  |  |             'role_permissions.*.role_id' => ['required', 'int', 'exists:roles,id'], | 
					
						
							|  |  |  |             'role_permissions.*.view' => ['required', 'boolean'], | 
					
						
							|  |  |  |             'role_permissions.*.create' => ['required', 'boolean'], | 
					
						
							|  |  |  |             'role_permissions.*.update' => ['required', 'boolean'], | 
					
						
							|  |  |  |             'role_permissions.*.delete' => ['required', 'boolean'], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             'fallback_permissions' => ['nullable'], | 
					
						
							|  |  |  |             'fallback_permissions.inheriting' => ['required_with:fallback_permissions', 'boolean'], | 
					
						
							|  |  |  |             'fallback_permissions.view' => ['required_if:fallback_permissions.inheriting,false', 'boolean'], | 
					
						
							|  |  |  |             'fallback_permissions.create' => ['required_if:fallback_permissions.inheriting,false', 'boolean'], | 
					
						
							|  |  |  |             'fallback_permissions.update' => ['required_if:fallback_permissions.inheriting,false', 'boolean'], | 
					
						
							|  |  |  |             'fallback_permissions.delete' => ['required_if:fallback_permissions.inheriting,false', 'boolean'], | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  |         ] | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Read the configured content-level permissions for the item of the given type and ID. | 
					
						
							| 
									
										
										
										
											2023-06-21 06:44:39 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  |      * 'contentType' should be one of: page, book, chapter, bookshelf. | 
					
						
							|  |  |  |      * 'contentId' should be the relevant ID of that item type you'd like to handle permissions for. | 
					
						
							| 
									
										
										
										
											2023-06-21 06:44:39 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-03-14 04:06:52 +08:00
										 |  |  |      * The permissions shown are those that override the default for just the specified item, they do not show the | 
					
						
							|  |  |  |      * full evaluated permission for a role, nor do they reflect permissions inherited from other items in the hierarchy. | 
					
						
							|  |  |  |      * Fallback permission values may be `null` when inheriting is active. | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function read(string $contentType, string $contentId) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $entity = $this->entities->get($contentType) | 
					
						
							|  |  |  |             ->newQuery()->scopes(['visible'])->findOrFail($contentId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->checkOwnablePermission('restrictions-manage', $entity); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return response()->json($this->formattedPermissionDataForEntity($entity)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-03-14 04:41:32 +08:00
										 |  |  |      * Update the configured content-level permission overrides for the item of the given type and ID. | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  |      * 'contentType' should be one of: page, book, chapter, bookshelf. | 
					
						
							| 
									
										
										
										
											2023-06-21 06:44:39 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  |      * 'contentId' should be the relevant ID of that item type you'd like to handle permissions for. | 
					
						
							| 
									
										
										
										
											2023-03-14 04:06:52 +08:00
										 |  |  |      * Providing an empty `role_permissions` array will remove any existing configured role permissions, | 
					
						
							|  |  |  |      * so you may want to fetch existing permissions beforehand if just adding/removing a single item. | 
					
						
							|  |  |  |      * You should completely omit the `owner_id`, `role_permissions` and/or the `fallback_permissions` properties | 
					
						
							| 
									
										
										
										
											2023-03-14 04:41:32 +08:00
										 |  |  |      * from your request data if you don't wish to update details within those categories. | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function update(Request $request, string $contentType, string $contentId) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $entity = $this->entities->get($contentType) | 
					
						
							|  |  |  |             ->newQuery()->scopes(['visible'])->findOrFail($contentId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->checkOwnablePermission('restrictions-manage', $entity); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $data = $this->validate($request, $this->rules()['update']); | 
					
						
							|  |  |  |         $this->permissionsUpdater->updateFromApiRequestData($entity, $data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return response()->json($this->formattedPermissionDataForEntity($entity)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function formattedPermissionDataForEntity(Entity $entity): array | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $rolePermissions = $entity->permissions() | 
					
						
							|  |  |  |             ->where('role_id', '!=', 0) | 
					
						
							|  |  |  |             ->with(['role:id,display_name']) | 
					
						
							|  |  |  |             ->get(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $fallback = $entity->permissions()->where('role_id', '=', 0)->first(); | 
					
						
							| 
									
										
										
										
											2023-03-14 04:06:52 +08:00
										 |  |  |         $fallbackData = [ | 
					
						
							|  |  |  |             'inheriting' => is_null($fallback), | 
					
						
							|  |  |  |             'view' => $fallback->view ?? null, | 
					
						
							|  |  |  |             'create' => $fallback->create ?? null, | 
					
						
							|  |  |  |             'update' => $fallback->update ?? null, | 
					
						
							|  |  |  |             'delete' => $fallback->delete ?? null, | 
					
						
							|  |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return [ | 
					
						
							|  |  |  |             'owner' => $entity->ownedBy()->first(), | 
					
						
							| 
									
										
										
										
											2023-03-14 04:06:52 +08:00
										 |  |  |             'role_permissions' => $rolePermissions, | 
					
						
							|  |  |  |             'fallback_permissions' => $fallbackData, | 
					
						
							| 
									
										
										
										
											2023-03-13 21:18:33 +08:00
										 |  |  |         ]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |