mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-05-06 17:20:07 +00:00
Updated joint perms. gen. to use new entity permission format
This commit is contained in:
parent
aee0e16194
commit
3839bf6bf1
2 changed files with 23 additions and 24 deletions
app/Auth/Permissions
|
@ -40,7 +40,7 @@ class JointPermissionBuilder
|
||||||
});
|
});
|
||||||
|
|
||||||
// Chunk through all bookshelves
|
// Chunk through all bookshelves
|
||||||
Bookshelf::query()->withTrashed()->select(['id', 'restricted', 'owned_by'])
|
Bookshelf::query()->withTrashed()->select(['id', 'owned_by'])
|
||||||
->chunk(50, function (EloquentCollection $shelves) use ($roles) {
|
->chunk(50, function (EloquentCollection $shelves) use ($roles) {
|
||||||
$this->createManyJointPermissions($shelves->all(), $roles);
|
$this->createManyJointPermissions($shelves->all(), $roles);
|
||||||
});
|
});
|
||||||
|
@ -92,7 +92,7 @@ class JointPermissionBuilder
|
||||||
});
|
});
|
||||||
|
|
||||||
// Chunk through all bookshelves
|
// Chunk through all bookshelves
|
||||||
Bookshelf::query()->select(['id', 'restricted', 'owned_by'])
|
Bookshelf::query()->select(['id', 'owned_by'])
|
||||||
->chunk(50, function ($shelves) use ($roles) {
|
->chunk(50, function ($shelves) use ($roles) {
|
||||||
$this->createManyJointPermissions($shelves->all(), $roles);
|
$this->createManyJointPermissions($shelves->all(), $roles);
|
||||||
});
|
});
|
||||||
|
@ -138,12 +138,11 @@ class JointPermissionBuilder
|
||||||
protected function bookFetchQuery(): Builder
|
protected function bookFetchQuery(): Builder
|
||||||
{
|
{
|
||||||
return Book::query()->withTrashed()
|
return Book::query()->withTrashed()
|
||||||
->select(['id', 'restricted', 'owned_by'])->with([
|
->select(['id', 'owned_by'])->with([
|
||||||
'chapters' => function ($query) {
|
'chapters' => function ($query) {
|
||||||
$query->withTrashed()->select(['id', 'restricted', 'owned_by', 'book_id']);
|
|
||||||
},
|
},
|
||||||
'pages' => function ($query) {
|
'pages' => function ($query) {
|
||||||
$query->withTrashed()->select(['id', 'restricted', 'owned_by', 'book_id', 'chapter_id']);
|
$query->withTrashed()->select(['id', 'owned_by', 'book_id', 'chapter_id']);
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -218,7 +217,6 @@ class JointPermissionBuilder
|
||||||
$simple = new SimpleEntityData();
|
$simple = new SimpleEntityData();
|
||||||
$simple->id = $attrs['id'];
|
$simple->id = $attrs['id'];
|
||||||
$simple->type = $entity->getMorphClass();
|
$simple->type = $entity->getMorphClass();
|
||||||
$simple->restricted = boolval($attrs['restricted'] ?? 0);
|
|
||||||
$simple->owned_by = $attrs['owned_by'] ?? 0;
|
$simple->owned_by = $attrs['owned_by'] ?? 0;
|
||||||
$simple->book_id = $attrs['book_id'] ?? null;
|
$simple->book_id = $attrs['book_id'] ?? null;
|
||||||
$simple->chapter_id = $attrs['chapter_id'] ?? null;
|
$simple->chapter_id = $attrs['chapter_id'] ?? null;
|
||||||
|
@ -240,24 +238,14 @@ class JointPermissionBuilder
|
||||||
$this->readyEntityCache($entities);
|
$this->readyEntityCache($entities);
|
||||||
$jointPermissions = [];
|
$jointPermissions = [];
|
||||||
|
|
||||||
// Create a mapping of entity restricted statuses
|
|
||||||
$entityRestrictedMap = [];
|
|
||||||
foreach ($entities as $entity) {
|
|
||||||
$entityRestrictedMap[$entity->type . ':' . $entity->id] = $entity->restricted;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch related entity permissions
|
// Fetch related entity permissions
|
||||||
$permissions = $this->getEntityPermissionsForEntities($entities);
|
$permissions = $this->getEntityPermissionsForEntities($entities);
|
||||||
|
|
||||||
// Create a mapping of explicit entity permissions
|
// Create a mapping of explicit entity permissions
|
||||||
// TODO - Handle new format, Now getting all defined entity permissions
|
|
||||||
// from the above call, Need to handle entries with none, and the 'Other Roles' (role_id=0)
|
|
||||||
// fallback option.
|
|
||||||
$permissionMap = [];
|
$permissionMap = [];
|
||||||
foreach ($permissions as $permission) {
|
foreach ($permissions as $permission) {
|
||||||
$key = $permission->entity_type . ':' . $permission->entity_id . ':' . $permission->role_id;
|
$key = $permission->entity_type . ':' . $permission->entity_id . ':' . $permission->role_id;
|
||||||
$isRestricted = $entityRestrictedMap[$permission->entity_type . ':' . $permission->entity_id];
|
$permissionMap[$key] = $permission->view;
|
||||||
$permissionMap[$key] = $isRestricted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a mapping of role permissions
|
// Create a mapping of role permissions
|
||||||
|
@ -347,7 +335,7 @@ class JointPermissionBuilder
|
||||||
return $this->createJointPermissionDataArray($entity, $roleId, true, true);
|
return $this->createJointPermissionDataArray($entity, $roleId, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($entity->restricted) {
|
if ($this->entityPermissionsActiveForRole($permissionMap, $entity, $roleId)) {
|
||||||
$hasAccess = $this->mapHasActiveRestriction($permissionMap, $entity, $roleId);
|
$hasAccess = $this->mapHasActiveRestriction($permissionMap, $entity, $roleId);
|
||||||
|
|
||||||
return $this->createJointPermissionDataArray($entity, $roleId, $hasAccess, $hasAccess);
|
return $this->createJointPermissionDataArray($entity, $roleId, $hasAccess, $hasAccess);
|
||||||
|
@ -360,13 +348,14 @@ class JointPermissionBuilder
|
||||||
// For chapters and pages, Check if explicit permissions are set on the Book.
|
// For chapters and pages, Check if explicit permissions are set on the Book.
|
||||||
$book = $this->getBook($entity->book_id);
|
$book = $this->getBook($entity->book_id);
|
||||||
$hasExplicitAccessToParents = $this->mapHasActiveRestriction($permissionMap, $book, $roleId);
|
$hasExplicitAccessToParents = $this->mapHasActiveRestriction($permissionMap, $book, $roleId);
|
||||||
$hasPermissiveAccessToParents = !$book->restricted;
|
$hasPermissiveAccessToParents = !$this->entityPermissionsActiveForRole($permissionMap, $book, $roleId);
|
||||||
|
|
||||||
// For pages with a chapter, Check if explicit permissions are set on the Chapter
|
// For pages with a chapter, Check if explicit permissions are set on the Chapter
|
||||||
if ($entity->type === 'page' && $entity->chapter_id !== 0) {
|
if ($entity->type === 'page' && $entity->chapter_id !== 0) {
|
||||||
$chapter = $this->getChapter($entity->chapter_id);
|
$chapter = $this->getChapter($entity->chapter_id);
|
||||||
$hasPermissiveAccessToParents = $hasPermissiveAccessToParents && !$chapter->restricted;
|
$chapterRestricted = $this->entityPermissionsActiveForRole($permissionMap, $chapter, $roleId);
|
||||||
if ($chapter->restricted) {
|
$hasPermissiveAccessToParents = $hasPermissiveAccessToParents && !$chapterRestricted;
|
||||||
|
if ($chapterRestricted) {
|
||||||
$hasExplicitAccessToParents = $this->mapHasActiveRestriction($permissionMap, $chapter, $roleId);
|
$hasExplicitAccessToParents = $this->mapHasActiveRestriction($permissionMap, $chapter, $roleId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,14 +368,25 @@ class JointPermissionBuilder
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if entity permissions are defined within the given map, for the given entity and role.
|
||||||
|
* Checks for the default `role_id=0` backup option as a fallback.
|
||||||
|
*/
|
||||||
|
protected function entityPermissionsActiveForRole(array $permissionMap, SimpleEntityData $entity, int $roleId): bool
|
||||||
|
{
|
||||||
|
$keyPrefix = $entity->type . ':' . $entity->id . ':';
|
||||||
|
return isset($permissionMap[$keyPrefix . $roleId]) || isset($permissionMap[$keyPrefix . '0']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for an active restriction in an entity map.
|
* Check for an active restriction in an entity map.
|
||||||
*/
|
*/
|
||||||
protected function mapHasActiveRestriction(array $entityMap, SimpleEntityData $entity, int $roleId): bool
|
protected function mapHasActiveRestriction(array $entityMap, SimpleEntityData $entity, int $roleId): bool
|
||||||
{
|
{
|
||||||
$key = $entity->type . ':' . $entity->id . ':' . $roleId;
|
$roleKey = $entity->type . ':' . $entity->id . ':' . $roleId;
|
||||||
|
$defaultKey = $entity->type . ':' . $entity->id . ':0';
|
||||||
|
|
||||||
return $entityMap[$key] ?? false;
|
return $entityMap[$roleKey] ?? $entityMap[$defaultKey] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,7 +6,6 @@ class SimpleEntityData
|
||||||
{
|
{
|
||||||
public int $id;
|
public int $id;
|
||||||
public string $type;
|
public string $type;
|
||||||
public bool $restricted;
|
|
||||||
public int $owned_by;
|
public int $owned_by;
|
||||||
public ?int $book_id;
|
public ?int $book_id;
|
||||||
public ?int $chapter_id;
|
public ?int $chapter_id;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue