mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-08-26 20:22:18 +00:00
Continued with database work for permissions overhaul
Added to the entity_permissions table with further required fields and indexes. Wrote the code for checking permissions.
This commit is contained in:
parent
ea287ebf86
commit
ada7c83e96
51
app/Console/Commands/RegeneratePermissions.php
Normal file
51
app/Console/Commands/RegeneratePermissions.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BookStack\Console\Commands;
|
||||||
|
|
||||||
|
use BookStack\Services\RestrictionService;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class RegeneratePermissions extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'permissions:regen';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Regenerate all system permissions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The service to handle the permission system.
|
||||||
|
*
|
||||||
|
* @var RestrictionService
|
||||||
|
*/
|
||||||
|
protected $restrictionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @param RestrictionService $restrictionService
|
||||||
|
*/
|
||||||
|
public function __construct(RestrictionService $restrictionService)
|
||||||
|
{
|
||||||
|
$this->restrictionService = $restrictionService;
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$this->restrictionService->buildEntityPermissions();
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ class Kernel extends ConsoleKernel
|
|||||||
protected $commands = [
|
protected $commands = [
|
||||||
\BookStack\Console\Commands\Inspire::class,
|
\BookStack\Console\Commands\Inspire::class,
|
||||||
\BookStack\Console\Commands\ResetViews::class,
|
\BookStack\Console\Commands\ResetViews::class,
|
||||||
|
\BookStack\Console\Commands\RegeneratePermissions::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,6 +73,15 @@ abstract class Entity extends Ownable
|
|||||||
return $this->restrictions->where('role_id', $role_id)->where('action', $action)->count() > 0;
|
return $this->restrictions->where('role_id', $role_id)->where('action', $action)->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the entity permissions this is connected to.
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
|
*/
|
||||||
|
public function permissions()
|
||||||
|
{
|
||||||
|
return $this->morphMany(EntityPermission::class, 'entity');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows checking of the exact class, Used to check entity type.
|
* Allows checking of the exact class, Used to check entity type.
|
||||||
* Cleaner method for is_a.
|
* Cleaner method for is_a.
|
||||||
@ -81,7 +90,16 @@ abstract class Entity extends Ownable
|
|||||||
*/
|
*/
|
||||||
public static function isA($type)
|
public static function isA($type)
|
||||||
{
|
{
|
||||||
return static::getClassName() === strtolower($type);
|
return static::getType() === strtolower($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get entity type.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function getType()
|
||||||
|
{
|
||||||
|
return strtolower(static::getClassName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,6 @@ use BookStack\Chapter;
|
|||||||
use BookStack\Entity;
|
use BookStack\Entity;
|
||||||
use BookStack\EntityPermission;
|
use BookStack\EntityPermission;
|
||||||
use BookStack\Page;
|
use BookStack\Page;
|
||||||
use BookStack\Permission;
|
|
||||||
use BookStack\Role;
|
use BookStack\Role;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
|
||||||
@ -23,18 +22,19 @@ class RestrictionService
|
|||||||
|
|
||||||
protected $entityPermission;
|
protected $entityPermission;
|
||||||
protected $role;
|
protected $role;
|
||||||
protected $permission;
|
|
||||||
|
protected $actions = ['view', 'create', 'update', 'delete'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RestrictionService constructor.
|
* RestrictionService constructor.
|
||||||
|
* TODO - Handle events when roles or entities change.
|
||||||
* @param EntityPermission $entityPermission
|
* @param EntityPermission $entityPermission
|
||||||
* @param Book $book
|
* @param Book $book
|
||||||
* @param Chapter $chapter
|
* @param Chapter $chapter
|
||||||
* @param Page $page
|
* @param Page $page
|
||||||
* @param Role $role
|
* @param Role $role
|
||||||
* @param Permission $permission
|
|
||||||
*/
|
*/
|
||||||
public function __construct(EntityPermission $entityPermission, Book $book, Chapter $chapter, Page $page, Role $role, Permission $permission)
|
public function __construct(EntityPermission $entityPermission, Book $book, Chapter $chapter, Page $page, Role $role)
|
||||||
{
|
{
|
||||||
$this->currentUser = auth()->user();
|
$this->currentUser = auth()->user();
|
||||||
$this->userRoles = $this->currentUser ? $this->currentUser->roles->pluck('id') : [];
|
$this->userRoles = $this->currentUser ? $this->currentUser->roles->pluck('id') : [];
|
||||||
@ -42,13 +42,11 @@ class RestrictionService
|
|||||||
|
|
||||||
$this->entityPermission = $entityPermission;
|
$this->entityPermission = $entityPermission;
|
||||||
$this->role = $role;
|
$this->role = $role;
|
||||||
$this->permission = $permission;
|
|
||||||
$this->book = $book;
|
$this->book = $book;
|
||||||
$this->chapter = $chapter;
|
$this->chapter = $chapter;
|
||||||
$this->page = $page;
|
$this->page = $page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-generate all entity permission from scratch.
|
* Re-generate all entity permission from scratch.
|
||||||
*/
|
*/
|
||||||
@ -65,12 +63,12 @@ class RestrictionService
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Chunk through all chapters
|
// Chunk through all chapters
|
||||||
$this->chapter->chunk(500, function ($books) use ($roles) {
|
$this->chapter->with('book')->chunk(500, function ($books) use ($roles) {
|
||||||
$this->createManyEntityPermissions($books, $roles);
|
$this->createManyEntityPermissions($books, $roles);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Chunk through all pages
|
// Chunk through all pages
|
||||||
$this->page->chunk(500, function ($books) use ($roles) {
|
$this->page->with('book', 'chapter')->chunk(500, function ($books) use ($roles) {
|
||||||
$this->createManyEntityPermissions($books, $roles);
|
$this->createManyEntityPermissions($books, $roles);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -85,16 +83,69 @@ class RestrictionService
|
|||||||
$entityPermissions = [];
|
$entityPermissions = [];
|
||||||
foreach ($entities as $entity) {
|
foreach ($entities as $entity) {
|
||||||
foreach ($roles as $role) {
|
foreach ($roles as $role) {
|
||||||
$entityPermissions[] = $this->createEntityPermission($entity, $role);
|
foreach ($this->actions as $action) {
|
||||||
|
$entityPermissions[] = $this->createEntityPermissionData($entity, $role, $action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->entityPermission->insert($entityPermissions);
|
$this->entityPermission->insert($entityPermissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected function createEntityPermissionData(Entity $entity, Role $role)
|
protected function createEntityPermissionData(Entity $entity, Role $role, $action)
|
||||||
{
|
{
|
||||||
// TODO - Check the permission values and return an EntityPermission
|
$permissionPrefix = $entity->getType() . '-' . $action;
|
||||||
|
$roleHasPermission = $role->hasPermission($permissionPrefix . '-all');
|
||||||
|
$roleHasPermissionOwn = $role->hasPermission($permissionPrefix . '-own');
|
||||||
|
|
||||||
|
if ($entity->isA('book')) {
|
||||||
|
|
||||||
|
if (!$entity->restricted) {
|
||||||
|
return $this->createEntityPermissionDataArray($entity, $role, $action, $roleHasPermission, $roleHasPermissionOwn);
|
||||||
|
} else {
|
||||||
|
$hasAccess = $entity->hasRestriction($role->id, $action);
|
||||||
|
return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
} elseif ($entity->isA('chapter')) {
|
||||||
|
|
||||||
|
if (!$entity->restricted) {
|
||||||
|
$hasAccessToBook = $entity->book->hasRestriction($role->id, $action);
|
||||||
|
return $this->createEntityPermissionDataArray($entity, $role, $action,
|
||||||
|
($roleHasPermission && $hasAccessToBook), ($roleHasPermissionOwn && $hasAccessToBook));
|
||||||
|
} else {
|
||||||
|
$hasAccess = $entity->hasRestriction($role->id, $action);
|
||||||
|
return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
} elseif ($entity->isA('page')) {
|
||||||
|
|
||||||
|
if (!$entity->restricted) {
|
||||||
|
$hasAccessToBook = $entity->book->hasRestriction($role->id, $action);
|
||||||
|
$hasAccessToChapter = $entity->chapter ? ($entity->chapter->hasRestriction($role->id, $action)) : true;
|
||||||
|
return $this->createEntityPermissionDataArray($entity, $role, $action,
|
||||||
|
($roleHasPermission && $hasAccessToBook && $hasAccessToChapter),
|
||||||
|
($roleHasPermissionOwn && $hasAccessToBook && $hasAccessToChapter));
|
||||||
|
} else {
|
||||||
|
$hasAccess = $entity->hasRestriction($role->id, $action);
|
||||||
|
return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createEntityPermissionDataArray(Entity $entity, Role $role, $action, $permissionAll, $permissionOwn)
|
||||||
|
{
|
||||||
|
$entityClass = get_class($entity);
|
||||||
|
return [
|
||||||
|
'role_id' => $role->id,
|
||||||
|
'entity_id' => $entity->id,
|
||||||
|
'entity_type' => $entityClass,
|
||||||
|
'action' => $action,
|
||||||
|
'has_permission' => $permissionAll,
|
||||||
|
'has_permission_own' => $permissionOwn,
|
||||||
|
'created_by' => $entity->created_by
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,85 +208,28 @@ class RestrictionService
|
|||||||
|
|
||||||
if ($this->isAdmin) return $query;
|
if ($this->isAdmin) return $query;
|
||||||
$this->currentAction = $action;
|
$this->currentAction = $action;
|
||||||
return $this->pageRestrictionQuery($query);
|
return $this->entityRestrictionQuery($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base query for restricting pages.
|
* The general query filter to remove all entities
|
||||||
|
* that the current user does not have access to.
|
||||||
* @param $query
|
* @param $query
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function pageRestrictionQuery($query)
|
protected function entityRestrictionQuery($query)
|
||||||
{
|
{
|
||||||
return $query->where(function ($parentWhereQuery) {
|
return $query->where(function ($parentQuery) {
|
||||||
|
$parentQuery->whereHas('permissions', function ($permissionQuery) {
|
||||||
$parentWhereQuery
|
$permissionQuery->whereIn('role_id', $this->userRoles)
|
||||||
// (Book & chapter & page) or (Book & page & NO CHAPTER) unrestricted
|
->where('action', '=', $this->currentAction)
|
||||||
->where(function ($query) {
|
->where(function ($query) {
|
||||||
$query->where(function ($query) {
|
$query->where('has_permission', '=', true)
|
||||||
$query->whereExists(function ($query) {
|
|
||||||
$query->select('*')->from('chapters')
|
|
||||||
->whereRaw('chapters.id=pages.chapter_id')
|
|
||||||
->where('restricted', '=', false);
|
|
||||||
})->whereExists(function ($query) {
|
|
||||||
$query->select('*')->from('books')
|
|
||||||
->whereRaw('books.id=pages.book_id')
|
|
||||||
->where('restricted', '=', false);
|
|
||||||
})->where('restricted', '=', false);
|
|
||||||
})->orWhere(function ($query) {
|
|
||||||
$query->where('restricted', '=', false)->where('chapter_id', '=', 0)
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$query->select('*')->from('books')
|
|
||||||
->whereRaw('books.id=pages.book_id')
|
|
||||||
->where('restricted', '=', false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
// Page unrestricted, Has no chapter & book has accepted restrictions
|
|
||||||
->orWhere(function ($query) {
|
->orWhere(function ($query) {
|
||||||
$query->where('restricted', '=', false)
|
$query->where('has_permission_own', '=', true)
|
||||||
->whereExists(function ($query) {
|
->where('created_by', '=', $this->currentUser->id);
|
||||||
$query->select('*')->from('chapters')
|
|
||||||
->whereRaw('chapters.id=pages.chapter_id');
|
|
||||||
}, 'and', true)
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$query->select('*')->from('books')
|
|
||||||
->whereRaw('books.id=pages.book_id')
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$this->checkRestrictionsQuery($query, 'books', 'Book');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
|
||||||
// Page unrestricted, Has an unrestricted chapter & book has accepted restrictions
|
|
||||||
->orWhere(function ($query) {
|
|
||||||
$query->where('restricted', '=', false)
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$query->select('*')->from('chapters')
|
|
||||||
->whereRaw('chapters.id=pages.chapter_id')->where('restricted', '=', false);
|
|
||||||
})
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$query->select('*')->from('books')
|
|
||||||
->whereRaw('books.id=pages.book_id')
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$this->checkRestrictionsQuery($query, 'books', 'Book');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
// Page unrestricted, Has a chapter with accepted permissions
|
|
||||||
->orWhere(function ($query) {
|
|
||||||
$query->where('restricted', '=', false)
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$query->select('*')->from('chapters')
|
|
||||||
->whereRaw('chapters.id=pages.chapter_id')
|
|
||||||
->where('restricted', '=', true)
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$this->checkRestrictionsQuery($query, 'chapters', 'Chapter');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
// Page has accepted permissions
|
|
||||||
->orWhereExists(function ($query) {
|
|
||||||
$this->checkRestrictionsQuery($query, 'pages', 'Page');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -250,43 +244,7 @@ class RestrictionService
|
|||||||
{
|
{
|
||||||
if ($this->isAdmin) return $query;
|
if ($this->isAdmin) return $query;
|
||||||
$this->currentAction = $action;
|
$this->currentAction = $action;
|
||||||
return $this->chapterRestrictionQuery($query);
|
return $this->entityRestrictionQuery($query);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The base query for restricting chapters.
|
|
||||||
* @param $query
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
private function chapterRestrictionQuery($query)
|
|
||||||
{
|
|
||||||
return $query->where(function ($parentWhereQuery) {
|
|
||||||
|
|
||||||
$parentWhereQuery
|
|
||||||
// Book & chapter unrestricted
|
|
||||||
->where(function ($query) {
|
|
||||||
$query->where('restricted', '=', false)->whereExists(function ($query) {
|
|
||||||
$query->select('*')->from('books')
|
|
||||||
->whereRaw('books.id=chapters.book_id')
|
|
||||||
->where('restricted', '=', false);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
// Chapter unrestricted & book has accepted restrictions
|
|
||||||
->orWhere(function ($query) {
|
|
||||||
$query->where('restricted', '=', false)
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$query->select('*')->from('books')
|
|
||||||
->whereRaw('books.id=chapters.book_id')
|
|
||||||
->whereExists(function ($query) {
|
|
||||||
$this->checkRestrictionsQuery($query, 'books', 'Book');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
// Chapter has accepted permissions
|
|
||||||
->orWhereExists(function ($query) {
|
|
||||||
$this->checkRestrictionsQuery($query, 'chapters', 'Chapter');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -299,25 +257,7 @@ class RestrictionService
|
|||||||
{
|
{
|
||||||
if ($this->isAdmin) return $query;
|
if ($this->isAdmin) return $query;
|
||||||
$this->currentAction = $action;
|
$this->currentAction = $action;
|
||||||
return $this->bookRestrictionQuery($query);
|
return $this->entityRestrictionQuery($query);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The base query for restricting books.
|
|
||||||
* @param $query
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
private function bookRestrictionQuery($query)
|
|
||||||
{
|
|
||||||
return $query->where(function ($parentWhereQuery) {
|
|
||||||
$parentWhereQuery
|
|
||||||
->where('restricted', '=', false)
|
|
||||||
->orWhere(function ($query) {
|
|
||||||
$query->where('restricted', '=', true)->whereExists(function ($query) {
|
|
||||||
$this->checkRestrictionsQuery($query, 'books', 'Book');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -333,31 +273,23 @@ class RestrictionService
|
|||||||
if ($this->isAdmin) return $query;
|
if ($this->isAdmin) return $query;
|
||||||
$this->currentAction = 'view';
|
$this->currentAction = 'view';
|
||||||
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn];
|
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn];
|
||||||
|
|
||||||
return $query->where(function ($query) use ($tableDetails) {
|
return $query->where(function ($query) use ($tableDetails) {
|
||||||
$query->where(function ($query) use (&$tableDetails) {
|
$query->whereExists(function ($permissionQuery) use (&$tableDetails) {
|
||||||
$query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Page')
|
$permissionQuery->select('id')->from('entity_permissions')
|
||||||
->whereExists(function ($query) use (&$tableDetails) {
|
->whereRaw('entity_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
||||||
$query->select('*')->from('pages')->whereRaw('pages.id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
->whereRaw('entity_permissions.entity_type=' . $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'])
|
||||||
|
->where('action', '=', $this->currentAction)
|
||||||
|
->whereIn('role_id', $this->userRoles)
|
||||||
->where(function ($query) {
|
->where(function ($query) {
|
||||||
$this->pageRestrictionQuery($query);
|
$query->where('has_permission', '=', true)->orWhere(function ($query) {
|
||||||
});
|
$query->where('has_permission_own', '=', true)
|
||||||
});
|
->where('created_by', '=', $this->currentUser->id);
|
||||||
})->orWhere(function ($query) use (&$tableDetails) {
|
|
||||||
$query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Book')->whereExists(function ($query) use (&$tableDetails) {
|
|
||||||
$query->select('*')->from('books')->whereRaw('books.id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
|
||||||
->where(function ($query) {
|
|
||||||
$this->bookRestrictionQuery($query);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})->orWhere(function ($query) use (&$tableDetails) {
|
|
||||||
$query->where($tableDetails['entityTypeColumn'], '=', 'BookStack\Chapter')->whereExists(function ($query) use (&$tableDetails) {
|
|
||||||
$query->select('*')->from('chapters')->whereRaw('chapters.id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
|
||||||
->where(function ($query) {
|
|
||||||
$this->chapterRestrictionQuery($query);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -372,32 +304,24 @@ class RestrictionService
|
|||||||
if ($this->isAdmin) return $query;
|
if ($this->isAdmin) return $query;
|
||||||
$this->currentAction = 'view';
|
$this->currentAction = 'view';
|
||||||
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn];
|
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn];
|
||||||
return $query->where(function ($query) use (&$tableDetails) {
|
|
||||||
|
return $query->where(function ($query) use ($tableDetails) {
|
||||||
$query->where(function ($query) use (&$tableDetails) {
|
$query->where(function ($query) use (&$tableDetails) {
|
||||||
$query->whereExists(function ($query) use (&$tableDetails) {
|
$query->whereExists(function ($permissionQuery) use (&$tableDetails) {
|
||||||
$query->select('*')->from('pages')->whereRaw('pages.id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
$permissionQuery->select('id')->from('entity_permissions')
|
||||||
|
->whereRaw('entity_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
||||||
|
->where('entity_type', '=', 'Bookstack\\Page')
|
||||||
|
->where('action', '=', $this->currentAction)
|
||||||
|
->whereIn('role_id', $this->userRoles)
|
||||||
->where(function ($query) {
|
->where(function ($query) {
|
||||||
$this->pageRestrictionQuery($query);
|
$query->where('has_permission', '=', true)->orWhere(function ($query) {
|
||||||
|
$query->where('has_permission_own', '=', true)
|
||||||
|
->where('created_by', '=', $this->currentUser->id);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})->orWhere($tableDetails['entityIdColumn'], '=', 0);
|
})->orWhere($tableDetails['entityIdColumn'], '=', 0);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The query to check the restrictions on an entity.
|
|
||||||
* @param $query
|
|
||||||
* @param $tableName
|
|
||||||
* @param $modelName
|
|
||||||
*/
|
|
||||||
private function checkRestrictionsQuery($query, $tableName, $modelName)
|
|
||||||
{
|
|
||||||
$query->select('*')->from('restrictions')
|
|
||||||
->whereRaw('restrictions.restrictable_id=' . $tableName . '.id')
|
|
||||||
->where('restrictions.restrictable_type', '=', 'BookStack\\' . $modelName)
|
|
||||||
->where('restrictions.action', '=', $this->currentAction)
|
|
||||||
->whereIn('restrictions.role_id', $this->userRoles);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -19,7 +19,16 @@ class CreateEntityPermissionsTable extends Migration
|
|||||||
$table->integer('entity_id');
|
$table->integer('entity_id');
|
||||||
$table->string('action');
|
$table->string('action');
|
||||||
$table->boolean('has_permission')->default(false);
|
$table->boolean('has_permission')->default(false);
|
||||||
|
$table->boolean('has_permission_own')->default(false);
|
||||||
|
$table->integer('created_by');
|
||||||
|
$table->index(['entity_id', 'entity_type']);
|
||||||
|
$table->index('role_id');
|
||||||
|
$table->index('action');
|
||||||
|
$table->index('created_by');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$restrictionService = app(\BookStack\Services\RestrictionService::class);
|
||||||
|
$restrictionService->buildEntityPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th>Create</th>
|
<th>Create</th>
|
||||||
|
<th>View</th>
|
||||||
<th>Edit</th>
|
<th>Edit</th>
|
||||||
<th>Delete</th>
|
<th>Delete</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
Loading…
Reference in New Issue
Block a user