Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2f53487c49 | |||
| 498a0197c9 | |||
| 194ca85578 | |||
| e5defd686c | |||
| 38532ee0c3 | |||
| 30a51ae98e | |||
| ef99ec66a7 | |||
| 7af8fdb7a3 | |||
| 0b0ef20193 | |||
| ee8c74fba6 | |||
| 6d69808a4a | |||
| 411cb7332b | |||
| 100962e67b | |||
| 9bc64ae4d9 | |||
| 9483ba37b9 | |||
| e35ef97e78 | |||
| 4e8d2c706b | |||
| bc1570810a | |||
| 27f2a81207 | |||
| 23c2449d86 | |||
| b2beefb6d7 |
@@ -261,6 +261,7 @@ export enum AllMetadataName {
|
||||
pageLayout = 'pageLayout',
|
||||
pageLayoutTab = 'pageLayoutTab',
|
||||
pageLayoutWidget = 'pageLayoutWidget',
|
||||
permissionFlag = 'permissionFlag',
|
||||
role = 'role',
|
||||
roleTarget = 'roleTarget',
|
||||
rowLevelPermissionPredicate = 'rowLevelPermissionPredicate',
|
||||
|
||||
+2
@@ -30,6 +30,8 @@ export const useMetadataErrorHandler = () => {
|
||||
viewFilter: t`view filter`,
|
||||
index: t`index`,
|
||||
logicFunction: t`logic function`,
|
||||
objectPermission: t`object permission`,
|
||||
permissionFlag: t`permission flag`,
|
||||
role: t`role`,
|
||||
roleTarget: t`role target`,
|
||||
agent: t`agent`,
|
||||
|
||||
@@ -4157,6 +4157,7 @@ enum AllMetadataName {
|
||||
pageLayoutTab
|
||||
commandMenuItem
|
||||
navigationMenuItem
|
||||
permissionFlag
|
||||
frontComponent
|
||||
webhook
|
||||
}
|
||||
|
||||
@@ -2809,7 +2809,7 @@ export type AnalyticsType = 'PAGEVIEW' | 'TRACK'
|
||||
|
||||
export type WorkspaceMigrationActionType = 'delete' | 'create' | 'update'
|
||||
|
||||
export type AllMetadataName = 'fieldMetadata' | 'objectMetadata' | 'view' | 'viewField' | 'viewFieldGroup' | 'viewGroup' | 'viewSort' | 'rowLevelPermissionPredicate' | 'rowLevelPermissionPredicateGroup' | 'viewFilterGroup' | 'index' | 'logicFunction' | 'viewFilter' | 'role' | 'roleTarget' | 'agent' | 'skill' | 'pageLayout' | 'pageLayoutWidget' | 'pageLayoutTab' | 'commandMenuItem' | 'navigationMenuItem' | 'frontComponent' | 'webhook'
|
||||
export type AllMetadataName = 'fieldMetadata' | 'objectMetadata' | 'view' | 'viewField' | 'viewFieldGroup' | 'viewGroup' | 'viewSort' | 'rowLevelPermissionPredicate' | 'rowLevelPermissionPredicateGroup' | 'viewFilterGroup' | 'index' | 'logicFunction' | 'viewFilter' | 'role' | 'roleTarget' | 'agent' | 'skill' | 'pageLayout' | 'pageLayoutWidget' | 'pageLayoutTab' | 'commandMenuItem' | 'navigationMenuItem' | 'permissionFlag' | 'frontComponent' | 'webhook'
|
||||
|
||||
export type FileFolder = 'ProfilePicture' | 'WorkspaceLogo' | 'Attachment' | 'PersonPicture' | 'CorePicture' | 'File' | 'AgentChat' | 'BuiltLogicFunction' | 'BuiltFrontComponent' | 'PublicAsset' | 'Source' | 'FilesField' | 'Dependencies' | 'Workflow' | 'AppTarball'
|
||||
|
||||
@@ -8685,6 +8685,7 @@ export const enumAllMetadataName = {
|
||||
pageLayoutTab: 'pageLayoutTab' as const,
|
||||
commandMenuItem: 'commandMenuItem' as const,
|
||||
navigationMenuItem: 'navigationMenuItem' as const,
|
||||
permissionFlag: 'permissionFlag' as const,
|
||||
frontComponent: 'frontComponent' as const,
|
||||
webhook: 'webhook' as const
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddUniversalIdentifierAndApplicationIdToPermissionFlag1773232418467
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = 'AddUniversalIdentifierAndApplicationIdToPermissionFlag1773232418467';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."permissionFlag" ADD "universalIdentifier" uuid NOT NULL`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."permissionFlag" ADD "applicationId" uuid NOT NULL`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE UNIQUE INDEX "IDX_da8ffd3c24b4a819430a861067" ON "core"."permissionFlag" ("workspaceId", "universalIdentifier") `,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."permissionFlag" ADD CONSTRAINT "FK_b26a9d39a88d0e72373c677c6c5" FOREIGN KEY ("applicationId") REFERENCES "core"."application"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."permissionFlag" DROP CONSTRAINT "FK_b26a9d39a88d0e72373c677c6c5"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP INDEX "core"."IDX_da8ffd3c24b4a819430a861067"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."permissionFlag" DROP COLUMN "applicationId"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."permissionFlag" DROP COLUMN "universalIdentifier"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
+2
@@ -30,6 +30,8 @@ export const fromRoleManifestToUniversalFlatRole = ({
|
||||
canBeAssignedToAgents: roleManifest.canBeAssignedToAgents ?? true,
|
||||
canBeAssignedToApiKeys: roleManifest.canBeAssignedToApiKeys ?? true,
|
||||
roleTargetUniversalIdentifiers: [],
|
||||
objectPermissionUniversalIdentifiers: [],
|
||||
permissionFlagUniversalIdentifiers: [],
|
||||
rowLevelPermissionPredicateUniversalIdentifiers: [],
|
||||
rowLevelPermissionPredicateGroupUniversalIdentifiers: [],
|
||||
createdAt: now,
|
||||
|
||||
+7
@@ -172,6 +172,13 @@ exports[`ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY should ma
|
||||
"overrides",
|
||||
],
|
||||
},
|
||||
"permissionFlag": {
|
||||
"propertiesToCompare": [
|
||||
"flag",
|
||||
"roleUniversalIdentifier",
|
||||
],
|
||||
"propertiesToStringify": [],
|
||||
},
|
||||
"role": {
|
||||
"propertiesToCompare": [
|
||||
"label",
|
||||
|
||||
+64
@@ -1088,6 +1088,70 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = {
|
||||
universalProperty: 'targetObjectMetadataUniversalIdentifier',
|
||||
},
|
||||
},
|
||||
objectPermission: {
|
||||
roleId: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
universalProperty: 'roleUniversalIdentifier',
|
||||
},
|
||||
objectMetadataId: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
universalProperty: 'objectMetadataUniversalIdentifier',
|
||||
},
|
||||
canReadObjectRecords: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
canUpdateObjectRecords: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
canSoftDeleteObjectRecords: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
canDestroyObjectRecords: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
createdAt: {
|
||||
toCompare: false,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
updatedAt: {
|
||||
toCompare: false,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
},
|
||||
permissionFlag: {
|
||||
flag: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
roleId: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
universalProperty: 'roleUniversalIdentifier',
|
||||
},
|
||||
createdAt: {
|
||||
toCompare: false,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
updatedAt: {
|
||||
toCompare: false,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
},
|
||||
rowLevelPermissionPredicate: {
|
||||
fieldMetadataId: {
|
||||
toCompare: true,
|
||||
|
||||
+17
@@ -163,6 +163,23 @@ export const ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY = {
|
||||
workspace: null,
|
||||
application: null,
|
||||
},
|
||||
permissionFlag: {
|
||||
workspace: null,
|
||||
application: null,
|
||||
role: {
|
||||
foreignKey: 'roleId',
|
||||
},
|
||||
},
|
||||
objectPermission: {
|
||||
workspace: null,
|
||||
application: null,
|
||||
role: {
|
||||
foreignKey: 'roleId',
|
||||
},
|
||||
objectMetadata: {
|
||||
foreignKey: 'objectMetadataId',
|
||||
},
|
||||
},
|
||||
pageLayout: {
|
||||
workspace: null,
|
||||
objectMetadata: {
|
||||
|
||||
+29
@@ -280,6 +280,35 @@ export const ALL_MANY_TO_ONE_METADATA_RELATIONS = {
|
||||
workspace: null,
|
||||
application: null,
|
||||
},
|
||||
permissionFlag: {
|
||||
workspace: null,
|
||||
application: null,
|
||||
role: {
|
||||
metadataName: 'role',
|
||||
foreignKey: 'roleId',
|
||||
inverseOneToManyProperty: 'permissionFlags',
|
||||
isNullable: false,
|
||||
universalForeignKey: 'roleUniversalIdentifier',
|
||||
},
|
||||
},
|
||||
objectPermission: {
|
||||
workspace: null,
|
||||
application: null,
|
||||
role: {
|
||||
metadataName: 'role',
|
||||
foreignKey: 'roleId',
|
||||
inverseOneToManyProperty: 'objectPermissions',
|
||||
isNullable: false,
|
||||
universalForeignKey: 'roleUniversalIdentifier',
|
||||
},
|
||||
objectMetadata: {
|
||||
metadataName: 'objectMetadata',
|
||||
foreignKey: 'objectMetadataId',
|
||||
inverseOneToManyProperty: 'objectPermissions',
|
||||
isNullable: false,
|
||||
universalForeignKey: 'objectMetadataUniversalIdentifier',
|
||||
},
|
||||
},
|
||||
pageLayout: {
|
||||
workspace: null,
|
||||
objectMetadata: {
|
||||
|
||||
+4
@@ -8,10 +8,12 @@ import { FrontComponentEntity } from 'src/engine/metadata-modules/front-componen
|
||||
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import { WebhookEntity } from 'src/engine/metadata-modules/webhook/entities/webhook.entity';
|
||||
import { NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation-menu-item/entities/navigation-menu-item.entity';
|
||||
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
|
||||
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
@@ -45,10 +47,12 @@ export const ALL_METADATA_ENTITY_BY_METADATA_NAME = {
|
||||
skill: SkillEntity,
|
||||
logicFunction: LogicFunctionEntity,
|
||||
objectMetadata: ObjectMetadataEntity,
|
||||
objectPermission: ObjectPermissionEntity,
|
||||
role: RoleEntity,
|
||||
agent: AgentEntity,
|
||||
commandMenuItem: CommandMenuItemEntity,
|
||||
navigationMenuItem: NavigationMenuItemEntity,
|
||||
permissionFlag: PermissionFlagEntity,
|
||||
webhook: WebhookEntity,
|
||||
viewSort: ViewSortEntity,
|
||||
} as const satisfies Record<AllMetadataName, EntityTarget<ObjectLiteral>>;
|
||||
|
||||
+7
@@ -74,6 +74,13 @@ export const ALL_METADATA_REQUIRED_METADATA_FOR_VALIDATION = {
|
||||
objectMetadata: true,
|
||||
view: true,
|
||||
},
|
||||
objectPermission: {
|
||||
role: true,
|
||||
objectMetadata: true,
|
||||
},
|
||||
permissionFlag: {
|
||||
role: true,
|
||||
},
|
||||
pageLayout: {
|
||||
objectMetadata: true,
|
||||
pageLayoutTab: true,
|
||||
|
||||
+2
@@ -33,6 +33,8 @@ export const ALL_METADATA_SERIALIZED_RELATION = {
|
||||
logicFunction: {},
|
||||
role: {},
|
||||
roleTarget: {},
|
||||
objectPermission: {},
|
||||
permissionFlag: {},
|
||||
pageLayout: {},
|
||||
pageLayoutTab: {},
|
||||
pageLayoutWidget: {
|
||||
|
||||
+20
-3
@@ -85,7 +85,12 @@ export const ALL_ONE_TO_MANY_METADATA_RELATIONS = {
|
||||
universalFlatEntityForeignKeyAggregator:
|
||||
'indexMetadataUniversalIdentifiers',
|
||||
},
|
||||
objectPermissions: null,
|
||||
objectPermissions: {
|
||||
metadataName: 'objectPermission',
|
||||
flatEntityForeignKeyAggregator: 'objectPermissionIds',
|
||||
universalFlatEntityForeignKeyAggregator:
|
||||
'objectPermissionUniversalIdentifiers',
|
||||
},
|
||||
fieldPermissions: null,
|
||||
views: {
|
||||
metadataName: 'view',
|
||||
@@ -144,8 +149,18 @@ export const ALL_ONE_TO_MANY_METADATA_RELATIONS = {
|
||||
flatEntityForeignKeyAggregator: 'roleTargetIds',
|
||||
universalFlatEntityForeignKeyAggregator: 'roleTargetUniversalIdentifiers',
|
||||
},
|
||||
objectPermissions: null,
|
||||
permissionFlags: null,
|
||||
objectPermissions: {
|
||||
metadataName: 'objectPermission',
|
||||
flatEntityForeignKeyAggregator: 'objectPermissionIds',
|
||||
universalFlatEntityForeignKeyAggregator:
|
||||
'objectPermissionUniversalIdentifiers',
|
||||
},
|
||||
permissionFlags: {
|
||||
metadataName: 'permissionFlag',
|
||||
flatEntityForeignKeyAggregator: 'permissionFlagIds',
|
||||
universalFlatEntityForeignKeyAggregator:
|
||||
'permissionFlagUniversalIdentifiers',
|
||||
},
|
||||
fieldPermissions: null,
|
||||
rowLevelPermissionPredicates: {
|
||||
metadataName: 'rowLevelPermissionPredicate',
|
||||
@@ -161,6 +176,8 @@ export const ALL_ONE_TO_MANY_METADATA_RELATIONS = {
|
||||
},
|
||||
},
|
||||
roleTarget: {},
|
||||
objectPermission: {},
|
||||
permissionFlag: {},
|
||||
pageLayout: {
|
||||
tabs: {
|
||||
metadataName: 'pageLayoutTab',
|
||||
|
||||
+5
@@ -25,6 +25,7 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
|
||||
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity';
|
||||
import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity';
|
||||
@@ -36,6 +37,7 @@ import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
|
||||
import { WorkspaceFlatPermissionFlagMapCacheService } from 'src/engine/metadata-modules/flat-permission-flag/services/workspace-flat-permission-flag-map-cache.service';
|
||||
import { WorkspaceFlatViewSortMapCacheService } from 'src/engine/metadata-modules/flat-view-sort/services/workspace-flat-view-sort-map-cache.service';
|
||||
|
||||
@Module({
|
||||
@@ -56,6 +58,7 @@ import { WorkspaceFlatViewSortMapCacheService } from 'src/engine/metadata-module
|
||||
PageLayoutEntity,
|
||||
PageLayoutTabEntity,
|
||||
PageLayoutWidgetEntity,
|
||||
PermissionFlagEntity,
|
||||
RowLevelPermissionPredicateEntity,
|
||||
RowLevelPermissionPredicateGroupEntity,
|
||||
ApplicationEntity,
|
||||
@@ -74,6 +77,7 @@ import { WorkspaceFlatViewSortMapCacheService } from 'src/engine/metadata-module
|
||||
WorkspaceFlatIndexMapCacheService,
|
||||
WorkspaceFlatFieldMetadataMapCacheService,
|
||||
WorkspaceFlatViewGroupMapCacheService,
|
||||
WorkspaceFlatPermissionFlagMapCacheService,
|
||||
WorkspaceFlatViewSortMapCacheService,
|
||||
WorkspaceFlatPageLayoutMapCacheService,
|
||||
WorkspaceFlatPageLayoutTabMapCacheService,
|
||||
@@ -92,6 +96,7 @@ import { WorkspaceFlatViewSortMapCacheService } from 'src/engine/metadata-module
|
||||
WorkspaceFlatIndexMapCacheService,
|
||||
WorkspaceFlatFieldMetadataMapCacheService,
|
||||
WorkspaceFlatViewGroupMapCacheService,
|
||||
WorkspaceFlatPermissionFlagMapCacheService,
|
||||
WorkspaceFlatViewSortMapCacheService,
|
||||
WorkspaceFlatPageLayoutMapCacheService,
|
||||
WorkspaceFlatPageLayoutTabMapCacheService,
|
||||
|
||||
+75
-21
@@ -12,12 +12,16 @@ import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-m
|
||||
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { type FlatObjectPermissionMaps } from 'src/engine/metadata-modules/flat-object-permission/types/flat-object-permission-maps.type';
|
||||
import { type FlatObjectPermission } from 'src/engine/metadata-modules/flat-object-permission/types/flat-object-permission.type';
|
||||
import { type FlatPageLayoutTabMaps } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab-maps.type';
|
||||
import { type FlatPageLayoutTab } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type';
|
||||
import { type FlatPageLayoutWidgetMaps } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-maps.type';
|
||||
import { type FlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type';
|
||||
import { type FlatPageLayoutMaps } from 'src/engine/metadata-modules/flat-page-layout/types/flat-page-layout-maps.type';
|
||||
import { type FlatPageLayout } from 'src/engine/metadata-modules/flat-page-layout/types/flat-page-layout.type';
|
||||
import { type FlatPermissionFlagMaps } from 'src/engine/metadata-modules/flat-permission-flag/types/flat-permission-flag-maps.type';
|
||||
import { type FlatPermissionFlag } from 'src/engine/metadata-modules/flat-permission-flag/types/flat-permission-flag.type';
|
||||
import { type FlatRoleTargetMaps } from 'src/engine/metadata-modules/flat-role-target/types/flat-role-target-maps.type';
|
||||
import { type FlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/types/flat-role-target.type';
|
||||
import { type FlatRole } from 'src/engine/metadata-modules/flat-role/types/flat-role.type';
|
||||
@@ -53,21 +57,23 @@ import { type UniversalFlatIndexMetadata } from 'src/engine/workspace-manager/wo
|
||||
import { type UniversalFlatLogicFunction } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-logic-function.type';
|
||||
import { type UniversalFlatNavigationMenuItem } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-navigation-menu-item.type';
|
||||
import { type UniversalFlatObjectMetadata } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-metadata.type';
|
||||
import { type UniversalFlatPageLayout } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-page-layout.type';
|
||||
import { type UniversalFlatObjectPermission } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-permission.type';
|
||||
import { type UniversalFlatPageLayoutTab } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-page-layout-tab.type';
|
||||
import { type UniversalFlatPageLayoutWidget } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-page-layout-widget.type';
|
||||
import { type UniversalFlatRole } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-role.type';
|
||||
import { type UniversalFlatPageLayout } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-page-layout.type';
|
||||
import { type UniversalFlatPermissionFlag } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-permission-flag.type';
|
||||
import { type UniversalFlatRoleTarget } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-role-target.type';
|
||||
import { type UniversalFlatRowLevelPermissionPredicate } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-row-level-permission-predicate.type';
|
||||
import { type UniversalFlatRole } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-role.type';
|
||||
import { type UniversalFlatRowLevelPermissionPredicateGroup } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-row-level-permission-predicate-group.type';
|
||||
import { type UniversalFlatRowLevelPermissionPredicate } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-row-level-permission-predicate.type';
|
||||
import { type UniversalFlatSkill } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-skill.type';
|
||||
import { type UniversalFlatViewFieldGroup } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-field-group.type';
|
||||
import { type UniversalFlatViewField } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-field.type';
|
||||
import { type UniversalFlatViewFilterGroup } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-filter-group.type';
|
||||
import { type UniversalFlatViewFilter } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-filter.type';
|
||||
import { type UniversalFlatViewGroup } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-group.type';
|
||||
import { type UniversalFlatView } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view.type';
|
||||
import { type UniversalFlatViewSort } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-sort.type';
|
||||
import { type UniversalFlatView } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view.type';
|
||||
import { type UniversalFlatWebhook } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-webhook.type';
|
||||
import {
|
||||
type FlatCreateAgentAction,
|
||||
@@ -102,10 +108,10 @@ import {
|
||||
type UniversalUpdateFrontComponentAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/types/workspace-migration-front-component-action.type';
|
||||
import {
|
||||
type UniversalCreateIndexAction,
|
||||
type FlatCreateIndexAction,
|
||||
type FlatDeleteIndexAction,
|
||||
type FlatUpdateIndexAction,
|
||||
type UniversalCreateIndexAction,
|
||||
type UniversalDeleteIndexAction,
|
||||
type UniversalUpdateIndexAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/index/types/workspace-migration-index-action';
|
||||
@@ -125,6 +131,14 @@ import {
|
||||
type UniversalDeleteNavigationMenuItemAction,
|
||||
type UniversalUpdateNavigationMenuItemAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/navigation-menu-item/types/workspace-migration-navigation-menu-item-action.type';
|
||||
import {
|
||||
type FlatCreateObjectPermissionAction,
|
||||
type FlatDeleteObjectPermissionAction,
|
||||
type FlatUpdateObjectPermissionAction,
|
||||
type UniversalCreateObjectPermissionAction,
|
||||
type UniversalDeleteObjectPermissionAction,
|
||||
type UniversalUpdateObjectPermissionAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object-permission/types/workspace-migration-object-permission-action.type';
|
||||
import {
|
||||
type FlatCreateObjectAction,
|
||||
type FlatDeleteObjectAction,
|
||||
@@ -157,6 +171,14 @@ import {
|
||||
type UniversalDeletePageLayoutAction,
|
||||
type UniversalUpdatePageLayoutAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/types/workspace-migration-page-layout-action.type';
|
||||
import {
|
||||
type FlatCreatePermissionFlagAction,
|
||||
type FlatDeletePermissionFlagAction,
|
||||
type FlatUpdatePermissionFlagAction,
|
||||
type UniversalCreatePermissionFlagAction,
|
||||
type UniversalDeletePermissionFlagAction,
|
||||
type UniversalUpdatePermissionFlagAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/permission-flag/types/workspace-migration-permission-flag-action.type';
|
||||
import {
|
||||
type FlatCreateRoleTargetAction,
|
||||
type FlatDeleteRoleTargetAction,
|
||||
@@ -197,14 +219,6 @@ import {
|
||||
type UniversalDeleteSkillAction,
|
||||
type UniversalUpdateSkillAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/skill/types/workspace-migration-skill-action.type';
|
||||
import {
|
||||
type FlatCreateViewFieldAction,
|
||||
type FlatDeleteViewFieldAction,
|
||||
type FlatUpdateViewFieldAction,
|
||||
type UniversalCreateViewFieldAction,
|
||||
type UniversalDeleteViewFieldAction,
|
||||
type UniversalUpdateViewFieldAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field/types/workspace-migration-view-field-action.type';
|
||||
import {
|
||||
type FlatCreateViewFieldGroupAction,
|
||||
type FlatDeleteViewFieldGroupAction,
|
||||
@@ -213,6 +227,14 @@ import {
|
||||
type UniversalDeleteViewFieldGroupAction,
|
||||
type UniversalUpdateViewFieldGroupAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field-group/types/workspace-migration-view-field-group-action.type';
|
||||
import {
|
||||
type FlatCreateViewFieldAction,
|
||||
type FlatDeleteViewFieldAction,
|
||||
type FlatUpdateViewFieldAction,
|
||||
type UniversalCreateViewFieldAction,
|
||||
type UniversalDeleteViewFieldAction,
|
||||
type UniversalUpdateViewFieldAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field/types/workspace-migration-view-field-action.type';
|
||||
import {
|
||||
type FlatCreateViewFilterGroupAction,
|
||||
type FlatDeleteViewFilterGroupAction,
|
||||
@@ -237,6 +259,14 @@ import {
|
||||
type UniversalDeleteViewGroupAction,
|
||||
type UniversalUpdateViewGroupAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-group/types/workspace-migration-view-group-action.type';
|
||||
import {
|
||||
type FlatCreateViewSortAction,
|
||||
type FlatDeleteViewSortAction,
|
||||
type FlatUpdateViewSortAction,
|
||||
type UniversalCreateViewSortAction,
|
||||
type UniversalDeleteViewSortAction,
|
||||
type UniversalUpdateViewSortAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-sort/types/workspace-migration-view-sort-action.type';
|
||||
import {
|
||||
type FlatCreateViewAction,
|
||||
type FlatDeleteViewAction,
|
||||
@@ -253,14 +283,6 @@ import {
|
||||
type UniversalDeleteWebhookAction,
|
||||
type UniversalUpdateWebhookAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/webhook/types/workspace-migration-webhook-action.type';
|
||||
import {
|
||||
type FlatCreateViewSortAction,
|
||||
type FlatDeleteViewSortAction,
|
||||
type FlatUpdateViewSortAction,
|
||||
type UniversalCreateViewSortAction,
|
||||
type UniversalDeleteViewSortAction,
|
||||
type UniversalUpdateViewSortAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-sort/types/workspace-migration-view-sort-action.type';
|
||||
|
||||
export type AllFlatEntityTypesByMetadataName = {
|
||||
fieldMetadata: {
|
||||
@@ -298,6 +320,22 @@ export type AllFlatEntityTypesByMetadataName = {
|
||||
universalFlatEntity: UniversalFlatObjectMetadata;
|
||||
entity: MetadataEntity<'objectMetadata'>;
|
||||
};
|
||||
objectPermission: {
|
||||
flatEntityMaps: FlatObjectPermissionMaps;
|
||||
universalActions: {
|
||||
create: UniversalCreateObjectPermissionAction;
|
||||
update: UniversalUpdateObjectPermissionAction;
|
||||
delete: UniversalDeleteObjectPermissionAction;
|
||||
};
|
||||
flatActions: {
|
||||
create: FlatCreateObjectPermissionAction;
|
||||
update: FlatUpdateObjectPermissionAction;
|
||||
delete: FlatDeleteObjectPermissionAction;
|
||||
};
|
||||
flatEntity: FlatObjectPermission;
|
||||
universalFlatEntity: UniversalFlatObjectPermission;
|
||||
entity: MetadataEntity<'objectPermission'>;
|
||||
};
|
||||
view: {
|
||||
flatEntityMaps: FlatViewMaps;
|
||||
universalActions: {
|
||||
@@ -570,6 +608,22 @@ export type AllFlatEntityTypesByMetadataName = {
|
||||
universalFlatEntity: UniversalFlatNavigationMenuItem;
|
||||
entity: NavigationMenuItemEntity;
|
||||
};
|
||||
permissionFlag: {
|
||||
flatEntityMaps: FlatPermissionFlagMaps;
|
||||
universalActions: {
|
||||
create: UniversalCreatePermissionFlagAction;
|
||||
update: UniversalUpdatePermissionFlagAction;
|
||||
delete: UniversalDeletePermissionFlagAction;
|
||||
};
|
||||
flatActions: {
|
||||
create: FlatCreatePermissionFlagAction;
|
||||
update: FlatUpdatePermissionFlagAction;
|
||||
delete: FlatDeletePermissionFlagAction;
|
||||
};
|
||||
flatEntity: FlatPermissionFlag;
|
||||
universalFlatEntity: UniversalFlatPermissionFlag;
|
||||
entity: MetadataEntity<'permissionFlag'>;
|
||||
};
|
||||
pageLayout: {
|
||||
flatEntityMaps: FlatPageLayoutMaps;
|
||||
universalActions: {
|
||||
|
||||
+7
@@ -67,9 +67,16 @@ exports[`getMetadataRelatedMetadataNames should return related metadata names fo
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`getMetadataRelatedMetadataNames should return related metadata names for permissionFlag 1`] = `
|
||||
[
|
||||
"role",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`getMetadataRelatedMetadataNames should return related metadata names for role 1`] = `
|
||||
[
|
||||
"roleTarget",
|
||||
"permissionFlag",
|
||||
"rowLevelPermissionPredicate",
|
||||
"rowLevelPermissionPredicateGroup",
|
||||
]
|
||||
|
||||
+1
@@ -11,6 +11,7 @@ exports[`sortMetadataNamesChildrenFirst should return metadata names sorted with
|
||||
"viewSort",
|
||||
"index",
|
||||
"pageLayout",
|
||||
"permissionFlag",
|
||||
"roleTarget",
|
||||
"rowLevelPermissionPredicateGroup",
|
||||
"viewGroup",
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
|
||||
export const FLAT_OBJECT_PERMISSION_EDITABLE_PROPERTIES = [
|
||||
'roleId',
|
||||
'objectMetadataId',
|
||||
'canReadObjectRecords',
|
||||
'canUpdateObjectRecords',
|
||||
'canSoftDeleteObjectRecords',
|
||||
'canDestroyObjectRecords',
|
||||
] as const satisfies MetadataEntityPropertyName<'objectPermission'>[];
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { type FlatObjectPermission } from 'src/engine/metadata-modules/flat-object-permission/types/flat-object-permission.type';
|
||||
|
||||
export type FlatObjectPermissionMaps = FlatEntityMaps<FlatObjectPermission>;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';
|
||||
import { type ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
|
||||
|
||||
export type FlatObjectPermission = FlatEntityFrom<ObjectPermissionEntity>;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
|
||||
export const FLAT_PERMISSION_FLAG_EDITABLE_PROPERTIES = [
|
||||
'flag',
|
||||
'roleId',
|
||||
] as const satisfies MetadataEntityPropertyName<'permissionFlag'>[];
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
|
||||
import { type FlatPermissionFlagMaps } from 'src/engine/metadata-modules/flat-permission-flag/types/flat-permission-flag-maps.type';
|
||||
import { fromPermissionFlagEntityToFlatPermissionFlag } from 'src/engine/metadata-modules/flat-permission-flag/utils/from-permission-flag-entity-to-flat-permission-flag.util';
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
|
||||
@Injectable()
|
||||
@WorkspaceCache('flatPermissionFlagMaps')
|
||||
export class WorkspaceFlatPermissionFlagMapCacheService extends WorkspaceCacheProvider<FlatPermissionFlagMaps> {
|
||||
constructor(
|
||||
@InjectRepository(PermissionFlagEntity)
|
||||
private readonly permissionFlagRepository: Repository<PermissionFlagEntity>,
|
||||
@InjectRepository(ApplicationEntity)
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async computeForCache(workspaceId: string): Promise<FlatPermissionFlagMaps> {
|
||||
const [permissionFlags, applications, roles] = await Promise.all([
|
||||
this.permissionFlagRepository.find({
|
||||
where: { workspaceId },
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.applicationRepository.find({
|
||||
where: { workspaceId },
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
this.roleRepository.find({
|
||||
where: { workspaceId },
|
||||
select: ['id', 'universalIdentifier'],
|
||||
withDeleted: true,
|
||||
}),
|
||||
]);
|
||||
|
||||
const applicationIdToUniversalIdentifierMap =
|
||||
createIdToUniversalIdentifierMap(applications);
|
||||
const roleIdToUniversalIdentifierMap =
|
||||
createIdToUniversalIdentifierMap(roles);
|
||||
|
||||
const flatPermissionFlagMaps = createEmptyFlatEntityMaps();
|
||||
|
||||
for (const permissionFlagEntity of permissionFlags) {
|
||||
const flatPermissionFlag = fromPermissionFlagEntityToFlatPermissionFlag({
|
||||
entity: permissionFlagEntity,
|
||||
applicationIdToUniversalIdentifierMap,
|
||||
roleIdToUniversalIdentifierMap,
|
||||
});
|
||||
|
||||
addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
|
||||
flatEntity: flatPermissionFlag,
|
||||
flatEntityMapsToMutate: flatPermissionFlagMaps,
|
||||
});
|
||||
}
|
||||
|
||||
return flatPermissionFlagMaps;
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { type FlatPermissionFlag } from 'src/engine/metadata-modules/flat-permission-flag/types/flat-permission-flag.type';
|
||||
|
||||
export type FlatPermissionFlagMaps = FlatEntityMaps<FlatPermissionFlag>;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';
|
||||
import { type PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
|
||||
export type FlatPermissionFlag = FlatEntityFrom<PermissionFlagEntity>;
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
|
||||
import { resolveEntityRelationUniversalIdentifiers } from 'src/engine/metadata-modules/flat-entity/utils/resolve-entity-relation-universal-identifiers.util';
|
||||
import { type CreatePermissionFlagInput } from 'src/engine/metadata-modules/permission-flag/dtos/create-permission-flag.input';
|
||||
import { type UniversalFlatPermissionFlag } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-permission-flag.type';
|
||||
|
||||
export const fromCreatePermissionFlagInputToFlatPermissionFlagToCreate = ({
|
||||
createPermissionFlagInput,
|
||||
flatApplication,
|
||||
flatRoleMaps,
|
||||
}: {
|
||||
createPermissionFlagInput: CreatePermissionFlagInput;
|
||||
flatApplication: FlatApplication;
|
||||
} & Pick<AllFlatEntityMaps, 'flatRoleMaps'>): UniversalFlatPermissionFlag & {
|
||||
id: string;
|
||||
} => {
|
||||
const { roleId, flag, universalIdentifier } = createPermissionFlagInput;
|
||||
const now = new Date().toISOString();
|
||||
|
||||
const { roleUniversalIdentifier } = resolveEntityRelationUniversalIdentifiers(
|
||||
{
|
||||
metadataName: 'permissionFlag',
|
||||
foreignKeyValues: { roleId },
|
||||
flatEntityMaps: { flatRoleMaps },
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
flag,
|
||||
universalIdentifier: universalIdentifier ?? v4(),
|
||||
applicationUniversalIdentifier: flatApplication.universalIdentifier,
|
||||
roleUniversalIdentifier,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
};
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
import { isDefined, removePropertiesFromRecord } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
FlatEntityMapsException,
|
||||
FlatEntityMapsExceptionCode,
|
||||
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
|
||||
import { getMetadataEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-entity-relation-properties.util';
|
||||
import { type FlatPermissionFlag } from 'src/engine/metadata-modules/flat-permission-flag/types/flat-permission-flag.type';
|
||||
import { type FromEntityToFlatEntityArgs } from 'src/engine/workspace-cache/types/from-entity-to-flat-entity-args.type';
|
||||
|
||||
export const fromPermissionFlagEntityToFlatPermissionFlag = ({
|
||||
entity: permissionFlagEntity,
|
||||
applicationIdToUniversalIdentifierMap,
|
||||
roleIdToUniversalIdentifierMap,
|
||||
}: FromEntityToFlatEntityArgs<'permissionFlag'>): FlatPermissionFlag => {
|
||||
const permissionFlagEntityWithoutRelations = removePropertiesFromRecord(
|
||||
permissionFlagEntity,
|
||||
getMetadataEntityRelationProperties('permissionFlag'),
|
||||
);
|
||||
|
||||
const applicationUniversalIdentifier =
|
||||
applicationIdToUniversalIdentifierMap.get(
|
||||
permissionFlagEntity.applicationId,
|
||||
);
|
||||
|
||||
if (!isDefined(applicationUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`Application with id ${permissionFlagEntity.applicationId} not found for permissionFlag ${permissionFlagEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const roleUniversalIdentifier = roleIdToUniversalIdentifierMap.get(
|
||||
permissionFlagEntity.roleId,
|
||||
);
|
||||
|
||||
if (!isDefined(roleUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`Role with id ${permissionFlagEntity.roleId} not found for permissionFlag ${permissionFlagEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...permissionFlagEntityWithoutRelations,
|
||||
createdAt: permissionFlagEntity.createdAt.toISOString(),
|
||||
updatedAt: permissionFlagEntity.updatedAt.toISOString(),
|
||||
universalIdentifier:
|
||||
permissionFlagEntityWithoutRelations.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
roleUniversalIdentifier,
|
||||
};
|
||||
};
|
||||
+2
@@ -54,7 +54,9 @@ export const fromCreateRoleInputToFlatRoleToCreate = ({
|
||||
roleTargetIds: [],
|
||||
roleTargetUniversalIdentifiers: [],
|
||||
objectPermissionIds: [],
|
||||
objectPermissionUniversalIdentifiers: [],
|
||||
permissionFlagIds: [],
|
||||
permissionFlagUniversalIdentifiers: [],
|
||||
fieldPermissionIds: [],
|
||||
rowLevelPermissionPredicateIds: [],
|
||||
rowLevelPermissionPredicateUniversalIdentifiers: [],
|
||||
|
||||
+6
@@ -68,6 +68,12 @@ export const fromRoleEntityToFlatRole = ({
|
||||
roleTargetUniversalIdentifiers: roleEntity.roleTargets.map(
|
||||
({ universalIdentifier }) => universalIdentifier,
|
||||
),
|
||||
objectPermissionUniversalIdentifiers: roleEntity.objectPermissions.map(
|
||||
({ universalIdentifier }) => universalIdentifier,
|
||||
),
|
||||
permissionFlagUniversalIdentifiers: roleEntity.permissionFlags.map(
|
||||
({ universalIdentifier }) => universalIdentifier,
|
||||
),
|
||||
rowLevelPermissionPredicateUniversalIdentifiers:
|
||||
roleEntity.rowLevelPermissionPredicates.map(
|
||||
({ universalIdentifier }) => universalIdentifier,
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ import {
|
||||
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity('objectPermission')
|
||||
@Unique('IDX_OBJECT_PERMISSION_OBJECT_METADATA_ID_ROLE_ID_UNIQUE', [
|
||||
@@ -21,7 +21,7 @@ import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/works
|
||||
'roleId',
|
||||
])
|
||||
@Index('IDX_OBJECT_PERMISSION_WORKSPACE_ID_ROLE_ID', ['workspaceId', 'roleId'])
|
||||
export class ObjectPermissionEntity extends WorkspaceRelatedEntity {
|
||||
export class ObjectPermissionEntity extends SyncableEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
|
||||
export type CreatePermissionFlagInput = {
|
||||
roleId: string;
|
||||
flag: PermissionFlagType;
|
||||
universalIdentifier?: string;
|
||||
};
|
||||
+2
-2
@@ -12,11 +12,11 @@ import {
|
||||
} from 'typeorm';
|
||||
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity('permissionFlag')
|
||||
@Unique('IDX_PERMISSION_FLAG_FLAG_ROLE_ID_UNIQUE', ['flag', 'roleId'])
|
||||
export class PermissionFlagEntity extends WorkspaceRelatedEntity {
|
||||
export class PermissionFlagEntity extends SyncableEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
|
||||
+6
-5
@@ -1,17 +1,18 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { PermissionFlagService } from 'src/engine/metadata-modules/permission-flag/permission-flag.service';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([PermissionFlagEntity, RoleEntity]),
|
||||
WorkspaceCacheModule,
|
||||
ApplicationModule,
|
||||
WorkspaceMigrationModule,
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
],
|
||||
|
||||
providers: [PermissionFlagService],
|
||||
exports: [PermissionFlagService],
|
||||
})
|
||||
|
||||
+124
-109
@@ -1,26 +1,31 @@
|
||||
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { DataSource, In, Repository } from 'typeorm';
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { type FlatPermissionFlag } from 'src/engine/metadata-modules/flat-permission-flag/types/flat-permission-flag.type';
|
||||
import { fromCreatePermissionFlagInputToFlatPermissionFlagToCreate } from 'src/engine/metadata-modules/flat-permission-flag/utils/from-create-permission-flag-input-to-flat-permission-flag-to-create.util';
|
||||
import { type PermissionFlagDTO } from 'src/engine/metadata-modules/permission-flag/dtos/permission-flag.dto';
|
||||
import { type UpsertPermissionFlagsInput } from 'src/engine/metadata-modules/permission-flag/dtos/upsert-permission-flag-input';
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { fromFlatPermissionFlagToPermissionFlagDto } from 'src/engine/metadata-modules/permission-flag/utils/from-flat-permission-flag-to-permission-flag-dto.util';
|
||||
import {
|
||||
PermissionsException,
|
||||
PermissionsExceptionCode,
|
||||
PermissionsExceptionMessage,
|
||||
} from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class PermissionFlagService {
|
||||
constructor(
|
||||
@InjectRepository(RoleEntity)
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectDataSource()
|
||||
private readonly coreDataSource: DataSource,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly workspaceManyOrAllFlatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly workspaceCacheService: WorkspaceCacheService,
|
||||
) {}
|
||||
|
||||
@@ -30,11 +35,39 @@ export class PermissionFlagService {
|
||||
}: {
|
||||
workspaceId: string;
|
||||
input: UpsertPermissionFlagsInput;
|
||||
}): Promise<PermissionFlagEntity[]> {
|
||||
await this.validateRoleIsEditableOrThrow({
|
||||
roleId: input.roleId,
|
||||
workspaceId,
|
||||
});
|
||||
}): Promise<PermissionFlagDTO[]> {
|
||||
const { flatPermissionFlagMaps, flatRoleMaps } =
|
||||
await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatPermissionFlagMaps', 'flatRoleMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const roleUniversalId = flatRoleMaps.universalIdentifierById[input.roleId];
|
||||
const roleById = isDefined(roleUniversalId)
|
||||
? flatRoleMaps.byUniversalIdentifier[roleUniversalId]
|
||||
: undefined;
|
||||
|
||||
if (!isDefined(roleById)) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.ROLE_NOT_FOUND,
|
||||
PermissionsExceptionCode.ROLE_NOT_FOUND,
|
||||
{
|
||||
userFriendlyMessage: msg`The role you are trying to modify could not be found.`,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (!roleById.isEditable) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.ROLE_NOT_EDITABLE,
|
||||
PermissionsExceptionCode.ROLE_NOT_EDITABLE,
|
||||
{
|
||||
userFriendlyMessage: msg`This role cannot be modified because it is a system role. Only custom roles can be edited.`,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const invalidFlags = input.permissionFlagKeys.filter(
|
||||
(flag) => !Object.values(PermissionFlagType).includes(flag),
|
||||
@@ -50,112 +83,94 @@ export class PermissionFlagService {
|
||||
);
|
||||
}
|
||||
|
||||
const queryRunner = this.coreDataSource.createQueryRunner();
|
||||
const roleUniversalIdentifier = roleById.universalIdentifier;
|
||||
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
const currentPermissionFlagsForRole = Object.values(
|
||||
flatPermissionFlagMaps.byUniversalIdentifier,
|
||||
).filter(
|
||||
(pf): pf is FlatPermissionFlag =>
|
||||
isDefined(pf) && pf.roleUniversalIdentifier === roleUniversalIdentifier,
|
||||
);
|
||||
|
||||
try {
|
||||
const existingPermissions = await queryRunner.manager.find(
|
||||
PermissionFlagEntity,
|
||||
const inputSet = new Set(input.permissionFlagKeys);
|
||||
const existingSet = new Set(
|
||||
currentPermissionFlagsForRole.map((pf) => pf.flag),
|
||||
);
|
||||
|
||||
const flatApplication =
|
||||
await this.getFlatApplicationForWorkspace(workspaceId);
|
||||
|
||||
const flatEntityToCreate = input.permissionFlagKeys
|
||||
.filter((flag) => !existingSet.has(flag))
|
||||
.map((flag) =>
|
||||
fromCreatePermissionFlagInputToFlatPermissionFlagToCreate({
|
||||
createPermissionFlagInput: { roleId: input.roleId, flag },
|
||||
flatApplication,
|
||||
flatRoleMaps,
|
||||
}),
|
||||
);
|
||||
|
||||
const flatEntityToDelete = currentPermissionFlagsForRole.filter(
|
||||
(pf) => !inputSet.has(pf.flag),
|
||||
);
|
||||
|
||||
if (flatEntityToCreate.length === 0 && flatEntityToDelete.length === 0) {
|
||||
const unchanged = currentPermissionFlagsForRole.filter((pf) =>
|
||||
inputSet.has(pf.flag),
|
||||
);
|
||||
return unchanged.map(fromFlatPermissionFlagToPermissionFlagDto);
|
||||
}
|
||||
|
||||
const buildAndRunResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
where: {
|
||||
roleId: input.roleId,
|
||||
workspaceId,
|
||||
allFlatEntityOperationByMetadataName: {
|
||||
permissionFlag: {
|
||||
flatEntityToCreate,
|
||||
flatEntityToDelete,
|
||||
flatEntityToUpdate: [],
|
||||
},
|
||||
},
|
||||
workspaceId,
|
||||
isSystemBuild: false,
|
||||
applicationUniversalIdentifier: flatApplication.universalIdentifier,
|
||||
},
|
||||
);
|
||||
const existingSettings = new Set(existingPermissions.map((p) => p.flag));
|
||||
const inputSettings = new Set(input.permissionFlagKeys);
|
||||
|
||||
const flagsToAdd = input.permissionFlagKeys.filter(
|
||||
(setting) => !existingSettings.has(setting),
|
||||
if (buildAndRunResult.status === 'fail') {
|
||||
throw new WorkspaceMigrationBuilderException(
|
||||
buildAndRunResult,
|
||||
'Validation errors occurred while upserting permission flags',
|
||||
);
|
||||
const permissionsToRemove = existingPermissions.filter(
|
||||
(permission) => !inputSettings.has(permission.flag),
|
||||
);
|
||||
|
||||
if (permissionsToRemove.length > 0) {
|
||||
await queryRunner.manager.delete(PermissionFlagEntity, {
|
||||
id: In(permissionsToRemove.map((p) => p.id)),
|
||||
});
|
||||
}
|
||||
|
||||
if (flagsToAdd.length > 0) {
|
||||
const newPermissions = flagsToAdd.map((flag) =>
|
||||
queryRunner.manager.create(PermissionFlagEntity, {
|
||||
workspaceId,
|
||||
roleId: input.roleId,
|
||||
flag,
|
||||
}),
|
||||
);
|
||||
|
||||
await queryRunner.manager.save(PermissionFlagEntity, newPermissions);
|
||||
}
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
|
||||
return queryRunner.manager.find(PermissionFlagEntity, {
|
||||
where: { roleId: input.roleId, workspaceId },
|
||||
order: { flag: 'ASC' },
|
||||
});
|
||||
} catch (error) {
|
||||
if (queryRunner.isTransactionActive) {
|
||||
try {
|
||||
await queryRunner.rollbackTransaction();
|
||||
} catch (error) {
|
||||
// oxlint-disable-next-line no-console
|
||||
console.trace(`Failed to rollback transaction: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (error.message.includes('violates foreign key constraint')) {
|
||||
const role = await this.roleRepository.findOne({
|
||||
where: { id: input.roleId },
|
||||
});
|
||||
|
||||
if (!isDefined(role)) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.ROLE_NOT_FOUND,
|
||||
PermissionsExceptionCode.ROLE_NOT_FOUND,
|
||||
{
|
||||
userFriendlyMessage: msg`The role you are trying to modify could not be found. It may have been deleted or you may not have access to it.`,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
|
||||
await this.workspaceCacheService.invalidateAndRecompute(workspaceId, [
|
||||
'rolesPermissions',
|
||||
]);
|
||||
}
|
||||
|
||||
await this.workspaceCacheService.invalidateAndRecompute(workspaceId, [
|
||||
'rolesPermissions',
|
||||
]);
|
||||
|
||||
const { flatPermissionFlagMaps: freshFlatPermissionFlagMaps } =
|
||||
await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatPermissionFlagMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const resultFlags = Object.values(
|
||||
freshFlatPermissionFlagMaps.byUniversalIdentifier,
|
||||
).filter(
|
||||
(pf): pf is FlatPermissionFlag =>
|
||||
isDefined(pf) && pf.roleUniversalIdentifier === roleUniversalIdentifier,
|
||||
);
|
||||
|
||||
return resultFlags.map(fromFlatPermissionFlagToPermissionFlagDto);
|
||||
}
|
||||
|
||||
private async validateRoleIsEditableOrThrow({
|
||||
roleId,
|
||||
workspaceId,
|
||||
}: {
|
||||
roleId: string;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
const role = await this.roleRepository.findOne({
|
||||
where: {
|
||||
id: roleId,
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!role?.isEditable) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.ROLE_NOT_EDITABLE,
|
||||
PermissionsExceptionCode.ROLE_NOT_EDITABLE,
|
||||
{
|
||||
userFriendlyMessage: msg`This role cannot be modified because it is a system role. Only custom roles can be edited.`,
|
||||
},
|
||||
private async getFlatApplicationForWorkspace(workspaceId: string) {
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{ workspaceId },
|
||||
);
|
||||
}
|
||||
return workspaceCustomFlatApplication;
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { type FlatPermissionFlag } from 'src/engine/metadata-modules/flat-permission-flag/types/flat-permission-flag.type';
|
||||
import { type PermissionFlagDTO } from 'src/engine/metadata-modules/permission-flag/dtos/permission-flag.dto';
|
||||
|
||||
export const fromFlatPermissionFlagToPermissionFlagDto = (
|
||||
flatPermissionFlag: FlatPermissionFlag,
|
||||
): PermissionFlagDTO => ({
|
||||
id: flatPermissionFlag.id,
|
||||
roleId: flatPermissionFlag.roleId,
|
||||
flag: flatPermissionFlag.flag,
|
||||
});
|
||||
@@ -32,6 +32,7 @@ export const WORKSPACE_CACHE_KEYS_V2 = {
|
||||
flatApplicationMaps: 'flat-maps:flatApplicationMaps',
|
||||
flatRoleMaps: 'flat-maps:role',
|
||||
flatRoleTargetMaps: 'flat-maps:role-target',
|
||||
flatPermissionFlagMaps: 'flat-maps:permission-flag',
|
||||
ORMEntityMetadatas: 'orm:entity-metadatas',
|
||||
flatAgentMaps: 'flat-maps:agent',
|
||||
flatSkillMaps: 'flat-maps:skill',
|
||||
|
||||
+2
@@ -73,8 +73,10 @@ export const createStandardRoleFlatMetadata = ({
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
permissionFlagIds: [],
|
||||
permissionFlagUniversalIdentifiers: [],
|
||||
fieldPermissionIds: [],
|
||||
objectPermissionIds: [],
|
||||
objectPermissionUniversalIdentifiers: [],
|
||||
roleTargetIds: [],
|
||||
roleTargetUniversalIdentifiers: [],
|
||||
rowLevelPermissionPredicateIds: [],
|
||||
|
||||
+1
@@ -167,6 +167,7 @@ export const enrichCreateWorkspaceMigrationActionsWithIds = ({
|
||||
case 'navigationMenuItem':
|
||||
case 'frontComponent':
|
||||
case 'viewSort':
|
||||
case 'permissionFlag':
|
||||
case 'webhook': {
|
||||
if (!isDefined(idByUniversalIdentifier)) {
|
||||
return action;
|
||||
|
||||
+35
-1
@@ -24,6 +24,7 @@ import { WorkspaceMigrationObjectActionsBuilderService } from 'src/engine/worksp
|
||||
import { WorkspaceMigrationPageLayoutTabActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-tab/workspace-migration-page-layout-tab-actions-builder.service';
|
||||
import { WorkspaceMigrationPageLayoutWidgetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-widget/workspace-migration-page-layout-widget-actions-builder.service';
|
||||
import { WorkspaceMigrationPageLayoutActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/workspace-migration-page-layout-actions-builder.service';
|
||||
import { WorkspaceMigrationPermissionFlagActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/permission-flag/workspace-migration-permission-flag-actions-builder.service';
|
||||
import { WorkspaceMigrationRoleTargetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role-target/workspace-migration-role-target-actions-builder.service';
|
||||
import { WorkspaceMigrationRoleActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/workspace-migration-role-actions-builder.service';
|
||||
import { WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate-group/workspace-migration-row-level-permission-predicate-group-actions-builder.service';
|
||||
@@ -34,9 +35,9 @@ import { WorkspaceMigrationViewFieldActionsBuilderService } from 'src/engine/wor
|
||||
import { WorkspaceMigrationViewFilterGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter-group/workspace-migration-view-filter-group-actions-builder.service';
|
||||
import { WorkspaceMigrationViewFilterActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter/workspace-migration-view-filter-actions-builder.service';
|
||||
import { WorkspaceMigrationViewGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-group/workspace-migration-view-group-actions-builder.service';
|
||||
import { WorkspaceMigrationViewSortActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-sort/workspace-migration-view-sort-actions.builder.service';
|
||||
import { WorkspaceMigrationViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view/workspace-migration-view-actions-builder.service';
|
||||
import { WorkspaceMigrationWebhookActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/webhook/workspace-migration-webhook-actions-builder.service';
|
||||
import { WorkspaceMigrationViewSortActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-sort/workspace-migration-view-sort-actions.builder.service';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationBuildOrchestratorService {
|
||||
@@ -50,6 +51,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
private readonly workspaceMigrationViewGroupActionsBuilderService: WorkspaceMigrationViewGroupActionsBuilderService,
|
||||
private readonly workspaceMigrationViewFieldGroupActionsBuilderService: WorkspaceMigrationViewFieldGroupActionsBuilderService,
|
||||
private readonly workspaceMigrationViewSortActionsBuilderService: WorkspaceMigrationViewSortActionsBuilderService,
|
||||
private readonly workspaceMigrationPermissionFlagActionsBuilderService: WorkspaceMigrationPermissionFlagActionsBuilderService,
|
||||
private readonly workspaceMigrationLogicFunctionActionsBuilderService: WorkspaceMigrationLogicFunctionActionsBuilderService,
|
||||
private readonly workspaceMigrationRoleTargetActionsBuilderService: WorkspaceMigrationRoleTargetActionsBuilderService,
|
||||
private readonly workspaceMigrationFieldActionsBuilderService: WorkspaceMigrationFieldActionsBuilderService,
|
||||
@@ -140,6 +142,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
flatRowLevelPermissionPredicateMaps,
|
||||
flatRowLevelPermissionPredicateGroupMaps,
|
||||
flatRoleMaps,
|
||||
flatPermissionFlagMaps,
|
||||
flatRoleTargetMaps,
|
||||
flatAgentMaps,
|
||||
flatSkillMaps,
|
||||
@@ -481,6 +484,31 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(flatPermissionFlagMaps)) {
|
||||
const { from: fromFlatPermissionFlagMaps, to: toFlatPermissionFlagMaps } =
|
||||
flatPermissionFlagMaps;
|
||||
|
||||
const permissionFlagResult =
|
||||
await this.workspaceMigrationPermissionFlagActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatPermissionFlagMaps,
|
||||
to: toFlatPermissionFlagMaps,
|
||||
buildOptions,
|
||||
dependencyOptimisticFlatEntityMaps: optimisticAllFlatEntityMaps,
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (permissionFlagResult.status === 'fail') {
|
||||
orchestratorFailureReport.permissionFlag.push(
|
||||
...permissionFlagResult.errors,
|
||||
);
|
||||
} else {
|
||||
orchestratorActionsReport.permissionFlag = permissionFlagResult.actions;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(flatRoleTargetMaps)) {
|
||||
const { from: fromFlatRoleTargetMaps, to: toFlatRoleTargetMaps } =
|
||||
flatRoleTargetMaps;
|
||||
@@ -811,6 +839,12 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
...aggregatedOrchestratorActionsReport.roleTarget.update,
|
||||
///
|
||||
|
||||
// Permission flags
|
||||
...aggregatedOrchestratorActionsReport.permissionFlag.delete,
|
||||
...aggregatedOrchestratorActionsReport.permissionFlag.create,
|
||||
...aggregatedOrchestratorActionsReport.permissionFlag.update,
|
||||
///
|
||||
|
||||
// Agents
|
||||
...aggregatedOrchestratorActionsReport.agent.delete,
|
||||
...aggregatedOrchestratorActionsReport.agent.create,
|
||||
|
||||
+2
@@ -28,8 +28,10 @@ exports[`ALL_UNIVERSAL_FLAT_ENTITY_FOREIGN_KEY_AGGREGATOR_PROPERTIES should matc
|
||||
"widgetUniversalIdentifiers",
|
||||
],
|
||||
"pageLayoutWidget": [],
|
||||
"permissionFlag": [],
|
||||
"role": [
|
||||
"roleTargetUniversalIdentifiers",
|
||||
"permissionFlagUniversalIdentifiers",
|
||||
"rowLevelPermissionPredicateUniversalIdentifiers",
|
||||
"rowLevelPermissionPredicateGroupUniversalIdentifiers",
|
||||
],
|
||||
|
||||
+2
@@ -35,6 +35,8 @@ export const ALL_JSONB_PROPERTIES_WITH_SERIALIZED_RELATION_BY_METADATA_NAME = {
|
||||
},
|
||||
commandMenuItem: {},
|
||||
navigationMenuItem: {},
|
||||
objectPermission: {},
|
||||
permissionFlag: {},
|
||||
frontComponent: {},
|
||||
} as const satisfies {
|
||||
[P in AllMetadataName]: Partial<{
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { type ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
|
||||
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
|
||||
|
||||
export type UniversalFlatObjectPermission = UniversalFlatEntityFrom<
|
||||
ObjectPermissionEntity,
|
||||
'objectPermission'
|
||||
>;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { type PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { type UniversalFlatEntityFrom } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-entity-from.type';
|
||||
|
||||
export type UniversalFlatPermissionFlag = UniversalFlatEntityFrom<
|
||||
PermissionFlagEntity,
|
||||
'permissionFlag'
|
||||
>;
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
|
||||
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
|
||||
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
|
||||
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
|
||||
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
|
||||
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
|
||||
|
||||
export type FlatCreateObjectPermissionAction =
|
||||
BaseFlatCreateWorkspaceMigrationAction<'objectPermission'>;
|
||||
|
||||
export type FlatUpdateObjectPermissionAction =
|
||||
BaseFlatUpdateWorkspaceMigrationAction<'objectPermission'>;
|
||||
|
||||
export type FlatDeleteObjectPermissionAction =
|
||||
BaseFlatDeleteWorkspaceMigrationAction<'objectPermission'>;
|
||||
|
||||
export type UniversalCreateObjectPermissionAction =
|
||||
BaseUniversalCreateWorkspaceMigrationAction<'objectPermission'>;
|
||||
|
||||
export type UniversalUpdateObjectPermissionAction =
|
||||
BaseUniversalUpdateWorkspaceMigrationAction<'objectPermission'>;
|
||||
|
||||
export type UniversalDeleteObjectPermissionAction =
|
||||
BaseUniversalDeleteWorkspaceMigrationAction<'objectPermission'>;
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { type BaseFlatCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-create-workspace-migration-action.type';
|
||||
import { type BaseFlatDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-delete-workspace-migration-action.type';
|
||||
import { type BaseFlatUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-flat-update-workspace-migration-action.type';
|
||||
import { type BaseUniversalCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-create-workspace-migration-action.type';
|
||||
import { type BaseUniversalDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-delete-workspace-migration-action.type';
|
||||
import { type BaseUniversalUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-universal-update-workspace-migration-action.type';
|
||||
|
||||
export type FlatCreatePermissionFlagAction =
|
||||
BaseFlatCreateWorkspaceMigrationAction<'permissionFlag'>;
|
||||
|
||||
export type FlatUpdatePermissionFlagAction =
|
||||
BaseFlatUpdateWorkspaceMigrationAction<'permissionFlag'>;
|
||||
|
||||
export type FlatDeletePermissionFlagAction =
|
||||
BaseFlatDeleteWorkspaceMigrationAction<'permissionFlag'>;
|
||||
|
||||
export type UniversalCreatePermissionFlagAction =
|
||||
BaseUniversalCreateWorkspaceMigrationAction<'permissionFlag'>;
|
||||
|
||||
export type UniversalUpdatePermissionFlagAction =
|
||||
BaseUniversalUpdateWorkspaceMigrationAction<'permissionFlag'>;
|
||||
|
||||
export type UniversalDeletePermissionFlagAction =
|
||||
BaseUniversalDeleteWorkspaceMigrationAction<'permissionFlag'>;
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
|
||||
|
||||
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service';
|
||||
import { UniversalUpdatePermissionFlagAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/permission-flag/types/workspace-migration-permission-flag-action.type';
|
||||
import { FlatPermissionFlagValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-permission-flag-validator.service';
|
||||
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
|
||||
import { UniversalFlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-result.type';
|
||||
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationPermissionFlagActionsBuilderService extends WorkspaceEntityMigrationBuilderService<
|
||||
typeof ALL_METADATA_NAME.permissionFlag
|
||||
> {
|
||||
constructor(
|
||||
private readonly flatPermissionFlagValidatorService: FlatPermissionFlagValidatorService,
|
||||
) {
|
||||
super(ALL_METADATA_NAME.permissionFlag);
|
||||
}
|
||||
|
||||
protected validateFlatEntityCreation(
|
||||
args: UniversalFlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.permissionFlag
|
||||
>,
|
||||
): UniversalFlatEntityValidationReturnType<
|
||||
typeof ALL_METADATA_NAME.permissionFlag,
|
||||
'create'
|
||||
> {
|
||||
const validationResult =
|
||||
this.flatPermissionFlagValidatorService.validateFlatPermissionFlagCreation(
|
||||
args,
|
||||
);
|
||||
|
||||
if (validationResult.errors.length > 0) {
|
||||
return {
|
||||
status: 'fail',
|
||||
...validationResult,
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityToValidate: flatPermissionFlagToValidate } = args;
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: {
|
||||
type: 'create',
|
||||
metadataName: 'permissionFlag',
|
||||
flatEntity: flatPermissionFlagToValidate,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected validateFlatEntityDeletion(
|
||||
args: UniversalFlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.permissionFlag
|
||||
>,
|
||||
): UniversalFlatEntityValidationReturnType<
|
||||
typeof ALL_METADATA_NAME.permissionFlag,
|
||||
'delete'
|
||||
> {
|
||||
const validationResult =
|
||||
this.flatPermissionFlagValidatorService.validateFlatPermissionFlagDeletion(
|
||||
args,
|
||||
);
|
||||
|
||||
if (validationResult.errors.length > 0) {
|
||||
return {
|
||||
status: 'fail',
|
||||
...validationResult,
|
||||
};
|
||||
}
|
||||
|
||||
const { flatEntityToValidate: flatPermissionFlagToValidate } = args;
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: {
|
||||
type: 'delete',
|
||||
metadataName: 'permissionFlag',
|
||||
universalIdentifier: flatPermissionFlagToValidate.universalIdentifier,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected validateFlatEntityUpdate(
|
||||
args: FlatEntityUpdateValidationArgs<
|
||||
typeof ALL_METADATA_NAME.permissionFlag
|
||||
>,
|
||||
): UniversalFlatEntityValidationReturnType<
|
||||
typeof ALL_METADATA_NAME.permissionFlag,
|
||||
'update'
|
||||
> {
|
||||
const validationResult =
|
||||
this.flatPermissionFlagValidatorService.validateFlatPermissionFlagUpdate(
|
||||
args,
|
||||
);
|
||||
|
||||
if (validationResult.errors.length > 0) {
|
||||
return {
|
||||
status: 'fail',
|
||||
...validationResult,
|
||||
};
|
||||
}
|
||||
|
||||
const { universalIdentifier, flatEntityUpdate } = args;
|
||||
|
||||
const updatePermissionFlagAction: UniversalUpdatePermissionFlagAction = {
|
||||
type: 'update',
|
||||
metadataName: 'permissionFlag',
|
||||
universalIdentifier,
|
||||
update: flatEntityUpdate,
|
||||
};
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: updatePermissionFlagAction,
|
||||
};
|
||||
}
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
|
||||
import { PermissionsExceptionCode } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
|
||||
import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util';
|
||||
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-update-validation-args.type';
|
||||
import { UniversalFlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/universal-flat-entity-validation-args.type';
|
||||
|
||||
@Injectable()
|
||||
export class FlatPermissionFlagValidatorService {
|
||||
validateFlatPermissionFlagCreation({
|
||||
flatEntityToValidate: flatPermissionFlagToValidate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatPermissionFlagMaps: optimisticFlatPermissionFlagMaps,
|
||||
flatRoleMaps,
|
||||
},
|
||||
}: UniversalFlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.permissionFlag
|
||||
>): FailedFlatEntityValidation<'permissionFlag', 'create'> {
|
||||
const validationResult = getEmptyFlatEntityValidationError({
|
||||
flatEntityMinimalInformation: {
|
||||
universalIdentifier: flatPermissionFlagToValidate.universalIdentifier,
|
||||
roleUniversalIdentifier:
|
||||
flatPermissionFlagToValidate.roleUniversalIdentifier,
|
||||
},
|
||||
metadataName: 'permissionFlag',
|
||||
type: 'create',
|
||||
});
|
||||
|
||||
const existingByUniversalId = findFlatEntityByUniversalIdentifier({
|
||||
universalIdentifier: flatPermissionFlagToValidate.universalIdentifier,
|
||||
flatEntityMaps: optimisticFlatPermissionFlagMaps,
|
||||
});
|
||||
|
||||
if (isDefined(existingByUniversalId)) {
|
||||
validationResult.errors.push({
|
||||
code: PermissionsExceptionCode.INVALID_SETTING,
|
||||
message: t`Permission flag with universal identifier ${flatPermissionFlagToValidate.universalIdentifier} already exists`,
|
||||
userFriendlyMessage: msg`Permission flag already exists`,
|
||||
});
|
||||
}
|
||||
|
||||
const referencedRole = findFlatEntityByUniversalIdentifier({
|
||||
universalIdentifier: flatPermissionFlagToValidate.roleUniversalIdentifier,
|
||||
flatEntityMaps: flatRoleMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(referencedRole)) {
|
||||
validationResult.errors.push({
|
||||
code: PermissionsExceptionCode.ROLE_NOT_FOUND,
|
||||
message: t`Role not found`,
|
||||
userFriendlyMessage: msg`Role not found`,
|
||||
});
|
||||
}
|
||||
|
||||
const isValidFlag =
|
||||
isDefined(flatPermissionFlagToValidate.flag) &&
|
||||
Object.values(PermissionFlagType).includes(
|
||||
flatPermissionFlagToValidate.flag,
|
||||
);
|
||||
|
||||
if (!isValidFlag) {
|
||||
validationResult.errors.push({
|
||||
code: PermissionsExceptionCode.INVALID_SETTING,
|
||||
message: t`Invalid permission flag value`,
|
||||
userFriendlyMessage: msg`Invalid permission setting`,
|
||||
});
|
||||
}
|
||||
|
||||
const duplicateForSameRole = Object.values(
|
||||
optimisticFlatPermissionFlagMaps.byUniversalIdentifier,
|
||||
).filter(
|
||||
(pf) =>
|
||||
isDefined(pf) &&
|
||||
pf.roleUniversalIdentifier ===
|
||||
flatPermissionFlagToValidate.roleUniversalIdentifier &&
|
||||
pf.flag === flatPermissionFlagToValidate.flag &&
|
||||
pf.universalIdentifier !==
|
||||
flatPermissionFlagToValidate.universalIdentifier,
|
||||
);
|
||||
|
||||
if (duplicateForSameRole.length > 0) {
|
||||
validationResult.errors.push({
|
||||
code: PermissionsExceptionCode.INVALID_SETTING,
|
||||
message: t`Permission flag for this role and setting already exists`,
|
||||
userFriendlyMessage: msg`This permission is already set for the role`,
|
||||
});
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
validateFlatPermissionFlagUpdate({
|
||||
universalIdentifier,
|
||||
flatEntityUpdate,
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatPermissionFlagMaps: optimisticFlatPermissionFlagMaps,
|
||||
flatRoleMaps,
|
||||
},
|
||||
}: FlatEntityUpdateValidationArgs<
|
||||
typeof ALL_METADATA_NAME.permissionFlag
|
||||
>): FailedFlatEntityValidation<'permissionFlag', 'update'> {
|
||||
const existingFlatPermissionFlag = findFlatEntityByUniversalIdentifier({
|
||||
universalIdentifier,
|
||||
flatEntityMaps: optimisticFlatPermissionFlagMaps,
|
||||
});
|
||||
|
||||
const validationResult = getEmptyFlatEntityValidationError({
|
||||
flatEntityMinimalInformation: {
|
||||
universalIdentifier,
|
||||
},
|
||||
metadataName: 'permissionFlag',
|
||||
type: 'update',
|
||||
});
|
||||
|
||||
if (!isDefined(existingFlatPermissionFlag)) {
|
||||
validationResult.errors.push({
|
||||
code: PermissionsExceptionCode.PERMISSION_NOT_FOUND,
|
||||
message: t`Permission flag to update not found`,
|
||||
userFriendlyMessage: msg`Permission flag not found`,
|
||||
});
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const updatedFlatPermissionFlag = {
|
||||
...existingFlatPermissionFlag,
|
||||
...flatEntityUpdate,
|
||||
};
|
||||
|
||||
if (isDefined(flatEntityUpdate.roleUniversalIdentifier)) {
|
||||
const referencedRole = findFlatEntityByUniversalIdentifier({
|
||||
universalIdentifier: updatedFlatPermissionFlag.roleUniversalIdentifier,
|
||||
flatEntityMaps: flatRoleMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(referencedRole)) {
|
||||
validationResult.errors.push({
|
||||
code: PermissionsExceptionCode.ROLE_NOT_FOUND,
|
||||
message: t`Role not found`,
|
||||
userFriendlyMessage: msg`Role not found`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(flatEntityUpdate.flag)) {
|
||||
const isValidFlag = Object.values(PermissionFlagType).includes(
|
||||
flatEntityUpdate.flag as PermissionFlagType,
|
||||
);
|
||||
|
||||
if (!isValidFlag) {
|
||||
validationResult.errors.push({
|
||||
code: PermissionsExceptionCode.INVALID_SETTING,
|
||||
message: t`Invalid permission flag value`,
|
||||
userFriendlyMessage: msg`Invalid permission setting`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const duplicateForSameRole = Object.values(
|
||||
optimisticFlatPermissionFlagMaps.byUniversalIdentifier,
|
||||
).filter(
|
||||
(pf) =>
|
||||
isDefined(pf) &&
|
||||
pf.roleUniversalIdentifier ===
|
||||
updatedFlatPermissionFlag.roleUniversalIdentifier &&
|
||||
pf.flag === updatedFlatPermissionFlag.flag &&
|
||||
pf.universalIdentifier !== universalIdentifier,
|
||||
);
|
||||
|
||||
if (duplicateForSameRole.length > 0) {
|
||||
validationResult.errors.push({
|
||||
code: PermissionsExceptionCode.INVALID_SETTING,
|
||||
message: t`Permission flag for this role and setting already exists`,
|
||||
userFriendlyMessage: msg`This permission is already set for the role`,
|
||||
});
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
validateFlatPermissionFlagDeletion({
|
||||
flatEntityToValidate: { universalIdentifier },
|
||||
optimisticFlatEntityMapsAndRelatedFlatEntityMaps: {
|
||||
flatPermissionFlagMaps: optimisticFlatPermissionFlagMaps,
|
||||
},
|
||||
}: UniversalFlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.permissionFlag
|
||||
>): FailedFlatEntityValidation<'permissionFlag', 'delete'> {
|
||||
const validationResult = getEmptyFlatEntityValidationError({
|
||||
flatEntityMinimalInformation: {
|
||||
universalIdentifier,
|
||||
},
|
||||
metadataName: 'permissionFlag',
|
||||
type: 'delete',
|
||||
});
|
||||
|
||||
const existingFlatPermissionFlag = findFlatEntityByUniversalIdentifier({
|
||||
universalIdentifier,
|
||||
flatEntityMaps: optimisticFlatPermissionFlagMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(existingFlatPermissionFlag)) {
|
||||
validationResult.errors.push({
|
||||
code: PermissionsExceptionCode.PERMISSION_NOT_FOUND,
|
||||
message: t`Permission flag to delete not found`,
|
||||
userFriendlyMessage: msg`Permission flag not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -8,25 +8,26 @@ import { FlatCommandMenuItemValidatorService } from 'src/engine/workspace-manage
|
||||
import { FlatFieldMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-field-metadata-validator.service';
|
||||
import { FlatFrontComponentValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-front-component-validator.service';
|
||||
import { FlatIndexValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-index-metadata-validator.service';
|
||||
import { FlatLogicFunctionValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-logic-function-validator.service';
|
||||
import { FlatNavigationMenuItemValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-navigation-menu-item-validator.service';
|
||||
import { FlatObjectMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-object-metadata-validator.service';
|
||||
import { FlatPageLayoutTabValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-tab-validator.service';
|
||||
import { FlatPageLayoutValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-validator.service';
|
||||
import { FlatPageLayoutWidgetValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service';
|
||||
import { FlatPermissionFlagValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-permission-flag-validator.service';
|
||||
import { FlatRoleTargetValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-target-validator.service';
|
||||
import { FlatRoleValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-validator.service';
|
||||
import { FlatRowLevelPermissionPredicateGroupValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-group-validator.service';
|
||||
import { FlatRowLevelPermissionPredicateValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-validator.service';
|
||||
import { FlatLogicFunctionValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-logic-function-validator.service';
|
||||
import { FlatSkillValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-skill-validator.service';
|
||||
import { FlatViewFieldGroupValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-field-group-validator.service';
|
||||
import { FlatViewFieldValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-field-validator.service';
|
||||
import { FlatViewFilterGroupValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-group-validator.service';
|
||||
import { FlatViewFilterValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-filter-validator.service';
|
||||
import { FlatViewGroupValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-group-validator.service';
|
||||
import { FlatViewSortValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-sort-validator.service';
|
||||
import { FlatViewValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-validator.service';
|
||||
import { FlatWebhookValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-webhook-validator.service';
|
||||
import { FlatViewSortValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-view-sort-validator.service';
|
||||
|
||||
@Module({
|
||||
imports: [FeatureFlagModule],
|
||||
@@ -38,6 +39,7 @@ import { FlatViewSortValidatorService } from 'src/engine/workspace-manager/works
|
||||
FlatViewGroupValidatorService,
|
||||
FlatViewFieldGroupValidatorService,
|
||||
FlatViewSortValidatorService,
|
||||
FlatPermissionFlagValidatorService,
|
||||
FlatIndexValidatorService,
|
||||
FlatFieldMetadataValidatorService,
|
||||
FlatObjectMetadataValidatorService,
|
||||
@@ -66,6 +68,7 @@ import { FlatViewSortValidatorService } from 'src/engine/workspace-manager/works
|
||||
FlatViewGroupValidatorService,
|
||||
FlatViewFieldGroupValidatorService,
|
||||
FlatViewSortValidatorService,
|
||||
FlatPermissionFlagValidatorService,
|
||||
FlatIndexValidatorService,
|
||||
FlatFieldMetadataValidatorService,
|
||||
FlatObjectMetadataValidatorService,
|
||||
|
||||
+10
-7
@@ -4,29 +4,30 @@ import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-
|
||||
import { FlatFieldMetadataTypeValidatorService } from 'src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-type-validator.service';
|
||||
import { WorkspaceMigrationAgentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/workspace-migration-agent-actions-builder.service';
|
||||
import { WorkspaceMigrationCommandMenuItemActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/workspace-migration-command-menu-item-actions-builder.service';
|
||||
import { WorkspaceMigrationNavigationMenuItemActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/navigation-menu-item/workspace-migration-navigation-menu-item-actions-builder.service';
|
||||
import { WorkspaceMigrationFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/workspace-migration-field-actions-builder.service';
|
||||
import { WorkspaceMigrationFrontComponentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/workspace-migration-front-component-actions-builder.service';
|
||||
import { WorkspaceMigrationIndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/index/workspace-migration-index-actions-builder.service';
|
||||
import { WorkspaceMigrationLogicFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/logic-function/workspace-migration-logic-function-actions-builder.service';
|
||||
import { WorkspaceMigrationNavigationMenuItemActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/navigation-menu-item/workspace-migration-navigation-menu-item-actions-builder.service';
|
||||
import { WorkspaceMigrationObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/workspace-migration-object-actions-builder.service';
|
||||
import { WorkspaceMigrationPageLayoutTabActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-tab/workspace-migration-page-layout-tab-actions-builder.service';
|
||||
import { WorkspaceMigrationPageLayoutWidgetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-widget/workspace-migration-page-layout-widget-actions-builder.service';
|
||||
import { WorkspaceMigrationPageLayoutActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/workspace-migration-page-layout-actions-builder.service';
|
||||
import { WorkspaceMigrationPermissionFlagActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/permission-flag/workspace-migration-permission-flag-actions-builder.service';
|
||||
import { WorkspaceMigrationRoleTargetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role-target/workspace-migration-role-target-actions-builder.service';
|
||||
import { WorkspaceMigrationRoleActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/workspace-migration-role-actions-builder.service';
|
||||
import { WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate-group/workspace-migration-row-level-permission-predicate-group-actions-builder.service';
|
||||
import { WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate/workspace-migration-row-level-permission-predicate-actions-builder.service';
|
||||
import { WorkspaceMigrationLogicFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/logic-function/workspace-migration-logic-function-actions-builder.service';
|
||||
import { WorkspaceMigrationSkillActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/skill/workspace-migration-skill-actions-builder.service';
|
||||
import { WorkspaceMigrationFrontComponentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/workspace-migration-front-component-actions-builder.service';
|
||||
import { WorkspaceMigrationViewFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field/workspace-migration-view-field-actions-builder.service';
|
||||
import { WorkspaceMigrationViewFieldGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field-group/workspace-migration-view-field-group-actions-builder.service';
|
||||
import { WorkspaceMigrationWebhookActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/webhook/workspace-migration-webhook-actions-builder.service';
|
||||
import { WorkspaceMigrationViewFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field/workspace-migration-view-field-actions-builder.service';
|
||||
import { WorkspaceMigrationViewFilterGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter-group/workspace-migration-view-filter-group-actions-builder.service';
|
||||
import { WorkspaceMigrationViewFilterActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter/workspace-migration-view-filter-actions-builder.service';
|
||||
import { WorkspaceMigrationViewGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-group/workspace-migration-view-group-actions-builder.service';
|
||||
import { WorkspaceMigrationViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view/workspace-migration-view-actions-builder.service';
|
||||
import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/workspace-migration-builder-validators.module';
|
||||
import { WorkspaceMigrationViewSortActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-sort/workspace-migration-view-sort-actions.builder.service';
|
||||
import { WorkspaceMigrationViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view/workspace-migration-view-actions-builder.service';
|
||||
import { WorkspaceMigrationWebhookActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/webhook/workspace-migration-webhook-actions-builder.service';
|
||||
import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/workspace-migration-builder-validators.module';
|
||||
|
||||
@Module({
|
||||
imports: [FeatureFlagModule, WorkspaceMigrationBuilderValidatorsModule],
|
||||
@@ -40,6 +41,7 @@ import { WorkspaceMigrationViewSortActionsBuilderService } from 'src/engine/work
|
||||
WorkspaceMigrationViewGroupActionsBuilderService,
|
||||
WorkspaceMigrationViewFieldGroupActionsBuilderService,
|
||||
WorkspaceMigrationViewSortActionsBuilderService,
|
||||
WorkspaceMigrationPermissionFlagActionsBuilderService,
|
||||
WorkspaceMigrationIndexActionsBuilderService,
|
||||
WorkspaceMigrationLogicFunctionActionsBuilderService,
|
||||
WorkspaceMigrationFieldActionsBuilderService,
|
||||
@@ -67,6 +69,7 @@ import { WorkspaceMigrationViewSortActionsBuilderService } from 'src/engine/work
|
||||
WorkspaceMigrationViewGroupActionsBuilderService,
|
||||
WorkspaceMigrationViewFieldGroupActionsBuilderService,
|
||||
WorkspaceMigrationViewSortActionsBuilderService,
|
||||
WorkspaceMigrationPermissionFlagActionsBuilderService,
|
||||
WorkspaceMigrationFieldActionsBuilderService,
|
||||
WorkspaceMigrationLogicFunctionActionsBuilderService,
|
||||
WorkspaceMigrationRoleActionsBuilderService,
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
|
||||
import {
|
||||
FlatCreatePermissionFlagAction,
|
||||
UniversalCreatePermissionFlagAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/permission-flag/types/workspace-migration-permission-flag-action.type';
|
||||
import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
|
||||
@Injectable()
|
||||
export class CreatePermissionFlagActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
'create',
|
||||
'permissionFlag',
|
||||
) {
|
||||
override async transpileUniversalActionToFlatAction({
|
||||
action,
|
||||
allFlatEntityMaps,
|
||||
flatApplication,
|
||||
workspaceId,
|
||||
}: WorkspaceMigrationActionRunnerArgs<UniversalCreatePermissionFlagAction>): Promise<FlatCreatePermissionFlagAction> {
|
||||
const { roleId } = resolveUniversalRelationIdentifiersToIds({
|
||||
flatEntityMaps: allFlatEntityMaps,
|
||||
metadataName: action.metadataName,
|
||||
universalForeignKeyValues: action.flatEntity,
|
||||
});
|
||||
|
||||
return {
|
||||
...action,
|
||||
flatEntity: {
|
||||
...action.flatEntity,
|
||||
roleId,
|
||||
applicationId: flatApplication.id,
|
||||
id: action.id ?? v4(),
|
||||
workspaceId,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatCreatePermissionFlagAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner } = context;
|
||||
const { flatEntity } = flatAction;
|
||||
|
||||
await this.insertFlatEntitiesInRepository({
|
||||
queryRunner,
|
||||
flatEntities: [flatEntity],
|
||||
});
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
_context: WorkspaceMigrationActionRunnerContext<FlatCreatePermissionFlagAction>,
|
||||
): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import {
|
||||
FlatDeletePermissionFlagAction,
|
||||
UniversalDeletePermissionFlagAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/permission-flag/types/workspace-migration-permission-flag-action.type';
|
||||
import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
|
||||
@Injectable()
|
||||
export class DeletePermissionFlagActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
'delete',
|
||||
'permissionFlag',
|
||||
) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
override async transpileUniversalActionToFlatAction(
|
||||
context: WorkspaceMigrationActionRunnerArgs<UniversalDeletePermissionFlagAction>,
|
||||
): Promise<FlatDeletePermissionFlagAction> {
|
||||
return this.transpileUniversalDeleteActionToFlatDeleteAction(context);
|
||||
}
|
||||
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatDeletePermissionFlagAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
|
||||
const permissionFlagRepository =
|
||||
queryRunner.manager.getRepository<PermissionFlagEntity>(
|
||||
PermissionFlagEntity,
|
||||
);
|
||||
|
||||
await permissionFlagRepository.delete({
|
||||
id: flatAction.entityId,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
_context: WorkspaceMigrationActionRunnerContext<FlatDeletePermissionFlagAction>,
|
||||
): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
|
||||
import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity';
|
||||
import { resolveUniversalUpdateRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-update-relation-identifiers-to-ids.util';
|
||||
import {
|
||||
FlatUpdatePermissionFlagAction,
|
||||
UniversalUpdatePermissionFlagAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/permission-flag/types/workspace-migration-permission-flag-action.type';
|
||||
import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
|
||||
|
||||
@Injectable()
|
||||
export class UpdatePermissionFlagActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
'update',
|
||||
'permissionFlag',
|
||||
) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
override async transpileUniversalActionToFlatAction(
|
||||
context: WorkspaceMigrationActionRunnerArgs<UniversalUpdatePermissionFlagAction>,
|
||||
): Promise<FlatUpdatePermissionFlagAction> {
|
||||
const { action, allFlatEntityMaps } = context;
|
||||
|
||||
const flatPermissionFlag = findFlatEntityByUniversalIdentifierOrThrow({
|
||||
flatEntityMaps: allFlatEntityMaps.flatPermissionFlagMaps,
|
||||
universalIdentifier: action.universalIdentifier,
|
||||
});
|
||||
|
||||
const update = resolveUniversalUpdateRelationIdentifiersToIds({
|
||||
metadataName: 'permissionFlag',
|
||||
universalUpdate: action.update,
|
||||
allFlatEntityMaps,
|
||||
});
|
||||
|
||||
return {
|
||||
type: 'update',
|
||||
metadataName: 'permissionFlag',
|
||||
entityId: flatPermissionFlag.id,
|
||||
update,
|
||||
};
|
||||
}
|
||||
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerContext<FlatUpdatePermissionFlagAction>,
|
||||
): Promise<void> {
|
||||
const { flatAction, queryRunner, workspaceId } = context;
|
||||
const { entityId, update } = flatAction;
|
||||
|
||||
const permissionFlagRepository =
|
||||
queryRunner.manager.getRepository<PermissionFlagEntity>(
|
||||
PermissionFlagEntity,
|
||||
);
|
||||
|
||||
await permissionFlagRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
update,
|
||||
);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
_context: WorkspaceMigrationActionRunnerContext<FlatUpdatePermissionFlagAction>,
|
||||
): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
+22
-15
@@ -9,15 +9,21 @@ import { UpdateAgentActionHandlerService } from 'src/engine/workspace-manager/wo
|
||||
import { CreateCommandMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/command-menu-item/services/create-command-menu-item-action-handler.service';
|
||||
import { DeleteCommandMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/command-menu-item/services/delete-command-menu-item-action-handler.service';
|
||||
import { UpdateCommandMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/command-menu-item/services/update-command-menu-item-action-handler.service';
|
||||
import { CreateNavigationMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/navigation-menu-item/services/create-navigation-menu-item-action-handler.service';
|
||||
import { DeleteNavigationMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/navigation-menu-item/services/delete-navigation-menu-item-action-handler.service';
|
||||
import { UpdateNavigationMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/navigation-menu-item/services/update-navigation-menu-item-action-handler.service';
|
||||
import { CreateFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/create-field-action-handler.service';
|
||||
import { DeleteFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/delete-field-action-handler.service';
|
||||
import { UpdateFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/update-field-action-handler.service';
|
||||
import { CreateFrontComponentActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/front-component/services/create-front-component-action-handler.service';
|
||||
import { DeleteFrontComponentActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/front-component/services/delete-front-component-action-handler.service';
|
||||
import { UpdateFrontComponentActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/front-component/services/update-front-component-action-handler.service';
|
||||
import { CreateIndexActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/services/create-index-action-handler.service';
|
||||
import { DeleteIndexActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/services/delete-index-action-handler.service';
|
||||
import { UpdateIndexActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/index/services/update-index-action-handler.service';
|
||||
import { CreateLogicFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/logic-function/services/create-logic-function-action-handler.service';
|
||||
import { DeleteLogicFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/logic-function/services/delete-logic-function-action-handler.service';
|
||||
import { UpdateLogicFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/logic-function/services/update-logic-function-action-handler.service';
|
||||
import { CreateNavigationMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/navigation-menu-item/services/create-navigation-menu-item-action-handler.service';
|
||||
import { DeleteNavigationMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/navigation-menu-item/services/delete-navigation-menu-item-action-handler.service';
|
||||
import { UpdateNavigationMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/navigation-menu-item/services/update-navigation-menu-item-action-handler.service';
|
||||
import { CreateObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/object/services/create-object-action-handler.service';
|
||||
import { DeleteObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/object/services/delete-object-action-handler.service';
|
||||
import { UpdateObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/object/services/update-object-action-handler.service';
|
||||
@@ -30,6 +36,9 @@ import { UpdatePageLayoutWidgetActionHandlerService } from 'src/engine/workspace
|
||||
import { CreatePageLayoutActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/page-layout/services/create-page-layout-action-handler.service';
|
||||
import { DeletePageLayoutActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/page-layout/services/delete-page-layout-action-handler.service';
|
||||
import { UpdatePageLayoutActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/page-layout/services/update-page-layout-action-handler.service';
|
||||
import { CreatePermissionFlagActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/permission-flag/services/create-permission-flag-action-handler.service';
|
||||
import { DeletePermissionFlagActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/permission-flag/services/delete-permission-flag-action-handler.service';
|
||||
import { UpdatePermissionFlagActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/permission-flag/services/update-permission-flag-action-handler.service';
|
||||
import { CreateRoleTargetActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/role-target/services/create-role-target-action-handler.service';
|
||||
import { DeleteRoleTargetActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/role-target/services/delete-role-target-action-handler.service';
|
||||
import { UpdateRoleTargetActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/role-target/services/update-role-target-action-handler.service';
|
||||
@@ -42,18 +51,9 @@ import { UpdateRowLevelPermissionPredicateGroupActionHandlerService } from 'src/
|
||||
import { CreateRowLevelPermissionPredicateActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/row-level-permission-predicate/services/create-row-level-permission-predicate-action-handler.service';
|
||||
import { DeleteRowLevelPermissionPredicateActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/row-level-permission-predicate/services/delete-row-level-permission-predicate-action-handler.service';
|
||||
import { UpdateRowLevelPermissionPredicateActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/row-level-permission-predicate/services/update-row-level-permission-predicate-action-handler.service';
|
||||
import { CreateLogicFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/logic-function/services/create-logic-function-action-handler.service';
|
||||
import { DeleteLogicFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/logic-function/services/delete-logic-function-action-handler.service';
|
||||
import { UpdateLogicFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/logic-function/services/update-logic-function-action-handler.service';
|
||||
import { CreateSkillActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/skill/services/create-skill-action-handler.service';
|
||||
import { DeleteSkillActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/skill/services/delete-skill-action-handler.service';
|
||||
import { CreateFrontComponentActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/front-component/services/create-front-component-action-handler.service';
|
||||
import { UpdateFrontComponentActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/front-component/services/update-front-component-action-handler.service';
|
||||
import { DeleteFrontComponentActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/front-component/services/delete-front-component-action-handler.service';
|
||||
import { UpdateSkillActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/skill/services/update-skill-action-handler.service';
|
||||
import { CreateWebhookActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/webhook/services/create-webhook-action-handler.service';
|
||||
import { DeleteWebhookActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/webhook/services/delete-webhook-action-handler.service';
|
||||
import { UpdateWebhookActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/webhook/services/update-webhook-action-handler.service';
|
||||
import { CreateViewFieldGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-field-group/services/create-view-field-group-action-handler.service';
|
||||
import { DeleteViewFieldGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-field-group/services/delete-view-field-group-action-handler.service';
|
||||
import { UpdateViewFieldGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-field-group/services/update-view-field-group-action-handler.service';
|
||||
@@ -69,12 +69,15 @@ import { UpdateViewFilterActionHandlerService } from 'src/engine/workspace-manag
|
||||
import { CreateViewGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-group/services/create-view-group-action-handler.service';
|
||||
import { DeleteViewGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-group/services/delete-view-group-action-handler.service';
|
||||
import { UpdateViewGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-group/services/update-view-group-action-handler.service';
|
||||
import { CreateViewSortActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-sort/services/create-view-sort-action-handler.service';
|
||||
import { DeleteViewSortActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-sort/services/delete-view-sort-action-handler.service';
|
||||
import { UpdateViewSortActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-sort/services/update-view-sort-action-handler.service';
|
||||
import { CreateViewActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view/services/create-view-action-handler.service';
|
||||
import { DeleteViewActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view/services/delete-view-action-handler.service';
|
||||
import { UpdateViewActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view/services/update-view-action-handler.service';
|
||||
import { CreateViewSortActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-sort/services/create-view-sort-action-handler.service';
|
||||
import { UpdateViewSortActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-sort/services/update-view-sort-action-handler.service';
|
||||
import { DeleteViewSortActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view-sort/services/delete-view-sort-action-handler.service';
|
||||
import { CreateWebhookActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/webhook/services/create-webhook-action-handler.service';
|
||||
import { DeleteWebhookActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/webhook/services/delete-webhook-action-handler.service';
|
||||
import { UpdateWebhookActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/webhook/services/update-webhook-action-handler.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -134,6 +137,10 @@ import { DeleteViewSortActionHandlerService } from 'src/engine/workspace-manager
|
||||
DeleteRoleTargetActionHandlerService,
|
||||
UpdateRoleTargetActionHandlerService,
|
||||
|
||||
CreatePermissionFlagActionHandlerService,
|
||||
UpdatePermissionFlagActionHandlerService,
|
||||
DeletePermissionFlagActionHandlerService,
|
||||
|
||||
CreateAgentActionHandlerService,
|
||||
UpdateAgentActionHandlerService,
|
||||
DeleteAgentActionHandlerService,
|
||||
|
||||
+1
@@ -19,6 +19,7 @@ export const METADATA_EVENTS_TO_EMIT = {
|
||||
pageLayoutTab: true,
|
||||
commandMenuItem: true,
|
||||
navigationMenuItem: true,
|
||||
permissionFlag: true,
|
||||
rowLevelPermissionPredicate: true,
|
||||
rowLevelPermissionPredicateGroup: true,
|
||||
index: true,
|
||||
|
||||
+1
@@ -89,6 +89,7 @@ const deriveAllMetadataEventsFromCreateAction = (
|
||||
case 'commandMenuItem':
|
||||
case 'frontComponent':
|
||||
case 'navigationMenuItem':
|
||||
case 'permissionFlag':
|
||||
case 'viewSort':
|
||||
case 'webhook': {
|
||||
return [
|
||||
|
||||
+1
@@ -53,6 +53,7 @@ const deriveAllMetadataEventsFromDeleteAction = ({
|
||||
case 'commandMenuItem':
|
||||
case 'frontComponent':
|
||||
case 'navigationMenuItem':
|
||||
case 'permissionFlag':
|
||||
case 'viewSort':
|
||||
case 'webhook': {
|
||||
const flatEntityToDelete = findFlatEntityByIdInFlatEntityMapsOrThrow<
|
||||
|
||||
+1
@@ -131,6 +131,7 @@ const deriveAllMetadataEventsFromUpdateAction = ({
|
||||
case 'commandMenuItem':
|
||||
case 'frontComponent':
|
||||
case 'navigationMenuItem':
|
||||
case 'permissionFlag':
|
||||
case 'viewSort':
|
||||
case 'webhook': {
|
||||
const flatEntityMapsKey = getMetadataFlatEntityMapsKey(
|
||||
|
||||
+1
@@ -68,6 +68,7 @@ export const optimisticallyApplyCreateActionOnAllFlatEntityMaps = ({
|
||||
case 'commandMenuItem':
|
||||
case 'frontComponent':
|
||||
case 'navigationMenuItem':
|
||||
case 'permissionFlag':
|
||||
case 'webhook': {
|
||||
addFlatEntityToFlatEntityAndRelatedEntityMapsThroughMutationOrThrow({
|
||||
flatEntity: flatAction.flatEntity,
|
||||
|
||||
+1
@@ -40,6 +40,7 @@ export const optimisticallyApplyDeleteActionOnAllFlatEntityMaps = ({
|
||||
case 'commandMenuItem':
|
||||
case 'frontComponent':
|
||||
case 'navigationMenuItem':
|
||||
case 'permissionFlag':
|
||||
case 'webhook': {
|
||||
const flatEntityToDelete = findFlatEntityByIdInFlatEntityMapsOrThrow<
|
||||
MetadataFlatEntity<typeof flatAction.metadataName>
|
||||
|
||||
+1
@@ -61,6 +61,7 @@ export const optimisticallyApplyUpdateActionOnAllFlatEntityMaps = ({
|
||||
case 'commandMenuItem':
|
||||
case 'frontComponent':
|
||||
case 'navigationMenuItem':
|
||||
case 'permissionFlag':
|
||||
case 'webhook': {
|
||||
const flatEntityMapsKey = getMetadataFlatEntityMapsKey(
|
||||
flatAction.metadataName,
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`Permission flag upsert should fail when permissionFlagKeys contains invalid enum value 1`] = `
|
||||
{
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"http": {
|
||||
"status": 400,
|
||||
},
|
||||
"userFriendlyMessage": "An error occurred.",
|
||||
},
|
||||
"message": "Value \"INVALID_FLAG\" does not exist in \"PermissionFlagType\" enum.",
|
||||
"name": "GraphQLError",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Permission flag upsert should fail when role is not editable (system role) 1`] = `
|
||||
{
|
||||
"extensions": {
|
||||
"code": "FORBIDDEN",
|
||||
"subCode": "ROLE_NOT_EDITABLE",
|
||||
"userFriendlyMessage": "This role cannot be modified because it is a system role. Only custom roles can be edited.",
|
||||
},
|
||||
"message": "Role is not editable",
|
||||
"name": "ForbiddenError",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Permission flag upsert should fail when roleId does not exist 1`] = `
|
||||
{
|
||||
"extensions": {
|
||||
"code": "NOT_FOUND",
|
||||
"subCode": "ROLE_NOT_FOUND",
|
||||
"userFriendlyMessage": "The role you are trying to modify could not be found.",
|
||||
},
|
||||
"message": "Role not found",
|
||||
"name": "NotFoundError",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Permission flag upsert should fail when roleId is not a valid UUID 1`] = `
|
||||
{
|
||||
"extensions": {
|
||||
"code": "GRAPHQL_VALIDATION_FAILED",
|
||||
"http": {
|
||||
"status": 400,
|
||||
},
|
||||
"userFriendlyMessage": "An error occurred.",
|
||||
"value": "invalid-uuid",
|
||||
},
|
||||
"message": "Invalid UUID: 'invalid-uuid'",
|
||||
"name": "ValidationError",
|
||||
}
|
||||
`;
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
import { expectOneNotInternalServerErrorSnapshot } from 'test/integration/graphql/utils/expect-one-not-internal-server-error-snapshot.util';
|
||||
import { upsertPermissionFlags } from 'test/integration/metadata/suites/permission-flag/utils/upsert-permission-flags.util';
|
||||
import { createOneRole } from 'test/integration/metadata/suites/role/utils/create-one-role.util';
|
||||
import { deleteOneRole } from 'test/integration/metadata/suites/role/utils/delete-one-role.util';
|
||||
import { findRoles } from 'test/integration/metadata/suites/role/utils/find-roles.util';
|
||||
import { jestExpectToBeDefined } from 'test/utils/jest-expect-to-be-defined.util.test';
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
import {
|
||||
eachTestingContextFilter,
|
||||
type EachTestingContext,
|
||||
} from 'twenty-shared/testing';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type UpsertPermissionFlagsInput } from 'src/engine/metadata-modules/permission-flag/dtos/upsert-permission-flag-input';
|
||||
|
||||
type GlobalTestContext = {
|
||||
editableRoleId: string;
|
||||
nonEditableRoleId: string;
|
||||
};
|
||||
|
||||
type TestContext = {
|
||||
input: (globalContext: GlobalTestContext) => UpsertPermissionFlagsInput;
|
||||
};
|
||||
|
||||
const failingPermissionFlagUpsertTestCases: EachTestingContext<TestContext>[] =
|
||||
[
|
||||
{
|
||||
title: 'when roleId is not a valid UUID',
|
||||
context: {
|
||||
input: () => ({
|
||||
roleId: 'invalid-uuid',
|
||||
permissionFlagKeys: [PermissionFlagType.DATA_MODEL],
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when roleId does not exist',
|
||||
context: {
|
||||
input: () => ({
|
||||
roleId: v4(),
|
||||
permissionFlagKeys: [PermissionFlagType.DATA_MODEL],
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when role is not editable (system role)',
|
||||
context: {
|
||||
input: (globalContext) => ({
|
||||
roleId: globalContext.nonEditableRoleId,
|
||||
permissionFlagKeys: [PermissionFlagType.DATA_MODEL],
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when permissionFlagKeys contains invalid enum value',
|
||||
context: {
|
||||
input: (globalContext) => ({
|
||||
roleId: globalContext.editableRoleId,
|
||||
permissionFlagKeys: ['INVALID_FLAG' as PermissionFlagType],
|
||||
}),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
describe('Permission flag upsert should fail', () => {
|
||||
let editableRoleId: string;
|
||||
let nonEditableRoleId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const { data: roleData } = await createOneRole({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
label: 'Test Role For Permission Flag Failing',
|
||||
description: 'Role for permission flag failing tests',
|
||||
icon: 'IconSettings',
|
||||
canUpdateAllSettings: false,
|
||||
canAccessAllTools: true,
|
||||
canReadAllObjectRecords: true,
|
||||
canUpdateAllObjectRecords: false,
|
||||
canSoftDeleteAllObjectRecords: false,
|
||||
canDestroyAllObjectRecords: false,
|
||||
canBeAssignedToUsers: true,
|
||||
canBeAssignedToAgents: false,
|
||||
canBeAssignedToApiKeys: false,
|
||||
},
|
||||
});
|
||||
|
||||
editableRoleId = roleData?.createOneRole?.id;
|
||||
jestExpectToBeDefined(editableRoleId);
|
||||
|
||||
const { data: rolesData } = await findRoles({
|
||||
expectToFail: false,
|
||||
gqlFields: `
|
||||
id
|
||||
label
|
||||
isEditable
|
||||
`,
|
||||
});
|
||||
|
||||
jestExpectToBeDefined(rolesData?.getRoles);
|
||||
const adminRole = rolesData.getRoles.find(
|
||||
(role: { label: string; isEditable: boolean }) =>
|
||||
role.label === 'Admin' && role.isEditable === false,
|
||||
);
|
||||
jestExpectToBeDefined(adminRole);
|
||||
nonEditableRoleId = adminRole.id;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
if (isDefined(editableRoleId)) {
|
||||
await deleteOneRole({
|
||||
expectToFail: false,
|
||||
input: { idToDelete: editableRoleId },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it.each(eachTestingContextFilter(failingPermissionFlagUpsertTestCases))(
|
||||
'$title',
|
||||
async ({ context }) => {
|
||||
const globalContext: GlobalTestContext = {
|
||||
editableRoleId: editableRoleId ?? '',
|
||||
nonEditableRoleId: nonEditableRoleId ?? '',
|
||||
};
|
||||
const input = context.input(globalContext);
|
||||
|
||||
const { errors } = await upsertPermissionFlags({
|
||||
expectToFail: true,
|
||||
input,
|
||||
});
|
||||
|
||||
expectOneNotInternalServerErrorSnapshot({
|
||||
errors,
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
import { upsertPermissionFlags } from 'test/integration/metadata/suites/permission-flag/utils/upsert-permission-flags.util';
|
||||
import { createOneRole } from 'test/integration/metadata/suites/role/utils/create-one-role.util';
|
||||
import { deleteOneRole } from 'test/integration/metadata/suites/role/utils/delete-one-role.util';
|
||||
import { jestExpectToBeDefined } from 'test/utils/jest-expect-to-be-defined.util.test';
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
|
||||
describe('Permission flag upsert should succeed', () => {
|
||||
let createdRoleId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const { data: roleData } = await createOneRole({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
label: 'Test Role For Permission Flag Success',
|
||||
description: 'Role for permission flag successful tests',
|
||||
icon: 'IconSettings',
|
||||
canUpdateAllSettings: false,
|
||||
canAccessAllTools: true,
|
||||
canReadAllObjectRecords: true,
|
||||
canUpdateAllObjectRecords: false,
|
||||
canSoftDeleteAllObjectRecords: false,
|
||||
canDestroyAllObjectRecords: false,
|
||||
canBeAssignedToUsers: true,
|
||||
canBeAssignedToAgents: false,
|
||||
canBeAssignedToApiKeys: false,
|
||||
},
|
||||
});
|
||||
|
||||
const roleId = roleData?.createOneRole?.id;
|
||||
jestExpectToBeDefined(roleId);
|
||||
createdRoleId = roleId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
if (createdRoleId) {
|
||||
await deleteOneRole({
|
||||
expectToFail: false,
|
||||
input: { idToDelete: createdRoleId },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('should upsert with empty permissionFlagKeys', async () => {
|
||||
const { data } = await upsertPermissionFlags({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
roleId: createdRoleId,
|
||||
permissionFlagKeys: [],
|
||||
},
|
||||
});
|
||||
|
||||
expect(data?.upsertPermissionFlags).toEqual([]);
|
||||
});
|
||||
|
||||
it('should upsert with one permission flag', async () => {
|
||||
const { data } = await upsertPermissionFlags({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
roleId: createdRoleId,
|
||||
permissionFlagKeys: [PermissionFlagType.DATA_MODEL],
|
||||
},
|
||||
});
|
||||
|
||||
expect(data?.upsertPermissionFlags).toHaveLength(1);
|
||||
expect(data?.upsertPermissionFlags?.[0]).toMatchObject({
|
||||
roleId: createdRoleId,
|
||||
flag: PermissionFlagType.DATA_MODEL,
|
||||
});
|
||||
expect(data?.upsertPermissionFlags?.[0].id).toBeDefined();
|
||||
});
|
||||
|
||||
it('should upsert with multiple permission flags', async () => {
|
||||
const { data } = await upsertPermissionFlags({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
roleId: createdRoleId,
|
||||
permissionFlagKeys: [
|
||||
PermissionFlagType.DATA_MODEL,
|
||||
PermissionFlagType.ROLES,
|
||||
PermissionFlagType.VIEWS,
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
expect(data?.upsertPermissionFlags).toHaveLength(3);
|
||||
const flags = data?.upsertPermissionFlags?.map((pf) => pf.flag) ?? [];
|
||||
expect(flags).toContain(PermissionFlagType.DATA_MODEL);
|
||||
expect(flags).toContain(PermissionFlagType.ROLES);
|
||||
expect(flags).toContain(PermissionFlagType.VIEWS);
|
||||
});
|
||||
|
||||
it('should upsert to remove some flags (replace with subset)', async () => {
|
||||
const { data } = await upsertPermissionFlags({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
roleId: createdRoleId,
|
||||
permissionFlagKeys: [PermissionFlagType.DATA_MODEL],
|
||||
},
|
||||
});
|
||||
|
||||
expect(data?.upsertPermissionFlags).toHaveLength(1);
|
||||
expect(data?.upsertPermissionFlags?.[0].flag).toBe(
|
||||
PermissionFlagType.DATA_MODEL,
|
||||
);
|
||||
});
|
||||
|
||||
it('should upsert back to empty', async () => {
|
||||
const { data } = await upsertPermissionFlags({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
roleId: createdRoleId,
|
||||
permissionFlagKeys: [],
|
||||
},
|
||||
});
|
||||
|
||||
expect(data?.upsertPermissionFlags).toEqual([]);
|
||||
});
|
||||
});
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import gql from 'graphql-tag';
|
||||
import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
|
||||
|
||||
import { type UpsertPermissionFlagsInput } from 'src/engine/metadata-modules/permission-flag/dtos/upsert-permission-flag-input';
|
||||
|
||||
export type UpsertPermissionFlagsFactoryInput = UpsertPermissionFlagsInput;
|
||||
|
||||
const DEFAULT_PERMISSION_FLAG_GQL_FIELDS = `
|
||||
id
|
||||
roleId
|
||||
flag
|
||||
`;
|
||||
|
||||
export const upsertPermissionFlagsQueryFactory = ({
|
||||
input,
|
||||
gqlFields = DEFAULT_PERMISSION_FLAG_GQL_FIELDS,
|
||||
}: PerformMetadataQueryParams<UpsertPermissionFlagsFactoryInput>) => ({
|
||||
query: gql`
|
||||
mutation UpsertPermissionFlags($upsertPermissionFlagsInput: UpsertPermissionFlagsInput!) {
|
||||
upsertPermissionFlags(upsertPermissionFlagsInput: $upsertPermissionFlagsInput) {
|
||||
${gqlFields}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
upsertPermissionFlagsInput: input,
|
||||
},
|
||||
});
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import {
|
||||
type UpsertPermissionFlagsFactoryInput,
|
||||
upsertPermissionFlagsQueryFactory,
|
||||
} from 'test/integration/metadata/suites/permission-flag/utils/upsert-permission-flags-query-factory.util';
|
||||
import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util';
|
||||
import { type CommonResponseBody } from 'test/integration/metadata/types/common-response-body.type';
|
||||
import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
|
||||
import { warnIfErrorButNotExpectedToFail } from 'test/integration/metadata/utils/warn-if-error-but-not-expected-to-fail.util';
|
||||
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
|
||||
|
||||
import { type PermissionFlagDTO } from 'src/engine/metadata-modules/permission-flag/dtos/permission-flag.dto';
|
||||
|
||||
export const upsertPermissionFlags = async ({
|
||||
input,
|
||||
gqlFields,
|
||||
expectToFail = false,
|
||||
token,
|
||||
}: PerformMetadataQueryParams<UpsertPermissionFlagsFactoryInput>): CommonResponseBody<{
|
||||
upsertPermissionFlags: PermissionFlagDTO[];
|
||||
}> => {
|
||||
const graphqlOperation = upsertPermissionFlagsQueryFactory({
|
||||
input,
|
||||
gqlFields,
|
||||
});
|
||||
|
||||
const response = await makeMetadataAPIRequest(graphqlOperation, token);
|
||||
|
||||
if (expectToFail === true) {
|
||||
warnIfNoErrorButExpectedToFail({
|
||||
response,
|
||||
errorMessage: 'Permission flags upsert should have failed but did not',
|
||||
});
|
||||
}
|
||||
|
||||
if (expectToFail === false) {
|
||||
warnIfErrorButNotExpectedToFail({
|
||||
response,
|
||||
errorMessage: 'Permission flags upsert has failed but should not',
|
||||
});
|
||||
}
|
||||
|
||||
return { data: response.body.data, errors: response.body.errors };
|
||||
};
|
||||
@@ -21,6 +21,8 @@ export const ALL_METADATA_NAME = {
|
||||
pageLayoutTab: 'pageLayoutTab',
|
||||
commandMenuItem: 'commandMenuItem',
|
||||
navigationMenuItem: 'navigationMenuItem',
|
||||
objectPermission: 'objectPermission',
|
||||
permissionFlag: 'permissionFlag',
|
||||
frontComponent: 'frontComponent',
|
||||
webhook: 'webhook',
|
||||
} as const;
|
||||
|
||||
Reference in New Issue
Block a user