]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/Api/ContentPermissionsController.php
Updated php deps
[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             'role_permissions' => ['array'],
23             'role_permissions.*.role_id' => ['required', 'int', 'exists:roles,id'],
24             'role_permissions.*.view' => ['required', 'boolean'],
25             'role_permissions.*.create' => ['required', 'boolean'],
26             'role_permissions.*.update' => ['required', 'boolean'],
27             'role_permissions.*.delete' => ['required', 'boolean'],
28
29             'fallback_permissions' => ['nullable'],
30             'fallback_permissions.inheriting' => ['required_with:fallback_permissions', 'boolean'],
31             'fallback_permissions.view' => ['required_if:fallback_permissions.inheriting,false', 'boolean'],
32             'fallback_permissions.create' => ['required_if:fallback_permissions.inheriting,false', 'boolean'],
33             'fallback_permissions.update' => ['required_if:fallback_permissions.inheriting,false', 'boolean'],
34             'fallback_permissions.delete' => ['required_if:fallback_permissions.inheriting,false', 'boolean'],
35         ]
36     ];
37
38     /**
39      * Read the configured content-level permissions for the item of the given type and ID.
40      * 'contentType' should be one of: page, book, chapter, bookshelf.
41      * 'contentId' should be the relevant ID of that item type you'd like to handle permissions for.
42      * The permissions shown are those that override the default for just the specified item, they do not show the
43      * full evaluated permission for a role, nor do they reflect permissions inherited from other items in the hierarchy.
44      * Fallback permission values may be `null` when inheriting is active.
45      */
46     public function read(string $contentType, string $contentId)
47     {
48         $entity = $this->entities->get($contentType)
49             ->newQuery()->scopes(['visible'])->findOrFail($contentId);
50
51         $this->checkOwnablePermission('restrictions-manage', $entity);
52
53         return response()->json($this->formattedPermissionDataForEntity($entity));
54     }
55
56     /**
57      * Update the configured content-level permission overrides for the item of the given type and ID.
58      * 'contentType' should be one of: page, book, chapter, bookshelf.
59      * 'contentId' should be the relevant ID of that item type you'd like to handle permissions for.
60      * Providing an empty `role_permissions` array will remove any existing configured role permissions,
61      * so you may want to fetch existing permissions beforehand if just adding/removing a single item.
62      * You should completely omit the `owner_id`, `role_permissions` and/or the `fallback_permissions` properties
63      * from your request data if you don't wish to update details within those categories.
64      */
65     public function update(Request $request, string $contentType, string $contentId)
66     {
67         $entity = $this->entities->get($contentType)
68             ->newQuery()->scopes(['visible'])->findOrFail($contentId);
69
70         $this->checkOwnablePermission('restrictions-manage', $entity);
71
72         $data = $this->validate($request, $this->rules()['update']);
73         $this->permissionsUpdater->updateFromApiRequestData($entity, $data);
74
75         return response()->json($this->formattedPermissionDataForEntity($entity));
76     }
77
78     protected function formattedPermissionDataForEntity(Entity $entity): array
79     {
80         $rolePermissions = $entity->permissions()
81             ->where('role_id', '!=', 0)
82             ->with(['role:id,display_name'])
83             ->get();
84
85         $fallback = $entity->permissions()->where('role_id', '=', 0)->first();
86         $fallbackData = [
87             'inheriting' => is_null($fallback),
88             'view' => $fallback->view ?? null,
89             'create' => $fallback->create ?? null,
90             'update' => $fallback->update ?? null,
91             'delete' => $fallback->delete ?? null,
92         ];
93
94         return [
95             'owner' => $entity->ownedBy()->first(),
96             'role_permissions' => $rolePermissions,
97             'fallback_permissions' => $fallbackData,
98         ];
99     }
100 }