]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/Api/ContentPermissionsController.php
Started build of content-permissions API endpoints
[bookstack] / app / Http / Controllers / Api / ContentPermissionsController.php
1 <?php
2
3 namespace BookStack\Http\Controllers\Api;
4
5 use BookStack\Entities\EntityProvider;
6 use BookStack\Entities\Models\Entity;
7 use BookStack\Entities\Tools\PermissionsUpdater;
8 use Illuminate\Http\Request;
9
10 class ContentPermissionsController extends ApiController
11 {
12     public function __construct(
13         protected PermissionsUpdater $permissionsUpdater,
14         protected EntityProvider $entities
15     ) {
16     }
17
18     protected $rules = [
19         'update' => [
20             'owner_id'  => ['int'],
21
22             'override_role_permissions' => ['array'],
23             'override_role_permissions.*.role_id' => ['required', 'int'],
24             'override_role_permissions.*.view' => ['required', 'boolean'],
25             'override_role_permissions.*.create' => ['required', 'boolean'],
26             'override_role_permissions.*.update' => ['required', 'boolean'],
27             'override_role_permissions.*.delete' => ['required', 'boolean'],
28
29             'override_fallback_permissions' => ['nullable'],
30             'override_fallback_permissions.view' => ['required', 'boolean'],
31             'override_fallback_permissions.create' => ['required', 'boolean'],
32             'override_fallback_permissions.update' => ['required', 'boolean'],
33             'override_fallback_permissions.delete' => ['required', 'boolean'],
34         ]
35     ];
36
37     /**
38      * Read the configured content-level permissions for the item of the given type and ID.
39      * 'contentType' should be one of: page, book, chapter, bookshelf.
40      * 'contentId' should be the relevant ID of that item type you'd like to handle permissions for.
41      */
42     public function read(string $contentType, string $contentId)
43     {
44         $entity = $this->entities->get($contentType)
45             ->newQuery()->scopes(['visible'])->findOrFail($contentId);
46
47         $this->checkOwnablePermission('restrictions-manage', $entity);
48
49         return response()->json($this->formattedPermissionDataForEntity($entity));
50     }
51
52     /**
53      * Update the configured content-level permissions for the item of the given type and ID.
54      * 'contentType' should be one of: page, book, chapter, bookshelf.
55      * 'contentId' should be the relevant ID of that item type you'd like to handle permissions for.
56      */
57     public function update(Request $request, string $contentType, string $contentId)
58     {
59         $entity = $this->entities->get($contentType)
60             ->newQuery()->scopes(['visible'])->findOrFail($contentId);
61
62         $this->checkOwnablePermission('restrictions-manage', $entity);
63
64         $data = $this->validate($request, $this->rules()['update']);
65         $this->permissionsUpdater->updateFromApiRequestData($entity, $data);
66
67         return response()->json($this->formattedPermissionDataForEntity($entity));
68     }
69
70     protected function formattedPermissionDataForEntity(Entity $entity): array
71     {
72         $rolePermissions = $entity->permissions()
73             ->where('role_id', '!=', 0)
74             ->with(['role:id,display_name'])
75             ->get();
76
77         $fallback = $entity->permissions()->where('role_id', '=', 0)->first();
78         $fallback?->makeHidden('role_id');
79
80         return [
81             'owner' => $entity->ownedBy()->first(),
82             'override_role_permissions' => $rolePermissions,
83             'override_fallback_permissions' => $fallback,
84             'inheriting' => is_null($fallback),
85         ];
86     }
87 }