Add missing row lvl permission check on Kanban view (#19002)

The Kanban view builds a query in two layers:
- Inner query — selects actual records from the table (has all the
permission context)
- Outer query — wraps the inner query's raw SQL string to do
grouping/pagination
The problem: the inner query's SQL is copied out as a plain string
before RLS predicates are added to it. RLS predicates are normally added
lazily when you execute the query, but here the execution happens on the
outer query — which doesn't know about the entity or its RLS rules.

So RLS predicates are never applied anywhere.

The fix: explicitly apply RLS predicates to the inner query before its
SQL is extracted.

Additonnaly, fixed a temporal issue in Datetime pickers.
This commit is contained in:
Thomas Trompette
2026-03-26 14:20:05 +00:00
committed by GitHub
parent 82611de9b6
commit 2e015ee68d
4 changed files with 269 additions and 9 deletions
@@ -23,6 +23,7 @@ import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/typ
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { type WorkspaceSelectQueryBuilder } from 'src/engine/twenty-orm/repository/workspace-select-query-builder';
import { applyRowLevelPermissionPredicates } from 'src/engine/twenty-orm/utils/apply-row-level-permission-predicates.util';
import { type WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
const RECORDS_PER_GROUP_LIMIT = 10;
@@ -84,6 +85,14 @@ export class GroupByWithRecordsService {
flatFieldMetadataMaps,
});
applyRowLevelPermissionPredicates({
queryBuilder: queryBuilderWithFiltersAndWithoutGroupBy,
objectMetadata: flatObjectMetadata,
internalContext: queryBuilderWithFiltersAndWithoutGroupBy.internalContext,
authContext: queryBuilderWithFiltersAndWithoutGroupBy.authContext,
featureFlagMap: queryBuilderWithFiltersAndWithoutGroupBy.featureFlagMap,
});
const queryBuilderWithPartitionBy = this.addPartitionByToQueryBuilder({
queryBuilderForSubQuery: queryBuilderWithFiltersAndWithoutGroupBy,
columnsToSelect,