Fix role synchronisation (#19469)
As title solves https://discord.com/channels/1130383047699738754/1491167098398052503
This commit is contained in:
+3
-149
@@ -1,6 +1,6 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { type Manifest, type RoleManifest } from 'twenty-shared/application';
|
||||
import { type Manifest } from 'twenty-shared/application';
|
||||
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@@ -15,9 +15,6 @@ import { computeApplicationManifestAllUniversalFlatEntityMaps } from 'src/engine
|
||||
import { getApplicationSubAllFlatEntityMaps } from 'src/engine/core-modules/application/application-manifest/utils/get-application-sub-all-flat-entity-maps.util';
|
||||
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
|
||||
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
|
||||
import { FieldPermissionService } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.service';
|
||||
import { ObjectPermissionService } from 'src/engine/metadata-modules/object-permission/object-permission.service';
|
||||
import { PermissionFlagService } from 'src/engine/metadata-modules/permission-flag/permission-flag.service';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
@@ -34,9 +31,6 @@ export class ApplicationManifestMigrationService {
|
||||
private readonly workspaceCacheService: WorkspaceCacheService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly objectPermissionService: ObjectPermissionService,
|
||||
private readonly fieldPermissionService: FieldPermissionService,
|
||||
private readonly permissionFlagService: PermissionFlagService,
|
||||
) {}
|
||||
|
||||
async syncMetadataFromManifest({
|
||||
@@ -119,7 +113,7 @@ export class ApplicationManifestMigrationService {
|
||||
`Metadata migration completed for application ${ownerFlatApplication.universalIdentifier}`,
|
||||
);
|
||||
|
||||
await this.syncRolePermissionsAndDefaultRole({
|
||||
await this.syncDefaultRoleAndSettingsCustomTab({
|
||||
manifest,
|
||||
workspaceId,
|
||||
ownerFlatApplication,
|
||||
@@ -131,13 +125,7 @@ export class ApplicationManifestMigrationService {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated should be remove once below issues are resolved:
|
||||
* - [objectPermission](https://github.com/twentyhq/core-team-issues/issues/2223)
|
||||
* - [fieldPermission](https://github.com/twentyhq/core-team-issues/issues/2224)
|
||||
* - [permissionFlag](https://github.com/twentyhq/core-team-issues/issues/2225)
|
||||
*/
|
||||
private async syncRolePermissionsAndDefaultRole({
|
||||
private async syncDefaultRoleAndSettingsCustomTab({
|
||||
manifest,
|
||||
workspaceId,
|
||||
ownerFlatApplication,
|
||||
@@ -148,13 +136,9 @@ export class ApplicationManifestMigrationService {
|
||||
}) {
|
||||
const {
|
||||
flatRoleMaps: refreshedFlatRoleMaps,
|
||||
flatObjectMetadataMaps: refreshedFlatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps: refreshedFlatFieldMetadataMaps,
|
||||
flatFrontComponentMaps: refreshedFlatFrontComponentMaps,
|
||||
} = await this.workspaceCacheService.getOrRecompute(workspaceId, [
|
||||
'flatRoleMaps',
|
||||
'flatObjectMetadataMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
'flatFrontComponentMaps',
|
||||
]);
|
||||
|
||||
@@ -173,14 +157,6 @@ export class ApplicationManifestMigrationService {
|
||||
);
|
||||
}
|
||||
|
||||
await this.syncApplicationRolePermissions({
|
||||
role,
|
||||
workspaceId,
|
||||
roleId: flatRole.id,
|
||||
refreshedFlatObjectMetadataMaps,
|
||||
refreshedFlatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
if (
|
||||
role.universalIdentifier ===
|
||||
manifest.application.defaultRoleUniversalIdentifier
|
||||
@@ -216,126 +192,4 @@ export class ApplicationManifestMigrationService {
|
||||
...(isDefined(defaultRoleId) ? { defaultRoleId } : {}),
|
||||
});
|
||||
}
|
||||
|
||||
private async syncApplicationRolePermissions({
|
||||
role,
|
||||
workspaceId,
|
||||
roleId,
|
||||
refreshedFlatObjectMetadataMaps,
|
||||
refreshedFlatFieldMetadataMaps,
|
||||
}: {
|
||||
role: RoleManifest;
|
||||
workspaceId: string;
|
||||
roleId: string;
|
||||
refreshedFlatObjectMetadataMaps: Awaited<
|
||||
ReturnType<WorkspaceCacheService['getOrRecompute']>
|
||||
>['flatObjectMetadataMaps'];
|
||||
refreshedFlatFieldMetadataMaps: Awaited<
|
||||
ReturnType<WorkspaceCacheService['getOrRecompute']>
|
||||
>['flatFieldMetadataMaps'];
|
||||
}) {
|
||||
if (
|
||||
(role.objectPermissions ?? []).length > 0 ||
|
||||
(role.fieldPermissions ?? []).length > 0
|
||||
) {
|
||||
const formattedObjectPermissions = role.objectPermissions
|
||||
?.map((permission) => {
|
||||
const flatObjectMetadata = findFlatEntityByUniversalIdentifier({
|
||||
flatEntityMaps: refreshedFlatObjectMetadataMaps,
|
||||
universalIdentifier: permission.objectUniversalIdentifier,
|
||||
});
|
||||
|
||||
if (!isDefined(flatObjectMetadata)) {
|
||||
throw new ApplicationException(
|
||||
`Failed to find object with universalIdentifier ${permission.objectUniversalIdentifier}`,
|
||||
ApplicationExceptionCode.OBJECT_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...permission,
|
||||
objectMetadataId: flatObjectMetadata.id,
|
||||
};
|
||||
})
|
||||
.filter(
|
||||
(
|
||||
permission,
|
||||
): permission is typeof permission & { objectMetadataId: string } =>
|
||||
isDefined(permission.objectMetadataId),
|
||||
);
|
||||
|
||||
if (isDefined(formattedObjectPermissions)) {
|
||||
await this.objectPermissionService.upsertObjectPermissions({
|
||||
workspaceId,
|
||||
input: {
|
||||
roleId,
|
||||
objectPermissions: formattedObjectPermissions,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const formattedFieldPermissions = role.fieldPermissions
|
||||
?.map((permission) => {
|
||||
const flatObjectMetadata = findFlatEntityByUniversalIdentifier({
|
||||
flatEntityMaps: refreshedFlatObjectMetadataMaps,
|
||||
universalIdentifier: permission.objectUniversalIdentifier,
|
||||
});
|
||||
|
||||
if (!isDefined(flatObjectMetadata)) {
|
||||
throw new ApplicationException(
|
||||
`Failed to find object with universalIdentifier ${permission.objectUniversalIdentifier}`,
|
||||
ApplicationExceptionCode.OBJECT_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const flatFieldMetadata = findFlatEntityByUniversalIdentifier({
|
||||
flatEntityMaps: refreshedFlatFieldMetadataMaps,
|
||||
universalIdentifier: permission.fieldUniversalIdentifier,
|
||||
});
|
||||
|
||||
if (!isDefined(flatFieldMetadata)) {
|
||||
throw new ApplicationException(
|
||||
`Failed to find field with universalIdentifier ${permission.fieldUniversalIdentifier}`,
|
||||
ApplicationExceptionCode.FIELD_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...permission,
|
||||
objectMetadataId: flatObjectMetadata.id,
|
||||
fieldMetadataId: flatFieldMetadata.id,
|
||||
};
|
||||
})
|
||||
.filter(
|
||||
(
|
||||
permission,
|
||||
): permission is typeof permission & {
|
||||
objectMetadataId: string;
|
||||
fieldMetadataId: string;
|
||||
} =>
|
||||
isDefined(permission.objectMetadataId) &&
|
||||
isDefined(permission.fieldMetadataId),
|
||||
);
|
||||
|
||||
if (isDefined(formattedFieldPermissions)) {
|
||||
await this.fieldPermissionService.upsertFieldPermissions({
|
||||
workspaceId,
|
||||
input: {
|
||||
roleId,
|
||||
fieldPermissions: formattedFieldPermissions,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(role.permissionFlags) && role.permissionFlags.length > 0) {
|
||||
await this.permissionFlagService.upsertPermissionFlags({
|
||||
workspaceId,
|
||||
input: {
|
||||
roleId,
|
||||
permissionFlagKeys: role.permissionFlags,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -7,8 +7,6 @@ import { ApplicationSyncService } from 'src/engine/core-modules/application/appl
|
||||
import { ApplicationVariableEntityModule } from 'src/engine/core-modules/application/application-variable/application-variable.module';
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module';
|
||||
import { ObjectPermissionModule } from 'src/engine/metadata-modules/object-permission/object-permission.module';
|
||||
import { PermissionFlagModule } from 'src/engine/metadata-modules/permission-flag/permission-flag.module';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor';
|
||||
@@ -21,8 +19,6 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
ApplicationVariableEntityModule,
|
||||
FeatureFlagModule,
|
||||
FileStorageModule,
|
||||
ObjectPermissionModule,
|
||||
PermissionFlagModule,
|
||||
PermissionsModule,
|
||||
WorkspaceCacheModule,
|
||||
WorkspaceMigrationModule,
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import { type FieldPermissionManifest } from 'twenty-shared/application';
|
||||
import { type UniversalFlatFieldPermission } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-field-permission.type';
|
||||
|
||||
export const fromFieldPermissionManifestToUniversalFlatFieldPermission = ({
|
||||
fieldPermissionManifest,
|
||||
roleUniversalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
now,
|
||||
}: {
|
||||
fieldPermissionManifest: FieldPermissionManifest;
|
||||
roleUniversalIdentifier: string;
|
||||
applicationUniversalIdentifier: string;
|
||||
now: string;
|
||||
}): UniversalFlatFieldPermission => {
|
||||
return {
|
||||
universalIdentifier: fieldPermissionManifest.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
roleUniversalIdentifier,
|
||||
objectMetadataUniversalIdentifier:
|
||||
fieldPermissionManifest.objectUniversalIdentifier,
|
||||
fieldMetadataUniversalIdentifier:
|
||||
fieldPermissionManifest.fieldUniversalIdentifier,
|
||||
canReadFieldValue: fieldPermissionManifest.canReadFieldValue ?? null,
|
||||
canUpdateFieldValue: fieldPermissionManifest.canUpdateFieldValue ?? null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
};
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import { type ObjectPermissionManifest } from 'twenty-shared/application';
|
||||
import { type UniversalFlatObjectPermission } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-object-permission.type';
|
||||
|
||||
export const fromObjectPermissionManifestToUniversalFlatObjectPermission = ({
|
||||
objectPermissionManifest,
|
||||
roleUniversalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
now,
|
||||
}: {
|
||||
objectPermissionManifest: ObjectPermissionManifest;
|
||||
roleUniversalIdentifier: string;
|
||||
applicationUniversalIdentifier: string;
|
||||
now: string;
|
||||
}): UniversalFlatObjectPermission => {
|
||||
return {
|
||||
universalIdentifier: objectPermissionManifest.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
roleUniversalIdentifier,
|
||||
objectMetadataUniversalIdentifier:
|
||||
objectPermissionManifest.objectUniversalIdentifier,
|
||||
canReadObjectRecords: objectPermissionManifest.canReadObjectRecords,
|
||||
canUpdateObjectRecords: objectPermissionManifest.canUpdateObjectRecords,
|
||||
canSoftDeleteObjectRecords:
|
||||
objectPermissionManifest.canSoftDeleteObjectRecords,
|
||||
canDestroyObjectRecords: objectPermissionManifest.canDestroyObjectRecords,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { type UniversalFlatPermissionFlag } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-permission-flag.type';
|
||||
import { PermissionFlagManifest } from 'twenty-shared/application';
|
||||
|
||||
export const fromPermissionFlagToUniversalFlatPermissionFlag = ({
|
||||
permissionFlag,
|
||||
roleUniversalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
now,
|
||||
}: {
|
||||
permissionFlag: PermissionFlagManifest;
|
||||
roleUniversalIdentifier: string;
|
||||
applicationUniversalIdentifier: string;
|
||||
now: string;
|
||||
}): UniversalFlatPermissionFlag => {
|
||||
return {
|
||||
universalIdentifier: permissionFlag.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
roleUniversalIdentifier,
|
||||
flag: permissionFlag.flag,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
};
|
||||
+44
@@ -4,13 +4,16 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { fromCommandMenuItemManifestToUniversalFlatCommandMenuItem } from 'src/engine/core-modules/application/application-manifest/converters/from-command-menu-item-manifest-to-universal-flat-command-menu-item.util';
|
||||
import { fromFieldManifestToUniversalFlatFieldMetadata } from 'src/engine/core-modules/application/application-manifest/converters/from-field-manifest-to-universal-flat-field-metadata.util';
|
||||
import { fromFieldPermissionManifestToUniversalFlatFieldPermission } from 'src/engine/core-modules/application/application-manifest/converters/from-field-permission-manifest-to-universal-flat-field-permission.util';
|
||||
import { fromFrontComponentManifestToUniversalFlatFrontComponent } from 'src/engine/core-modules/application/application-manifest/converters/from-front-component-manifest-to-universal-flat-front-component.util';
|
||||
import { fromLogicFunctionManifestToUniversalFlatLogicFunction } from 'src/engine/core-modules/application/application-manifest/converters/from-logic-function-manifest-to-universal-flat-logic-function.util';
|
||||
import { fromNavigationMenuItemManifestToUniversalFlatNavigationMenuItem } from 'src/engine/core-modules/application/application-manifest/converters/from-navigation-menu-item-manifest-to-universal-flat-navigation-menu-item.util';
|
||||
import { fromObjectManifestToUniversalFlatObjectMetadata } from 'src/engine/core-modules/application/application-manifest/converters/from-object-manifest-to-universal-flat-object-metadata.util';
|
||||
import { fromObjectPermissionManifestToUniversalFlatObjectPermission } from 'src/engine/core-modules/application/application-manifest/converters/from-object-permission-manifest-to-universal-flat-object-permission.util';
|
||||
import { fromPageLayoutManifestToUniversalFlatPageLayout } from 'src/engine/core-modules/application/application-manifest/converters/from-page-layout-manifest-to-universal-flat-page-layout.util';
|
||||
import { fromPageLayoutTabManifestToUniversalFlatPageLayoutTab } from 'src/engine/core-modules/application/application-manifest/converters/from-page-layout-tab-manifest-to-universal-flat-page-layout-tab.util';
|
||||
import { fromPageLayoutWidgetManifestToUniversalFlatPageLayoutWidget } from 'src/engine/core-modules/application/application-manifest/converters/from-page-layout-widget-manifest-to-universal-flat-page-layout-widget.util';
|
||||
import { fromPermissionFlagToUniversalFlatPermissionFlag } from 'src/engine/core-modules/application/application-manifest/converters/from-permission-flag-to-universal-flat-permission-flag.util';
|
||||
import { fromRoleManifestToUniversalFlatRole } from 'src/engine/core-modules/application/application-manifest/converters/from-role-manifest-to-universal-flat-role.util';
|
||||
import { fromSkillManifestToUniversalFlatSkill } from 'src/engine/core-modules/application/application-manifest/converters/from-skill-manifest-to-universal-flat-skill.util';
|
||||
import { computeSearchVectorUniversalSettingsFromObjectManifest } from 'src/engine/core-modules/application/application-manifest/utils/compute-search-vector-universal-settings-from-object-manifest.util';
|
||||
@@ -144,6 +147,47 @@ export const computeApplicationManifestAllUniversalFlatEntityMaps = ({
|
||||
}),
|
||||
universalFlatEntityMapsToMutate: allUniversalFlatEntityMaps.flatRoleMaps,
|
||||
});
|
||||
for (const objectPermissionManifest of roleManifest.objectPermissions ??
|
||||
[]) {
|
||||
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
|
||||
universalFlatEntity:
|
||||
fromObjectPermissionManifestToUniversalFlatObjectPermission({
|
||||
objectPermissionManifest,
|
||||
roleUniversalIdentifier: roleManifest.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
now,
|
||||
}),
|
||||
universalFlatEntityMapsToMutate:
|
||||
allUniversalFlatEntityMaps.flatObjectPermissionMaps,
|
||||
});
|
||||
}
|
||||
|
||||
for (const fieldPermissionManifest of roleManifest.fieldPermissions ?? []) {
|
||||
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
|
||||
universalFlatEntity:
|
||||
fromFieldPermissionManifestToUniversalFlatFieldPermission({
|
||||
fieldPermissionManifest,
|
||||
roleUniversalIdentifier: roleManifest.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
now,
|
||||
}),
|
||||
universalFlatEntityMapsToMutate:
|
||||
allUniversalFlatEntityMaps.flatFieldPermissionMaps,
|
||||
});
|
||||
}
|
||||
|
||||
for (const permissionFlag of roleManifest.permissionFlags ?? []) {
|
||||
addUniversalFlatEntityToUniversalFlatEntityMapsThroughMutationOrThrow({
|
||||
universalFlatEntity: fromPermissionFlagToUniversalFlatPermissionFlag({
|
||||
permissionFlag,
|
||||
roleUniversalIdentifier: roleManifest.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
now,
|
||||
}),
|
||||
universalFlatEntityMapsToMutate:
|
||||
allUniversalFlatEntityMaps.flatPermissionFlagMaps,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const skillManifest of manifest.skills ?? []) {
|
||||
|
||||
Reference in New Issue
Block a user