]> BookStack Code Mirror - bookstack/blob - app/Entities/Tools/PermissionsUpdater.php
Aligned logic to entity_permission role_id usage change
[bookstack] / app / Entities / Tools / PermissionsUpdater.php
1 <?php
2
3 namespace BookStack\Entities\Tools;
4
5 use BookStack\Actions\ActivityType;
6 use BookStack\Auth\Permissions\EntityPermission;
7 use BookStack\Auth\User;
8 use BookStack\Entities\Models\Book;
9 use BookStack\Entities\Models\Bookshelf;
10 use BookStack\Entities\Models\Entity;
11 use BookStack\Facades\Activity;
12 use Illuminate\Http\Request;
13 use Illuminate\Support\Collection;
14
15 class PermissionsUpdater
16 {
17     /**
18      * Update an entities permissions from a permission form submit request.
19      */
20     public function updateFromPermissionsForm(Entity $entity, Request $request)
21     {
22         $permissions = $request->get('permissions', null);
23         $ownerId = $request->get('owned_by', null);
24
25         $entity->permissions()->delete();
26
27         if (!is_null($permissions)) {
28             $entityPermissionData = $this->formatPermissionsFromRequestToEntityPermissions($permissions);
29             $entity->permissions()->createMany($entityPermissionData);
30         }
31
32         if (!is_null($ownerId)) {
33             $this->updateOwnerFromId($entity, intval($ownerId));
34         }
35
36         $entity->save();
37         $entity->rebuildPermissions();
38
39         Activity::add(ActivityType::PERMISSIONS_UPDATE, $entity);
40     }
41
42     /**
43      * Update the owner of the given entity.
44      * Checks the user exists in the system first.
45      * Does not save the model, just updates it.
46      */
47     protected function updateOwnerFromId(Entity $entity, int $newOwnerId)
48     {
49         $newOwner = User::query()->find($newOwnerId);
50         if (!is_null($newOwner)) {
51             $entity->owned_by = $newOwner->id;
52         }
53     }
54
55     /**
56      * Format permissions provided from a permission form to be EntityPermission data.
57      */
58     protected function formatPermissionsFromRequestToEntityPermissions(array $permissions): array
59     {
60         $formatted = [];
61         $columnsByType = [
62             'role' => 'role_id',
63             'user' => 'user_id',
64             'fallback' => '',
65         ];
66
67         foreach ($permissions as $type => $byId) {
68             $column  = $columnsByType[$type] ?? null;
69             if (is_null($column)) {
70                 continue;
71             }
72
73             foreach ($byId as $id => $info) {
74                 $entityPermissionData = [];
75
76                 if (!empty($column)) {
77                     $entityPermissionData[$column] = $id;
78                 }
79
80                 foreach (EntityPermission::PERMISSIONS as $permission) {
81                     $entityPermissionData[$permission] = (($info[$permission] ?? false) === "true");
82                 }
83                 $formatted[] = $entityPermissionData;
84             }
85         }
86
87         return $formatted;
88     }
89
90     /**
91      * Copy down the permissions of the given shelf to all child books.
92      */
93     public function updateBookPermissionsFromShelf(Bookshelf $shelf, $checkUserPermissions = true): int
94     {
95         $shelfPermissions = $shelf->permissions()->get(['role_id', 'view', 'create', 'update', 'delete'])->toArray();
96         $shelfBooks = $shelf->books()->get(['id', 'owned_by']);
97         $updatedBookCount = 0;
98
99         /** @var Book $book */
100         foreach ($shelfBooks as $book) {
101             if ($checkUserPermissions && !userCan('restrictions-manage', $book)) {
102                 continue;
103             }
104             $book->permissions()->delete();
105             $book->permissions()->createMany($shelfPermissions);
106             $book->rebuildPermissions();
107             $updatedBookCount++;
108         }
109
110         return $updatedBookCount;
111     }
112 }