[permissions] Add permissions check layer in entityManager (#11818)
First and main step of https://github.com/twentyhq/core-team-issues/issues/747 We are implementing a permission check layer in our custom WorkspaceEntityManager by overriding all the db-executing methods (this PR only overrides some as a POC, the rest will be done in the next PR). Our custom repositories call entity managers under the hood to interact with the db so this solves the repositories case too. This is still behind the feature flag IsPermissionsV2Enabled. In the next PR - finish overriding all the methods required in WorkspaceEntityManager - add tests
This commit is contained in:
@ -1,13 +1,15 @@
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { COMPANIES_DEMO } from 'src/engine/workspace-manager/demo-objects-prefill-data/companies-demo.json';
|
||||
|
||||
export const seedCompanyWithDemoData = async (
|
||||
entityManager: EntityManager,
|
||||
entityManager: WorkspaceEntityManager,
|
||||
schemaName: string,
|
||||
) => {
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.company`, [
|
||||
'name',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { DEMO_SEED_WORKSPACE_MEMBER_IDS } from 'src/engine/workspace-manager/demo-objects-prefill-data/seed-workspace-member-with-demo-data';
|
||||
import { EntityManager } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
const tableName = 'opportunity';
|
||||
@ -33,7 +33,7 @@ const generateOpportunities = (companies) => {
|
||||
};
|
||||
|
||||
export const seedOpportunityWithDemoData = async (
|
||||
entityManager: EntityManager,
|
||||
entityManager: WorkspaceEntityManager,
|
||||
schemaName: string,
|
||||
) => {
|
||||
const companiesWithPeople = await entityManager?.query(
|
||||
@ -46,7 +46,9 @@ export const seedOpportunityWithDemoData = async (
|
||||
const opportunities = generateOpportunities(companiesWithPeople);
|
||||
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.${tableName}`, [
|
||||
'id',
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { peopleDemo } from 'src/engine/workspace-manager/demo-objects-prefill-data/people-demo.json';
|
||||
|
||||
export const seedPersonWithDemoData = async (
|
||||
entityManager: EntityManager,
|
||||
entityManager: WorkspaceEntityManager,
|
||||
schemaName: string,
|
||||
) => {
|
||||
const companies = await entityManager?.query(
|
||||
@ -27,7 +27,9 @@ export const seedPersonWithDemoData = async (
|
||||
}));
|
||||
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.person`, [
|
||||
'nameFirstName',
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { DEMO_SEED_USER_IDS } from 'src/database/typeorm-seeds/core/demo/users';
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
|
||||
export const DEMO_SEED_WORKSPACE_MEMBER_IDS = {
|
||||
@ -10,11 +10,13 @@ export const DEMO_SEED_WORKSPACE_MEMBER_IDS = {
|
||||
};
|
||||
|
||||
export const seedWorkspaceMemberWithDemoData = async (
|
||||
entityManager: EntityManager,
|
||||
entityManager: WorkspaceEntityManager,
|
||||
schemaName: string,
|
||||
) => {
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.workspaceMember`, [
|
||||
'id',
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { DataSource, EntityManager } from 'typeorm';
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
import { seedWorkspaceFavorites } from 'src/database/typeorm-seeds/workspace/favorites';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { shouldSeedWorkspaceFavorite } from 'src/engine/utils/should-seed-workspace-favorite';
|
||||
import { seedCompanyWithDemoData } from 'src/engine/workspace-manager/demo-objects-prefill-data/seed-company-with-demo-data';
|
||||
import { seedOpportunityWithDemoData } from 'src/engine/workspace-manager/demo-objects-prefill-data/seed-opportunity-with-demo-data';
|
||||
@ -28,7 +29,7 @@ export const seedWorkspaceWithDemoData = async (
|
||||
}, {});
|
||||
|
||||
await workspaceDataSource.transaction(
|
||||
async (entityManager: EntityManager) => {
|
||||
async (entityManager: WorkspaceEntityManager) => {
|
||||
await seedCompanyWithDemoData(entityManager, schemaName);
|
||||
await seedPersonWithDemoData(entityManager, schemaName);
|
||||
await seedOpportunityWithDemoData(entityManager, schemaName);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
|
||||
export const AIRBNB_ID = 'c776ee49-f608-4a77-8cc8-6fe96ae1e43f';
|
||||
export const QONTO_ID = 'f45ee421-8a3e-4aa5-a1cf-7207cc6754e1';
|
||||
@ -9,11 +8,13 @@ export const FIGMA_ID = '9d5bcf43-7d38-4e88-82cb-d6d4ce638bf0';
|
||||
export const NOTION_ID = '06290608-8bf0-4806-99ae-a715a6a93fad';
|
||||
|
||||
export const companyPrefillData = async (
|
||||
entityManager: EntityManager,
|
||||
entityManager: WorkspaceEntityManager,
|
||||
schemaName: string,
|
||||
) => {
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.company`, [
|
||||
'id',
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { EntityManager } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
|
||||
export const createWorkspaceViews = async (
|
||||
entityManager: EntityManager,
|
||||
entityManager: WorkspaceEntityManager,
|
||||
schemaName: string,
|
||||
viewDefinitions: ViewDefinition[],
|
||||
) => {
|
||||
@ -14,7 +14,9 @@ export const createWorkspaceViews = async (
|
||||
}));
|
||||
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.view`, [
|
||||
'id',
|
||||
@ -64,7 +66,9 @@ export const createWorkspaceViews = async (
|
||||
for (const viewDefinition of viewDefinitionsWithId) {
|
||||
if (viewDefinition.fields && viewDefinition.fields.length > 0) {
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.viewField`, [
|
||||
'fieldMetadataId',
|
||||
@ -89,7 +93,9 @@ export const createWorkspaceViews = async (
|
||||
|
||||
if (viewDefinition.filters && viewDefinition.filters.length > 0) {
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.viewFilter`, [
|
||||
'fieldMetadataId',
|
||||
@ -116,7 +122,9 @@ export const createWorkspaceViews = async (
|
||||
viewDefinition.groups.length > 0
|
||||
) {
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.viewGroup`, [
|
||||
'fieldMetadataId',
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import {
|
||||
AIRBNB_ID,
|
||||
FIGMA_ID,
|
||||
@ -11,11 +10,13 @@ import {
|
||||
|
||||
// FixMe: Is this file a duplicate of src/database/typeorm-seeds/workspace/people.ts
|
||||
export const personPrefillData = async (
|
||||
entityManager: EntityManager,
|
||||
entityManager: WorkspaceEntityManager,
|
||||
schemaName: string,
|
||||
) => {
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
})
|
||||
.insert()
|
||||
.into(`${schemaName}.person`, [
|
||||
'nameFirstName',
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { ObjectMetadataStandardIdToIdMap } from 'src/engine/metadata-modules/object-metadata/interfaces/object-metadata-standard-id-to-id-map';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { createWorkspaceViews } from 'src/engine/workspace-manager/standard-objects-prefill-data/create-workspace-views';
|
||||
import { seedCompaniesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/companies-all.view';
|
||||
import { notesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/notes-all.view';
|
||||
@ -16,7 +15,7 @@ import { workflowVersionsAllView } from 'src/engine/workspace-manager/standard-o
|
||||
import { workflowsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/workflows-all.view';
|
||||
|
||||
export const seedViewWithDemoData = async (
|
||||
entityManager: EntityManager,
|
||||
entityManager: WorkspaceEntityManager,
|
||||
schemaName: string,
|
||||
objectMetadataStandardIdToIdMap: ObjectMetadataStandardIdToIdMap,
|
||||
) => {
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { DataSource, EntityManager } from 'typeorm';
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
import { seedWorkspaceFavorites } from 'src/database/typeorm-seeds/workspace/favorites';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { shouldSeedWorkspaceFavorite } from 'src/engine/utils/should-seed-workspace-favorite';
|
||||
import { companyPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/company';
|
||||
import { personPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/person';
|
||||
@ -33,28 +34,30 @@ export const standardObjectsPrefillData = async (
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
workspaceDataSource.transaction(async (entityManager: EntityManager) => {
|
||||
await companyPrefillData(entityManager, schemaName);
|
||||
await personPrefillData(entityManager, schemaName);
|
||||
const viewDefinitionsWithId = await seedViewWithDemoData(
|
||||
entityManager,
|
||||
schemaName,
|
||||
objectMetadataMap,
|
||||
);
|
||||
workspaceDataSource.transaction(
|
||||
async (entityManager: WorkspaceEntityManager) => {
|
||||
await companyPrefillData(entityManager, schemaName);
|
||||
await personPrefillData(entityManager, schemaName);
|
||||
const viewDefinitionsWithId = await seedViewWithDemoData(
|
||||
entityManager,
|
||||
schemaName,
|
||||
objectMetadataMap,
|
||||
);
|
||||
|
||||
await seedWorkspaceFavorites(
|
||||
viewDefinitionsWithId
|
||||
.filter(
|
||||
(view) =>
|
||||
view.key === 'INDEX' &&
|
||||
shouldSeedWorkspaceFavorite(
|
||||
view.objectMetadataId,
|
||||
objectMetadataMap,
|
||||
),
|
||||
)
|
||||
.map((view) => view.id),
|
||||
entityManager,
|
||||
schemaName,
|
||||
);
|
||||
});
|
||||
await seedWorkspaceFavorites(
|
||||
viewDefinitionsWithId
|
||||
.filter(
|
||||
(view) =>
|
||||
view.key === 'INDEX' &&
|
||||
shouldSeedWorkspaceFavorite(
|
||||
view.objectMetadataId,
|
||||
objectMetadataMap,
|
||||
),
|
||||
)
|
||||
.map((view) => view.id),
|
||||
entityManager,
|
||||
schemaName,
|
||||
);
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user