Now all tests are passing.
Some level of manual checks to do.
*/
public function restrictPageRelationQuery(Builder $query, string $tableName, string $pageIdColumn): Builder
{
- // TODO - Refactor
$fullPageIdColumn = $tableName . '.' . $pageIdColumn;
- $morphClass = (new Page())->getMorphClass();
-
- $existsQuery = function ($permissionQuery) use ($fullPageIdColumn, $morphClass) {
- /** @var Builder $permissionQuery */
- $permissionQuery->select('joint_permissions.role_id')->from('joint_permissions')
- ->whereColumn('joint_permissions.entity_id', '=', $fullPageIdColumn)
- ->where('joint_permissions.entity_type', '=', $morphClass)
- ->whereIn('joint_permissions.role_id', $this->getCurrentUserRoleIds())
- ->where(function (QueryBuilder $query) {
- $this->addJointHasPermissionCheck($query, $this->currentUser()->id);
- });
- };
-
- $q = $query->where(function ($query) use ($existsQuery, $fullPageIdColumn) {
- $query->whereExists($existsQuery)
- ->orWhere($fullPageIdColumn, '=', 0);
- });
-
- // Prevent visibility of non-owned draft pages
- $q->whereExists(function (QueryBuilder $query) use ($fullPageIdColumn) {
- $query->select('id')->from('pages')
- ->whereColumn('pages.id', '=', $fullPageIdColumn)
- ->where(function (QueryBuilder $query) {
- $query->where('pages.draft', '=', false)
- ->orWhere('pages.owned_by', '=', $this->currentUser()->id);
+ return $this->restrictEntityQuery($query)
+ ->where(function ($query) use ($fullPageIdColumn) {
+ /** @var Builder $query */
+ $query->whereExists(function (QueryBuilder $query) use ($fullPageIdColumn) {
+ $query->select('id')->from('pages')
+ ->whereColumn('pages.id', '=', $fullPageIdColumn)
+ ->where('pages.draft', '=', false);
});
- });
-
- return $q;
- }
-
- /**
- * Add the query for checking the given user id has permission
- * within the join_permissions table.
- *
- * @param QueryBuilder|Builder $query
- */
- protected function addJointHasPermissionCheck($query, int $userIdToCheck)
- {
- $query->where('joint_permissions.has_permission', '=', true)->orWhere(function ($query) use ($userIdToCheck) {
- $query->where('joint_permissions.has_permission_own', '=', true)
- ->where('joint_permissions.owned_by', '=', $userIdToCheck);
- });
+ });
}
/**
public function attachRole(Role $role)
{
$this->roles()->attach($role->id);
+ $this->unsetRelation('roles');
}
/**
namespace BookStack\Uploads;
+use BookStack\Auth\Permissions\JointPermission;
use BookStack\Auth\Permissions\PermissionApplicator;
use BookStack\Auth\User;
use BookStack\Entities\Models\Entity;
use BookStack\Traits\HasCreatorAndUpdater;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
return $this->belongsTo(Page::class, 'uploaded_to');
}
+ public function jointPermissions(): HasMany
+ {
+ return $this->hasMany(JointPermission::class, 'entity_id', 'uploaded_to')
+ ->where('joint_permissions.entity_type', '=', 'page');
+ }
+
/**
* Get the url of this file.
*/
namespace BookStack\Uploads;
+use BookStack\Auth\Permissions\JointPermission;
use BookStack\Entities\Models\Page;
use BookStack\Model;
use BookStack\Traits\HasCreatorAndUpdater;
use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
protected $fillable = ['name'];
protected $hidden = [];
+ public function jointPermissions(): HasMany
+ {
+ return $this->hasMany(JointPermission::class, 'entity_id', 'uploaded_to')
+ ->where('joint_permissions.entity_type', '=', 'page');
+ }
+
/**
* Get a thumbnail for this image.
*
'entity_id' => $page->id,
'entity_type' => 'page',
'role_id' => $role->id,
- 'has_permission' => 1,
+ 'status' => 3, // Explicit allow
]);
$page->permissions()->delete();
$chapter = $this->entities->chapter();
$book = $chapter->book;
- $this->permissions->setEntityPermissions($book, ['edit'], [$viewerRole], false);
+ $this->permissions->setEntityPermissions($book, ['update'], [$viewerRole], false);
$this->permissions->setEntityPermissions($chapter, [], [$viewerRole], true);
$this->assertFalse(userCan('chapter-update', $chapter));
$chapter = $this->entities->chapter();
$book = $chapter->book;
- $this->permissions->setEntityPermissions($book, ['edit'], [$editorRole], false);
+ $this->permissions->setEntityPermissions($book, ['update'], [$editorRole], false);
$this->permissions->setEntityPermissions($chapter, [], [$viewerRole], true);
+ $this->actingAs($user);
$this->assertTrue(userCan('chapter-update', $chapter));
}