+<?php
+
+namespace BookStack\Http\Controllers\Api;
+
+use BookStack\Entities\EntityProvider;
+use BookStack\Entities\Models\Entity;
+use BookStack\Entities\Tools\PermissionsUpdater;
+use Illuminate\Http\Request;
+
+class ContentPermissionsController extends ApiController
+{
+ public function __construct(
+ protected PermissionsUpdater $permissionsUpdater,
+ protected EntityProvider $entities
+ ) {
+ }
+
+ protected $rules = [
+ 'update' => [
+ 'owner_id' => ['int'],
+
+ 'override_role_permissions' => ['array'],
+ 'override_role_permissions.*.role_id' => ['required', 'int'],
+ 'override_role_permissions.*.view' => ['required', 'boolean'],
+ 'override_role_permissions.*.create' => ['required', 'boolean'],
+ 'override_role_permissions.*.update' => ['required', 'boolean'],
+ 'override_role_permissions.*.delete' => ['required', 'boolean'],
+
+ 'override_fallback_permissions' => ['nullable'],
+ 'override_fallback_permissions.view' => ['required', 'boolean'],
+ 'override_fallback_permissions.create' => ['required', 'boolean'],
+ 'override_fallback_permissions.update' => ['required', 'boolean'],
+ 'override_fallback_permissions.delete' => ['required', 'boolean'],
+ ]
+ ];
+
+ /**
+ * Read the configured content-level permissions for the item of the given type and ID.
+ * '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.
+ */
+ 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));
+ }
+
+ /**
+ * Update the configured content-level permissions for the item of the given type and ID.
+ * '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.
+ */
+ 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();
+ $fallback?->makeHidden('role_id');
+
+ return [
+ 'owner' => $entity->ownedBy()->first(),
+ 'override_role_permissions' => $rolePermissions,
+ 'override_fallback_permissions' => $fallback,
+ 'inheriting' => is_null($fallback),
+ ];
+ }
+}