mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-05-12 20:01:53 +00:00
Worked around create permission quirks
This commit is contained in:
parent
a81a56706e
commit
9a31b83b2a
3 changed files with 45 additions and 19 deletions
app
database/seeds
|
@ -69,7 +69,7 @@ class PageController extends Controller
|
||||||
{
|
{
|
||||||
$book = $this->bookRepo->getBySlug($bookSlug);
|
$book = $this->bookRepo->getBySlug($bookSlug);
|
||||||
$draft = $this->pageRepo->getById($pageId, true);
|
$draft = $this->pageRepo->getById($pageId, true);
|
||||||
$this->checkOwnablePermission('page-create', $draft);
|
$this->checkOwnablePermission('page-create', $book);
|
||||||
$this->setPageTitle('Edit Page Draft');
|
$this->setPageTitle('Edit Page Draft');
|
||||||
|
|
||||||
return view('pages/create', ['draft' => $draft, 'book' => $book]);
|
return view('pages/create', ['draft' => $draft, 'book' => $book]);
|
||||||
|
|
|
@ -6,6 +6,7 @@ use BookStack\Entity;
|
||||||
use BookStack\EntityPermission;
|
use BookStack\EntityPermission;
|
||||||
use BookStack\Page;
|
use BookStack\Page;
|
||||||
use BookStack\Role;
|
use BookStack\Role;
|
||||||
|
use BookStack\User;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
|
||||||
class RestrictionService
|
class RestrictionService
|
||||||
|
@ -23,12 +24,6 @@ class RestrictionService
|
||||||
protected $entityPermission;
|
protected $entityPermission;
|
||||||
protected $role;
|
protected $role;
|
||||||
|
|
||||||
/**
|
|
||||||
* The actions that have permissions attached throughout the application.
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $actions = ['view', 'create', 'update', 'delete'];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RestrictionService constructor.
|
* RestrictionService constructor.
|
||||||
* @param EntityPermission $entityPermission
|
* @param EntityPermission $entityPermission
|
||||||
|
@ -40,6 +35,7 @@ class RestrictionService
|
||||||
public function __construct(EntityPermission $entityPermission, Book $book, Chapter $chapter, Page $page, Role $role)
|
public function __construct(EntityPermission $entityPermission, Book $book, Chapter $chapter, Page $page, Role $role)
|
||||||
{
|
{
|
||||||
$this->currentUser = auth()->user();
|
$this->currentUser = auth()->user();
|
||||||
|
if ($this->currentUser === null) $this->currentUser = new User(['id' => 0]);
|
||||||
$this->userRoles = $this->currentUser ? $this->currentUser->roles->pluck('id') : [];
|
$this->userRoles = $this->currentUser ? $this->currentUser->roles->pluck('id') : [];
|
||||||
$this->isAdmin = $this->currentUser ? $this->currentUser->hasRole('admin') : false;
|
$this->isAdmin = $this->currentUser ? $this->currentUser->hasRole('admin') : false;
|
||||||
|
|
||||||
|
@ -172,15 +168,34 @@ class RestrictionService
|
||||||
$entityPermissions = [];
|
$entityPermissions = [];
|
||||||
foreach ($entities as $entity) {
|
foreach ($entities as $entity) {
|
||||||
foreach ($roles as $role) {
|
foreach ($roles as $role) {
|
||||||
foreach ($this->actions as $action) {
|
foreach ($this->getActions($entity) as $action) {
|
||||||
$entityPermissions[] = $this->createEntityPermissionData($entity, $role, $action);
|
$entityPermissions[] = $this->createEntityPermissionData($entity, $role, $action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\Log::info(collect($entityPermissions)->where('entity_id', 1)->where('entity_type', 'BookStack\\Page')->where('role_id', 2)->all());
|
|
||||||
$this->entityPermission->insert($entityPermissions);
|
$this->entityPermission->insert($entityPermissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the actions related to an entity.
|
||||||
|
* @param $entity
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getActions($entity)
|
||||||
|
{
|
||||||
|
$baseActions = ['view', 'update', 'delete'];
|
||||||
|
|
||||||
|
if ($entity->isA('chapter')) {
|
||||||
|
$baseActions[] = 'page-create';
|
||||||
|
} else if ($entity->isA('book')) {
|
||||||
|
$baseActions[] = 'page-create';
|
||||||
|
$baseActions[] = 'chapter-create';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $baseActions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create entity permission data for an entity and role
|
* Create entity permission data for an entity and role
|
||||||
* for a particular action.
|
* for a particular action.
|
||||||
|
@ -191,38 +206,40 @@ class RestrictionService
|
||||||
*/
|
*/
|
||||||
protected function createEntityPermissionData(Entity $entity, Role $role, $action)
|
protected function createEntityPermissionData(Entity $entity, Role $role, $action)
|
||||||
{
|
{
|
||||||
$permissionPrefix = $entity->getType() . '-' . $action;
|
$permissionPrefix = (strpos($action, '-') === false ? ($entity->getType() . '-') : '') . $action;
|
||||||
$roleHasPermission = $role->hasPermission($permissionPrefix . '-all');
|
$roleHasPermission = $role->hasPermission($permissionPrefix . '-all');
|
||||||
$roleHasPermissionOwn = $role->hasPermission($permissionPrefix . '-own');
|
$roleHasPermissionOwn = $role->hasPermission($permissionPrefix . '-own');
|
||||||
|
$explodedAction = explode('-', $action);
|
||||||
|
$restrictionAction = end($explodedAction);
|
||||||
|
|
||||||
if ($entity->isA('book')) {
|
if ($entity->isA('book')) {
|
||||||
|
|
||||||
if (!$entity->restricted) {
|
if (!$entity->restricted) {
|
||||||
return $this->createEntityPermissionDataArray($entity, $role, $action, $roleHasPermission, $roleHasPermissionOwn);
|
return $this->createEntityPermissionDataArray($entity, $role, $action, $roleHasPermission, $roleHasPermissionOwn);
|
||||||
} else {
|
} else {
|
||||||
$hasAccess = $entity->hasActiveRestriction($role->id, $action);
|
$hasAccess = $entity->hasActiveRestriction($role->id, $restrictionAction);
|
||||||
return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
|
return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
} elseif ($entity->isA('chapter')) {
|
} elseif ($entity->isA('chapter')) {
|
||||||
|
|
||||||
if (!$entity->restricted) {
|
if (!$entity->restricted) {
|
||||||
$hasExplicitAccessToBook = $entity->book->hasActiveRestriction($role->id, $action);
|
$hasExplicitAccessToBook = $entity->book->hasActiveRestriction($role->id, $restrictionAction);
|
||||||
$hasPermissiveAccessToBook = !$entity->book->restricted;
|
$hasPermissiveAccessToBook = !$entity->book->restricted;
|
||||||
return $this->createEntityPermissionDataArray($entity, $role, $action,
|
return $this->createEntityPermissionDataArray($entity, $role, $action,
|
||||||
($hasExplicitAccessToBook || ($roleHasPermission && $hasPermissiveAccessToBook)),
|
($hasExplicitAccessToBook || ($roleHasPermission && $hasPermissiveAccessToBook)),
|
||||||
($hasExplicitAccessToBook || ($roleHasPermissionOwn && $hasPermissiveAccessToBook)));
|
($hasExplicitAccessToBook || ($roleHasPermissionOwn && $hasPermissiveAccessToBook)));
|
||||||
} else {
|
} else {
|
||||||
$hasAccess = $entity->hasActiveRestriction($role->id, $action);
|
$hasAccess = $entity->hasActiveRestriction($role->id, $restrictionAction);
|
||||||
return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
|
return $this->createEntityPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
} elseif ($entity->isA('page')) {
|
} elseif ($entity->isA('page')) {
|
||||||
|
|
||||||
if (!$entity->restricted) {
|
if (!$entity->restricted) {
|
||||||
$hasExplicitAccessToBook = $entity->book->hasActiveRestriction($role->id, $action);
|
$hasExplicitAccessToBook = $entity->book->hasActiveRestriction($role->id, $restrictionAction);
|
||||||
$hasPermissiveAccessToBook = !$entity->book->restricted;
|
$hasPermissiveAccessToBook = !$entity->book->restricted;
|
||||||
$hasExplicitAccessToChapter = $entity->chapter && $entity->chapter->hasActiveRestriction($role->id, $action);
|
$hasExplicitAccessToChapter = $entity->chapter && $entity->chapter->hasActiveRestriction($role->id, $restrictionAction);
|
||||||
$hasPermissiveAccessToChapter = $entity->chapter && !$entity->chapter->restricted;
|
$hasPermissiveAccessToChapter = $entity->chapter && !$entity->chapter->restricted;
|
||||||
$acknowledgeChapter = ($entity->chapter && $entity->chapter->restricted);
|
$acknowledgeChapter = ($entity->chapter && $entity->chapter->restricted);
|
||||||
|
|
||||||
|
@ -277,6 +294,8 @@ class RestrictionService
|
||||||
$explodedPermission = explode('-', $permission);
|
$explodedPermission = explode('-', $permission);
|
||||||
|
|
||||||
$baseQuery = $entity->where('id', '=', $entity->id);
|
$baseQuery = $entity->where('id', '=', $entity->id);
|
||||||
|
$action = end($explodedPermission);
|
||||||
|
$this->currentAction = $action;
|
||||||
|
|
||||||
$nonEntityPermissions = ['restrictions'];
|
$nonEntityPermissions = ['restrictions'];
|
||||||
|
|
||||||
|
@ -289,8 +308,12 @@ class RestrictionService
|
||||||
return ($allPermission || ($isOwner && $ownPermission));
|
return ($allPermission || ($isOwner && $ownPermission));
|
||||||
}
|
}
|
||||||
|
|
||||||
$action = end($explodedPermission);
|
// Handle abnormal create permissions
|
||||||
$this->currentAction = $action;
|
if ($action === 'create') {
|
||||||
|
$this->currentAction = $permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $this->entityRestrictionQuery($baseQuery)->count() > 0;
|
return $this->entityRestrictionQuery($baseQuery)->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,7 +464,7 @@ class RestrictionService
|
||||||
->where(function ($query) {
|
->where(function ($query) {
|
||||||
$query->where('has_permission', '=', true)->orWhere(function ($query) {
|
$query->where('has_permission', '=', true)->orWhere(function ($query) {
|
||||||
$query->where('has_permission_own', '=', true)
|
$query->where('has_permission_own', '=', true)
|
||||||
->where('created_by', '=', $this->currentUser ? $this->currentUser->id : 0);
|
->where('created_by', '=', $this->currentUser->id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,12 +20,15 @@ class DummyContentSeeder extends Seeder
|
||||||
->each(function($book) use ($user) {
|
->each(function($book) use ($user) {
|
||||||
$chapters = factory(BookStack\Chapter::class, 5)->create(['created_by' => $user->id, 'updated_by' => $user->id])
|
$chapters = factory(BookStack\Chapter::class, 5)->create(['created_by' => $user->id, 'updated_by' => $user->id])
|
||||||
->each(function($chapter) use ($user, $book){
|
->each(function($chapter) use ($user, $book){
|
||||||
$pages = factory(\BookStack\Page::class, 10)->make(['created_by' => $user->id, 'updated_by' => $user->id, 'book_id' => $book->id]);
|
$pages = factory(\BookStack\Page::class, 5)->make(['created_by' => $user->id, 'updated_by' => $user->id, 'book_id' => $book->id]);
|
||||||
$chapter->pages()->saveMany($pages);
|
$chapter->pages()->saveMany($pages);
|
||||||
});
|
});
|
||||||
$pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $user->id, 'updated_by' => $user->id]);
|
$pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $user->id, 'updated_by' => $user->id]);
|
||||||
$book->chapters()->saveMany($chapters);
|
$book->chapters()->saveMany($chapters);
|
||||||
$book->pages()->saveMany($pages);
|
$book->pages()->saveMany($pages);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$restrictionService = app(\BookStack\Services\RestrictionService::class);
|
||||||
|
$restrictionService->buildEntityPermissions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue