[permissions] Remove raw queries and restrict its usage (#12360)

Closes https://github.com/twentyhq/core-team-issues/issues/748

In the frame of the work on permissions we

- remove all raw queries possible to use repositories instead
- forbid usage workspaceDataSource.executeRawQueries()
- restrict usage of workspaceDataSource.query() to force developers to
pass on shouldBypassPermissionChecks to use it.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
Marie
2025-06-02 10:53:51 +02:00
committed by GitHub
parent 1ef7b7a474
commit 9706f0df13
49 changed files with 495 additions and 754 deletions

View File

@ -11,6 +11,10 @@ import {
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
import {
PermissionsException,
PermissionsExceptionCode,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
import { WorkspaceQueryRunner } from 'src/engine/twenty-orm/query-runner/workspace-query-runner';
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
@ -79,6 +83,26 @@ export class WorkspaceDataSource extends DataSource {
return queryRunner as any as WorkspaceQueryRunner;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
override query<T = any>(
query: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
parameters?: any[],
queryRunner?: QueryRunner,
options?: {
shouldBypassPermissionChecks?: boolean;
},
): Promise<T> {
if (!options?.shouldBypassPermissionChecks) {
throw new PermissionsException(
'Method not allowed because permissions are not implemented at datasource level.',
PermissionsExceptionCode.METHOD_NOT_ALLOWED,
);
}
return super.query(query, parameters, queryRunner);
}
setRolesPermissionsVersion(rolesPermissionsVersion: string) {
this.rolesPermissionsVersion = rolesPermissionsVersion;
}

View File

@ -406,15 +406,6 @@ export class WorkspaceEntityManager extends EntityManager {
return this.connection.getMetadata(entity.constructor).name;
}
// Forbidden methods
// eslint-disable-next-line @typescript-eslint/no-explicit-any
override query<T = any>(_query: string, _parameters?: any[]): Promise<T> {
throw new Error('Method not allowed.');
}
// Not in use methods - duplicated from TypeORM's EntityManager to use our createQueryBuilder
override find<Entity extends ObjectLiteral>(
entityClass: EntityTarget<Entity>,
options?: FindManyOptions<Entity>,
@ -1098,4 +1089,14 @@ export class WorkspaceEntityManager extends EntityManager {
return super.decrement(target, criteria, propertyPath, value);
}
// Forbidden methods
// eslint-disable-next-line @typescript-eslint/no-explicit-any
override query<T = any>(_query: string, _parameters?: any[]): Promise<T> {
throw new PermissionsException(
'Method not allowed.',
PermissionsExceptionCode.RAW_SQL_NOT_ALLOWED,
);
}
}

View File

@ -24,6 +24,10 @@ import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import {
PermissionsException,
PermissionsExceptionCode,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modules/utils/get-object-metadata-map-item-by-name-singular.util';
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
@ -890,7 +894,10 @@ export class WorkspaceRepository<
* DEPRECATED AND RESTRICTED METHODS
*/
override async query(): Promise<unknown> {
throw new Error('Method not allowed.');
throw new PermissionsException(
'Method not allowed.',
PermissionsExceptionCode.RAW_SQL_NOT_ALLOWED,
);
}
override async findByIds(): Promise<T[]> {