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
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
2 changed files with 51 additions and 14 deletions
app
Auth/Permissions
Entities/Models

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

@ -10,6 +10,7 @@ use BookStack\Actions\View;
use BookStack\Auth\Permissions\EntityPermission;
use BookStack\Auth\Permissions\JointPermission;
use BookStack\Auth\Permissions\JointPermissionBuilder;
use BookStack\Auth\Permissions\JointUserPermission;
use BookStack\Auth\Permissions\PermissionApplicator;
use BookStack\Entities\Tools\SlugGenerator;
use BookStack\Interfaces\Deletable;
@ -194,6 +195,14 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
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.
*/