Permission checks on twentyORM global manager (#11477)

In this PR we are handling permissions when using
twentyORMGlobalManager,
and handling permissions for rest api and api key
This commit is contained in:
Marie
2025-04-23 17:57:48 +02:00
committed by GitHub
parent 28a1354928
commit 4257f30f12
54 changed files with 547 additions and 116 deletions

View File

@ -1,16 +1,17 @@
import { BadRequestException, Injectable } from '@nestjs/common';
import { capitalize, isDefined } from 'twenty-shared/utils';
import { Request } from 'express';
import { capitalize, isDefined } from 'twenty-shared/utils';
import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
import { CoreQueryBuilderFactory } from 'src/engine/api/rest/core/query-builder/core-query-builder.factory';
import { parseCorePath } from 'src/engine/api/rest/core/query-builder/utils/path-parsers/parse-core-path.utils';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { RecordInputTransformerService } from 'src/engine/core-modules/record-transformer/services/record-input-transformer.service';
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { RecordInputTransformerService } from 'src/engine/core-modules/record-transformer/services/record-input-transformer.service';
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
@Injectable()
export class RestApiCoreServiceV2 {
@ -19,6 +20,7 @@ export class RestApiCoreServiceV2 {
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly recordInputTransformerService: RecordInputTransformerService,
protected readonly apiEventEmitterService: ApiEventEmitterService,
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
) {}
async delete(request: Request) {
@ -137,7 +139,7 @@ export class RestApiCoreServiceV2 {
}
private async getRepositoryAndMetadataOrFail(request: Request) {
const { workspace } = request;
const { workspace, apiKey, userWorkspaceId } = request;
const { object: parsedObject } = parseCorePath(request);
const objectMetadata = await this.coreQueryBuilderFactory.getObjectMetadata(
@ -153,13 +155,25 @@ export class RestApiCoreServiceV2 {
throw new BadRequestException('Workspace not found');
}
const dataSource =
await this.twentyORMGlobalManager.getDataSourceForWorkspace(workspace.id);
const objectMetadataNameSingular =
objectMetadata.objectMetadataMapItem.nameSingular;
const repository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace<ObjectRecord>(
workspace.id,
objectMetadataNameSingular,
);
const shouldBypassPermissionChecks = !!apiKey;
const roleId =
await this.workspacePermissionsCacheService.getRoleIdFromUserWorkspaceId({
workspaceId: workspace.id,
userWorkspaceId,
});
const repository = dataSource.getRepository<ObjectRecord>(
objectMetadataNameSingular,
shouldBypassPermissionChecks,
roleId,
);
return {
objectMetadataNameSingular,

View File

@ -1,6 +1,7 @@
import { HttpModule } from '@nestjs/axios';
import { Module } from '@nestjs/common';
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
import { RestApiCoreBatchController } from 'src/engine/api/rest/core/controllers/rest-api-core-batch.controller';
import { RestApiCoreController } from 'src/engine/api/rest/core/controllers/rest-api-core.controller';
import { CoreQueryBuilderModule } from 'src/engine/api/rest/core/query-builder/core-query-builder.module';
@ -15,9 +16,9 @@ import { RestApiMetadataService } from 'src/engine/api/rest/metadata/rest-api-me
import { RestApiService } from 'src/engine/api/rest/rest-api.service';
import { AuthModule } from 'src/engine/core-modules/auth/auth.module';
import { RecordTransformerModule } from 'src/engine/core-modules/record-transformer/record-transformer.module';
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
@Module({
imports: [
@ -28,6 +29,7 @@ import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-run
HttpModule,
TwentyORMModule,
RecordTransformerModule,
WorkspacePermissionsCacheModule,
],
controllers: [
RestApiMetadataController,