[permissions] Fix rest api (#12608)

We need to use twentyORMManager and not twentyORMGlobalManager in rest
api base handler, because we don't want to bypass permissions using
`shouldBypassPermissions` parameter (which we would have to do to use
twentyORMGlobalManager).

ScopedWorkspaceContextFactory was not adapted to rest api requests which
form differs from graphql request.
This commit is contained in:
Marie
2025-06-16 10:42:55 +02:00
committed by GitHub
parent a05c659e03
commit 929586e4a9
4 changed files with 21 additions and 17 deletions

View File

@ -33,7 +33,7 @@ import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modu
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service'; import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
import { WorkspaceSelectQueryBuilder } from 'src/engine/twenty-orm/repository/workspace-select-query-builder'; import { WorkspaceSelectQueryBuilder } from 'src/engine/twenty-orm/repository/workspace-select-query-builder';
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository'; import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { formatResult as formatGetManyData } from 'src/engine/twenty-orm/utils/format-result.util'; import { formatResult as formatGetManyData } from 'src/engine/twenty-orm/utils/format-result.util';
export interface PageInfo { export interface PageInfo {
@ -72,7 +72,7 @@ export abstract class RestApiBaseHandler {
@Inject() @Inject()
protected readonly coreQueryBuilderFactory: CoreQueryBuilderFactory; protected readonly coreQueryBuilderFactory: CoreQueryBuilderFactory;
@Inject() @Inject()
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager; protected readonly twentyORMManager: TwentyORMManager;
@Inject() @Inject()
protected readonly getVariablesFactory: GetVariablesFactory; protected readonly getVariablesFactory: GetVariablesFactory;
@Inject() @Inject()
@ -105,11 +105,7 @@ export abstract class RestApiBaseHandler {
throw new BadRequestException('Workspace not found'); throw new BadRequestException('Workspace not found');
} }
const workspaceDataSource = const workspaceDataSource = await this.twentyORMManager.getDatasource();
await this.twentyORMGlobalManager.getDataSourceForWorkspace({
workspaceId: workspace.id,
shouldFailIfMetadataNotFound: false,
});
const objectMetadataNameSingular = const objectMetadataNameSingular =
objectMetadata.objectMetadataMapItem.nameSingular; objectMetadata.objectMetadataMapItem.nameSingular;

View File

@ -222,11 +222,11 @@ export class WorkspacePermissionsCacheService {
return; return;
} }
const userWorkspaceRoleMap = await this.getUserWorkspaceRoleMapFromCache({ const { data: userWorkspaceRoleMap } =
workspaceId, await this.getUserWorkspaceRoleMapFromCache({
}); workspaceId,
});
// @ts-expect-error legacy noImplicitAny
return userWorkspaceRoleMap[userWorkspaceId]; return userWorkspaceRoleMap[userWorkspaceId];
} }

View File

@ -19,7 +19,9 @@ export class ScopedWorkspaceContextFactory {
// @ts-expect-error legacy noImplicitAny // @ts-expect-error legacy noImplicitAny
this.request?.['req']?.['workspaceId'] || this.request?.['req']?.['workspaceId'] ||
// @ts-expect-error legacy noImplicitAny // @ts-expect-error legacy noImplicitAny
this.request?.['params']?.['workspaceId']; this.request?.['params']?.['workspaceId'] ||
// @ts-expect-error legacy noImplicitAny
this.request?.['workspace']?.['id']; // rest api
const workspaceMetadataVersion: number | undefined = const workspaceMetadataVersion: number | undefined =
// @ts-expect-error legacy noImplicitAny // @ts-expect-error legacy noImplicitAny
this.request?.['req']?.['workspaceMetadataVersion']; this.request?.['req']?.['workspaceMetadataVersion'];
@ -27,10 +29,16 @@ export class ScopedWorkspaceContextFactory {
return { return {
workspaceId: workspaceId ?? null, workspaceId: workspaceId ?? null,
workspaceMetadataVersion: workspaceMetadataVersion ?? null, workspaceMetadataVersion: workspaceMetadataVersion ?? null,
// @ts-expect-error legacy noImplicitAny userWorkspaceId:
userWorkspaceId: this.request?.['req']?.['userWorkspaceId'] ?? null, // @ts-expect-error legacy noImplicitAny
// @ts-expect-error legacy noImplicitAny this.request?.['req']?.['userWorkspaceId'] ??
isExecutedByApiKey: !!this.request?.['req']?.['apiKey'], // @ts-expect-error legacy noImplicitAny
this.request?.['userWorkspaceId'] ?? // rest api
null,
isExecutedByApiKey: !!(
// @ts-expect-error legacy noImplicitAny
(this.request?.['req']?.['apiKey'] || this.request?.['apiKey'])
),
}; };
} }
} }

View File

@ -1,10 +1,10 @@
import { TEST_COMPANY_1_ID } from 'test/integration/constants/test-company-ids.constants'; import { TEST_COMPANY_1_ID } from 'test/integration/constants/test-company-ids.constants';
import { TEST_PERSON_1_ID } from 'test/integration/constants/test-person-ids.constants'; import { TEST_PERSON_1_ID } from 'test/integration/constants/test-person-ids.constants';
import { TEST_PRIMARY_LINK_URL } from 'test/integration/constants/test-primary-link-url.constant'; import { TEST_PRIMARY_LINK_URL } from 'test/integration/constants/test-primary-link-url.constant';
import { TIM_ACCOUNT_ID } from 'test/integration/graphql/integration.constants';
import { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util'; import { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util';
import { deleteAllRecords } from 'test/integration/utils/delete-all-records'; import { deleteAllRecords } from 'test/integration/utils/delete-all-records';
import { generateRecordName } from 'test/integration/utils/generate-record-name'; import { generateRecordName } from 'test/integration/utils/generate-record-name';
import { TIM_ACCOUNT_ID } from 'test/integration/graphql/integration.constants';
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type'; import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';