1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-31 15:24:31 +03:00

Added joint_user_permissions handling to query system

Some issues exist to resolve though, not in final state.
This commit is contained in:
Dan Brown
2022-12-11 22:53:46 +00:00
parent 0411185fbb
commit 60bf838a4a
2 changed files with 51 additions and 14 deletions

View File

@ -167,12 +167,15 @@ class PermissionApplicator
{ {
return $query->where(function (Builder $parentQuery) { return $query->where(function (Builder $parentQuery) {
$parentQuery->whereHas('jointPermissions', function (Builder $permissionQuery) { $parentQuery->whereHas('jointPermissions', function (Builder $permissionQuery) {
// TODO - Update for user permission
$permissionQuery->whereIn('role_id', $this->getCurrentUserRoleIds()) $permissionQuery->whereIn('role_id', $this->getCurrentUserRoleIds())
->where(function (Builder $query) { ->where(function (Builder $query) {
$this->addJointHasPermissionCheck($query, $this->currentUser()->id); $this->addJointHasPermissionCheck($query, $this->currentUser()->id);
}); });
})->orWhereHas('jointUserPermissions', function (Builder $query) {
$query->where('user_id', '=', $this->currentUser()->id)->where('has_permission', '=', true);
}); });
})->whereDoesntHave('jointUserPermissions', function (Builder $query) {
$query->where('user_id', '=', $this->currentUser()->id)->where('has_permission', '=', false);
}); });
} }
@ -203,16 +206,30 @@ class PermissionApplicator
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn]; $tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn];
$pageMorphClass = (new Page())->getMorphClass(); $pageMorphClass = (new Page())->getMorphClass();
$q = $query->whereExists(function ($permissionQuery) use (&$tableDetails) { $q = $query->where(function ($query) use ($tableDetails) {
// TODO - Update for user permission $query->whereExists(function ($permissionQuery) use ($tableDetails) {
/** @var Builder $permissionQuery */ /** @var Builder $permissionQuery */
$permissionQuery->select(['role_id'])->from('joint_permissions') $permissionQuery->select(['role_id'])->from('joint_permissions')
->whereColumn('joint_permissions.entity_id', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn']) ->whereColumn('joint_permissions.entity_id', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
->whereColumn('joint_permissions.entity_type', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn']) ->whereColumn('joint_permissions.entity_type', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'])
->whereIn('joint_permissions.role_id', $this->getCurrentUserRoleIds()) ->whereIn('joint_permissions.role_id', $this->getCurrentUserRoleIds())
->where(function (QueryBuilder $query) { ->where(function (QueryBuilder $query) {
$this->addJointHasPermissionCheck($query, $this->currentUser()->id); $this->addJointHasPermissionCheck($query, $this->currentUser()->id);
}); });
})->orWhereExists(function ($permissionQuery) use ($tableDetails) {
/** @var Builder $permissionQuery */
$permissionQuery->select(['user_id'])->from('joint_user_permissions')
->whereColumn('joint_user_permissions.entity_id', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
->whereColumn('joint_user_permissions.entity_type', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'])
->where('joint_user_permissions.user_id', '=', $this->currentUser()->id)
->where('joint_user_permissions.has_permission', '=', true);
});
})->whereNotExists(function ($query) use ($tableDetails) {
$query->select(['user_id'])->from('joint_user_permissions')
->whereColumn('joint_user_permissions.entity_id', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
->whereColumn('joint_user_permissions.entity_type', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'])
->where('joint_user_permissions.user_id', '=', $this->currentUser()->id)
->where('joint_user_permissions.has_permission', '=', false);
})->where(function ($query) use ($tableDetails, $pageMorphClass) { })->where(function ($query) use ($tableDetails, $pageMorphClass) {
/** @var Builder $query */ /** @var Builder $query */
$query->where($tableDetails['entityTypeColumn'], '!=', $pageMorphClass) $query->where($tableDetails['entityTypeColumn'], '!=', $pageMorphClass)
@ -238,7 +255,6 @@ class PermissionApplicator
$fullPageIdColumn = $tableName . '.' . $pageIdColumn; $fullPageIdColumn = $tableName . '.' . $pageIdColumn;
$morphClass = (new Page())->getMorphClass(); $morphClass = (new Page())->getMorphClass();
// TODO - Update for user permission
$existsQuery = function ($permissionQuery) use ($fullPageIdColumn, $morphClass) { $existsQuery = function ($permissionQuery) use ($fullPageIdColumn, $morphClass) {
/** @var Builder $permissionQuery */ /** @var Builder $permissionQuery */
$permissionQuery->select('joint_permissions.role_id')->from('joint_permissions') $permissionQuery->select('joint_permissions.role_id')->from('joint_permissions')
@ -250,10 +266,22 @@ class PermissionApplicator
}); });
}; };
$q = $query->where(function ($query) use ($existsQuery, $fullPageIdColumn) { $userExistsQuery = function ($hasPermission) use ($fullPageIdColumn, $morphClass) {
return function ($permissionQuery) use ($fullPageIdColumn, $morphClass) {
/** @var Builder $permissionQuery */
$permissionQuery->select('joint_user_permissions.user_id')->from('joint_user_permissions')
->whereColumn('joint_user_permissions.entity_id', '=', $fullPageIdColumn)
->where('joint_user_permissions.entity_type', '=', $morphClass)
->where('joint_user_permissions.user_id', $this->currentUser()->id)
->where('has_permission', '=', true);
};
};
$q = $query->where(function ($query) use ($existsQuery, $userExistsQuery, $fullPageIdColumn) {
$query->whereExists($existsQuery) $query->whereExists($existsQuery)
->orWhereExists($userExistsQuery(true))
->orWhere($fullPageIdColumn, '=', 0); ->orWhere($fullPageIdColumn, '=', 0);
}); })->whereNotExists($userExistsQuery(false));
// Prevent visibility of non-owned draft pages // Prevent visibility of non-owned draft pages
$q->whereExists(function (QueryBuilder $query) use ($fullPageIdColumn) { $q->whereExists(function (QueryBuilder $query) use ($fullPageIdColumn) {

View File

@ -10,6 +10,7 @@ use BookStack\Actions\View;
use BookStack\Auth\Permissions\EntityPermission; use BookStack\Auth\Permissions\EntityPermission;
use BookStack\Auth\Permissions\JointPermission; use BookStack\Auth\Permissions\JointPermission;
use BookStack\Auth\Permissions\JointPermissionBuilder; use BookStack\Auth\Permissions\JointPermissionBuilder;
use BookStack\Auth\Permissions\JointUserPermission;
use BookStack\Auth\Permissions\PermissionApplicator; use BookStack\Auth\Permissions\PermissionApplicator;
use BookStack\Entities\Tools\SlugGenerator; use BookStack\Entities\Tools\SlugGenerator;
use BookStack\Interfaces\Deletable; use BookStack\Interfaces\Deletable;
@ -194,6 +195,14 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
return $this->morphMany(JointPermission::class, 'entity'); return $this->morphMany(JointPermission::class, 'entity');
} }
/**
* Get the join user permissions for this entity.
*/
public function jointUserPermissions(): MorphMany
{
return $this->morphMany(JointUserPermission::class, 'entity');
}
/** /**
* Get the related delete records for this entity. * Get the related delete records for this entity.
*/ */