]> BookStack Code Mirror - bookstack/commitdiff
Updated additional relation queries to apply permissions correctly
authorDan Brown <redacted>
Fri, 13 Jan 2023 22:13:31 +0000 (22:13 +0000)
committerDan Brown <redacted>
Fri, 13 Jan 2023 22:13:31 +0000 (22:13 +0000)
app/Actions/ActivityQueries.php
app/Actions/TagRepo.php
app/Auth/Permissions/PermissionApplicator.php

index 852913e634eb46e67909bf39154552d7d3e49515..88e6aa7e783485a47d67ba3ee91ddc744080e97f 100644 (file)
@@ -15,6 +15,8 @@ class ActivityQueries
 {
     protected PermissionApplicator $permissions;
 
+    protected array $fieldsForLists = ['id', 'type', 'detail', 'activities.entity_type', 'activities.entity_id', 'user_id', 'created_at'];
+
     public function __construct(PermissionApplicator $permissions)
     {
         $this->permissions = $permissions;
@@ -25,7 +27,7 @@ class ActivityQueries
      */
     public function latest(int $count = 20, int $page = 0): array
     {
-        $query = Activity::query()->select(['id', 'type', 'detail', 'activities.entity_type', 'activities.entity_id', 'user_id', 'created_at']);
+        $query = Activity::query()->select($this->fieldsForLists);
         $activityList = $this->permissions
             ->restrictEntityRelationQuery($query, 'activities', 'entity_id', 'entity_type')
             ->orderBy('created_at', 'desc')
@@ -79,8 +81,9 @@ class ActivityQueries
      */
     public function userActivity(User $user, int $count = 20, int $page = 0): array
     {
+        $query = Activity::query()->select($this->fieldsForLists);
         $activityList = $this->permissions
-            ->restrictEntityRelationQuery(Activity::query(), 'activities', 'entity_id', 'entity_type')
+            ->restrictEntityRelationQuery($query, 'activities', 'entity_id', 'entity_type')
             ->orderBy('created_at', 'desc')
             ->where('user_id', '=', $user->id)
             ->skip($count * $page)
index cece30de003b3a48b0d72f2d0e30b28e7dfa828e..176dbaa61a85cdce2430acbfb7b275c2d7e1a098 100644 (file)
@@ -29,15 +29,16 @@ class TagRepo
             $sort = 'value';
         }
 
+        $entityTypeCol = DB::getTablePrefix() . 'tags.entity_type';
         $query = Tag::query()
             ->select([
                 'name',
                 ($searchTerm || $nameFilter) ? 'value' : DB::raw('COUNT(distinct value) as `values`'),
                 DB::raw('COUNT(id) as usages'),
-                DB::raw('SUM(IF(entity_type = \'page\', 1, 0)) as page_count'),
-                DB::raw('SUM(IF(entity_type = \'chapter\', 1, 0)) as chapter_count'),
-                DB::raw('SUM(IF(entity_type = \'book\', 1, 0)) as book_count'),
-                DB::raw('SUM(IF(entity_type = \'bookshelf\', 1, 0)) as shelf_count'),
+                DB::raw("SUM(IF({$entityTypeCol} = 'page', 1, 0)) as page_count"),
+                DB::raw("SUM(IF({$entityTypeCol} = 'chapter', 1, 0)) as chapter_count"),
+                DB::raw("SUM(IF({$entityTypeCol} = 'book', 1, 0)) as book_count"),
+                DB::raw("SUM(IF({$entityTypeCol} = 'bookshelf', 1, 0)) as shelf_count"),
             ])
             ->orderBy($sort, $listOptions->getOrder());
 
index 64850fd8adda6f5c5bd4442141e896e4230a7949..c3ae2dce14354ac2ab5a9537e3c3957bc9ddad08 100644 (file)
@@ -319,10 +319,9 @@ class PermissionApplicator
      */
     public function restrictEntityRelationQuery($query, string $tableName, string $entityIdColumn, string $entityTypeColumn)
     {
+        // TODO - Apply admin allow all as per above query thing
         $this->applyPermissionsToQuery($query, $tableName, '', $entityIdColumn, $entityTypeColumn);
         // TODO - Test page draft access (Might allow drafts which should not be seen)
-        // TODO - Test each use of this to check column/relation fetching.
-        //    Original queries might need selects applied to limit field exposure and to get right original table columns.
 
         return $query;
     }
@@ -335,65 +334,12 @@ class PermissionApplicator
      */
     public function restrictPageRelationQuery(Builder $query, string $tableName, string $pageIdColumn): Builder
     {
-        $fullPageIdColumn = $tableName . '.' . $pageIdColumn;
         $morphClass = (new Page())->getMorphClass();
 
-        // TODO
+        $this->applyPermissionsToQuery($query, $tableName, $morphClass, $pageIdColumn, '');
+        // TODO - Admin workaround as above
+        // TODO - Draft display
         return $query;
-
-        $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);
-                });
-        };
-
-        $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) {
-            $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 $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);
-        });
     }
 
     /**