3 namespace BookStack\Auth\Permissions;
5 class MassEntityPermissionEvaluator extends EntityPermissionEvaluator
8 * @var SimpleEntityData[]
10 protected array $entitiesInvolved;
11 protected array $permissionMapCache;
13 public function __construct(array $entitiesInvolved, string $action)
15 $this->entitiesInvolved = $entitiesInvolved;
16 parent::__construct($action);
19 public function evaluateEntityForRole(SimpleEntityData $entity, int $roleId): ?bool
21 $typeIdChain = $this->gatherEntityChainTypeIds($entity);
22 $relevantPermissions = $this->getPermissionMapByTypeIdForChainAndRole($typeIdChain, $roleId);
23 $permitsByType = $this->collapseAndCategorisePermissions($typeIdChain, $relevantPermissions);
25 return $this->evaluatePermitsByType($permitsByType);
29 * @param string[] $typeIdChain
30 * @return array<string, EntityPermission[]>
32 protected function getPermissionMapByTypeIdForChainAndRole(array $typeIdChain, int $roleId): array
34 $allPermissions = $this->getPermissionMapByTypeIdAndRoleForAllInvolved();
35 $relevantPermissions = [];
37 // Filter down permissions to just those for current typeId
38 // and current roleID or fallback permissions.
39 foreach ($typeIdChain as $typeId) {
40 $relevantPermissions[$typeId] = [
41 ...($allPermissions[$typeId][$roleId] ?? []),
42 ...($allPermissions[$typeId][0] ?? [])
46 return $relevantPermissions;
50 * @return array<string, array<int, EntityPermission[]>>
52 protected function getPermissionMapByTypeIdAndRoleForAllInvolved(): array
54 if (isset($this->permissionMapCache)) {
55 return $this->permissionMapCache;
58 $entityTypeIdChain = [];
59 foreach ($this->entitiesInvolved as $entity) {
60 $entityTypeIdChain[] = $entity->type . ':' . $entity->id;
63 $permissionMap = $this->getPermissionsMapByTypeId($entityTypeIdChain, []);
65 // Manipulate permission map to also be keyed by roleId.
66 foreach ($permissionMap as $typeId => $permissions) {
67 $permissionMap[$typeId] = [];
68 foreach ($permissions as $permission) {
69 $roleId = $permission->getRawAttribute('role_id');
70 if (!isset($permissionMap[$typeId][$roleId])) {
71 $permissionMap[$typeId][$roleId] = [];
73 $permissionMap[$typeId][$roleId][] = $permission;
77 $this->permissionMapCache = $permissionMap;
79 return $this->permissionMapCache;