[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:
@ -1,130 +0,0 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { InjectDataSource } from '@nestjs/typeorm';
|
||||
|
||||
import { Command, CommandRunner, Option } from 'nest-commander';
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
|
||||
interface RunCommandOptions {
|
||||
workspaceId?: string;
|
||||
}
|
||||
|
||||
@Command({
|
||||
name: 'workspace:convert-record-positions-to-integers',
|
||||
description: 'Convert record positions to integers',
|
||||
})
|
||||
export class ConvertRecordPositionsToIntegers extends CommandRunner {
|
||||
private readonly logger = new Logger(ConvertRecordPositionsToIntegers.name);
|
||||
|
||||
constructor(
|
||||
@InjectDataSource('metadata')
|
||||
private readonly metadataDataSource: DataSource,
|
||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async run(_passedParam: string[], options: RunCommandOptions): Promise<void> {
|
||||
const queryRunner = this.metadataDataSource.createQueryRunner();
|
||||
const workspaceId = options.workspaceId;
|
||||
|
||||
if (!workspaceId || typeof workspaceId !== 'string') {
|
||||
this.logger.error('Workspace id is required');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const customObjectMetadataCollection = await this.metadataDataSource
|
||||
.getRepository(ObjectMetadataEntity)
|
||||
.findBy({
|
||||
workspaceId,
|
||||
isCustom: true,
|
||||
});
|
||||
|
||||
const customObjectTableNames = customObjectMetadataCollection.map(
|
||||
(metadata) => metadata.nameSingular,
|
||||
);
|
||||
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
|
||||
const transactionManager = queryRunner.manager;
|
||||
|
||||
this.logger.log('Converting record positions to integers');
|
||||
|
||||
try {
|
||||
await this.convertRecordPositionsToIntegers(
|
||||
customObjectTableNames,
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
} catch (error) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
this.logger.error('Error converting record positions to integers', error);
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
this.logger.log('Record positions converted to integers');
|
||||
}
|
||||
}
|
||||
|
||||
private async convertRecordPositionsToIntegers(
|
||||
customObjectTableNames: string[],
|
||||
workspaceId: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
transactionManager: any,
|
||||
): Promise<void> {
|
||||
const dataSourceSchema =
|
||||
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||
|
||||
for (const tableName of ['company', 'person', 'opportunity']) {
|
||||
await this.convertRecordPositionsToIntegersForTable(
|
||||
tableName,
|
||||
dataSourceSchema,
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
}
|
||||
|
||||
for (const tableName of customObjectTableNames) {
|
||||
await this.convertRecordPositionsToIntegersForTable(
|
||||
`_${tableName}`,
|
||||
dataSourceSchema,
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async convertRecordPositionsToIntegersForTable(
|
||||
tableName: string,
|
||||
dataSourceSchema: string,
|
||||
workspaceId: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
transactionManager: any,
|
||||
): Promise<void> {
|
||||
await this.workspaceDataSourceService.executeRawQuery(
|
||||
`UPDATE ${dataSourceSchema}."${tableName}" SET position = subquery.position
|
||||
FROM (
|
||||
SELECT id, ROW_NUMBER() OVER (ORDER BY position) as position
|
||||
FROM ${dataSourceSchema}."${tableName}"
|
||||
) as subquery
|
||||
WHERE ${dataSourceSchema}."${tableName}".id = subquery.id`,
|
||||
[],
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
}
|
||||
|
||||
@Option({
|
||||
flags: '-w, --workspace-id [workspace_id]',
|
||||
description: 'workspace id',
|
||||
required: true,
|
||||
})
|
||||
parseWorkspaceId(value: string): string {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@ -7,9 +7,8 @@ import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.mod
|
||||
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { WorkspaceHealthModule } from 'src/engine/workspace-manager/workspace-health/workspace-health.module';
|
||||
import { ConvertRecordPositionsToIntegers } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/convert-record-positions-to-integers.command';
|
||||
import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module';
|
||||
import { SyncWorkspaceLoggerModule } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.module';
|
||||
import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module';
|
||||
|
||||
import { SyncWorkspaceMetadataCommand } from './sync-workspace-metadata.command';
|
||||
|
||||
@ -24,7 +23,7 @@ import { SyncWorkspaceMetadataCommand } from './sync-workspace-metadata.command'
|
||||
TypeOrmModule.forFeature([Workspace], 'core'),
|
||||
SyncWorkspaceLoggerModule,
|
||||
],
|
||||
providers: [SyncWorkspaceMetadataCommand, ConvertRecordPositionsToIntegers],
|
||||
providers: [SyncWorkspaceMetadataCommand],
|
||||
exports: [SyncWorkspaceMetadataCommand],
|
||||
})
|
||||
export class WorkspaceSyncMetadataCommandsModule {}
|
||||
|
||||
Reference in New Issue
Block a user