Migrate role and role target to v2 (#16009)
# Introduction close https://github.com/twentyhq/core-team-issues/issues/1930 close https://github.com/twentyhq/core-team-issues/issues/1929 Migrating role and roleTarget entities to the v2 core engine, allowing v2 caching leverage and allow migrating agent to v2 that needs role target in prior After agent we should be able to pass twenty standard app totally though workspace migration ## Role target assignation Please note that role target have 3 creation entrypoints: - Agent - User workspace - ApiKey Refactored all 3 of them to pass through a new role-target.service.ts that consumes the v2 under the hood. --------- Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
+58
@@ -0,0 +1,58 @@
|
||||
import { trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatRole } from 'src/engine/metadata-modules/flat-role/types/flat-role.type';
|
||||
import { type CreateRoleInput } from 'src/engine/metadata-modules/role/dtos/create-role-input.dto';
|
||||
|
||||
export const fromCreateRoleInputToFlatRoleToCreate = ({
|
||||
createRoleInput,
|
||||
workspaceId,
|
||||
applicationId,
|
||||
}: {
|
||||
createRoleInput: CreateRoleInput;
|
||||
workspaceId: string;
|
||||
applicationId: string;
|
||||
}): FlatRole => {
|
||||
const now = new Date();
|
||||
|
||||
const {
|
||||
label,
|
||||
description,
|
||||
icon,
|
||||
id: inputId,
|
||||
} = trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
createRoleInput,
|
||||
['description', 'icon', 'id', 'label'],
|
||||
);
|
||||
const id = inputId ?? v4();
|
||||
|
||||
return {
|
||||
id,
|
||||
standardId: null,
|
||||
label,
|
||||
description: description ?? null,
|
||||
icon: icon ?? null,
|
||||
canUpdateAllSettings: createRoleInput.canUpdateAllSettings ?? false,
|
||||
canAccessAllTools: createRoleInput.canAccessAllTools ?? false,
|
||||
canReadAllObjectRecords: createRoleInput.canReadAllObjectRecords ?? false,
|
||||
canUpdateAllObjectRecords:
|
||||
createRoleInput.canUpdateAllObjectRecords ?? false,
|
||||
canSoftDeleteAllObjectRecords:
|
||||
createRoleInput.canSoftDeleteAllObjectRecords ?? false,
|
||||
canDestroyAllObjectRecords:
|
||||
createRoleInput.canDestroyAllObjectRecords ?? false,
|
||||
canBeAssignedToUsers: createRoleInput.canBeAssignedToUsers ?? true,
|
||||
canBeAssignedToAgents: createRoleInput.canBeAssignedToAgents ?? true,
|
||||
canBeAssignedToApiKeys: createRoleInput.canBeAssignedToApiKeys ?? true,
|
||||
isEditable: true,
|
||||
workspaceId,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
universalIdentifier: id,
|
||||
applicationId,
|
||||
roleTargetIds: [],
|
||||
objectPermissionIds: [],
|
||||
permissionFlagIds: [],
|
||||
fieldPermissionIds: [],
|
||||
};
|
||||
};
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { type FlatRole } from 'src/engine/metadata-modules/flat-role/types/flat-role.type';
|
||||
import {
|
||||
PermissionsException,
|
||||
PermissionsExceptionCode,
|
||||
} from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
|
||||
export const fromDeleteRoleInputToFlatRoleOrThrow = ({
|
||||
flatRoleMaps,
|
||||
roleId,
|
||||
}: {
|
||||
flatRoleMaps: FlatEntityMaps<FlatRole>;
|
||||
roleId: string;
|
||||
}): FlatRole => {
|
||||
const existingFlatRole = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: roleId,
|
||||
flatEntityMaps: flatRoleMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(existingFlatRole)) {
|
||||
throw new PermissionsException(
|
||||
'Role not found',
|
||||
PermissionsExceptionCode.ROLE_NOT_FOUND,
|
||||
{
|
||||
userFriendlyMessage: msg`The role you are looking for could not be found. It may have been deleted or you may not have access to it.`,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return existingFlatRole;
|
||||
};
|
||||
+7
-1
@@ -19,7 +19,13 @@ export const fromRoleEntityToFlatRole = (role: RoleEntity): FlatRole => {
|
||||
canBeAssignedToAgents: role.canBeAssignedToAgents,
|
||||
canBeAssignedToApiKeys: role.canBeAssignedToApiKeys,
|
||||
workspaceId: role.workspaceId,
|
||||
universalIdentifier: role.standardId || role.id,
|
||||
createdAt: role.createdAt,
|
||||
updatedAt: role.updatedAt,
|
||||
universalIdentifier: role.universalIdentifier ?? role.standardId ?? role.id,
|
||||
applicationId: role.applicationId ?? null,
|
||||
roleTargetIds: role.roleTargets.map((rt) => rt.id),
|
||||
objectPermissionIds: role.objectPermissions.map((op) => op.id),
|
||||
permissionFlagIds: role.permissionFlags.map((pf) => pf.id),
|
||||
fieldPermissionIds: role.fieldPermissions.map((fp) => fp.id),
|
||||
};
|
||||
};
|
||||
|
||||
+8
@@ -7,10 +7,18 @@ export const fromStandardRoleDefinitionToFlatRole = (
|
||||
standardRoleDefinition: StandardRoleDefinition,
|
||||
workspaceId: string,
|
||||
): FlatRole => {
|
||||
const createdAt = new Date();
|
||||
|
||||
return {
|
||||
...standardRoleDefinition,
|
||||
id: v4(),
|
||||
workspaceId,
|
||||
universalIdentifier: standardRoleDefinition.standardId || v4(),
|
||||
createdAt,
|
||||
updatedAt: createdAt,
|
||||
permissionFlagIds: [],
|
||||
fieldPermissionIds: [],
|
||||
objectPermissionIds: [],
|
||||
roleTargetIds: [],
|
||||
};
|
||||
};
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { type FlatRole } from 'src/engine/metadata-modules/flat-role/types/flat-role.type';
|
||||
import {
|
||||
PermissionsException,
|
||||
PermissionsExceptionCode,
|
||||
} from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { type UpdateRoleInput } from 'src/engine/metadata-modules/role/dtos/update-role-input.dto';
|
||||
|
||||
export const fromUpdateRoleInputToFlatRoleToUpdateOrThrow = ({
|
||||
flatRoleMaps,
|
||||
updateRoleInput,
|
||||
}: {
|
||||
flatRoleMaps: FlatEntityMaps<FlatRole>;
|
||||
updateRoleInput: UpdateRoleInput;
|
||||
}): FlatRole => {
|
||||
const existingFlatRole = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: updateRoleInput.id,
|
||||
flatEntityMaps: flatRoleMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(existingFlatRole)) {
|
||||
throw new PermissionsException(
|
||||
'Role not found',
|
||||
PermissionsExceptionCode.ROLE_NOT_FOUND,
|
||||
{
|
||||
userFriendlyMessage: msg`The role you are looking for could not be found. It may have been deleted or you may not have access to it.`,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...existingFlatRole,
|
||||
...updateRoleInput.update,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user