Forbid permissions update cross app role retarget (#19982)

closes https://github.com/twentyhq/twenty/issues/19807
This commit is contained in:
Paul Rastoin
2026-04-22 17:39:26 +02:00
committed by GitHub
parent 0696290af4
commit 921a0f01c8
12 changed files with 470 additions and 34 deletions
@@ -145,6 +145,7 @@ export class FlatFieldPermissionValidatorService {
flatObjectMetadataMaps,
flatFieldMetadataMaps,
},
buildOptions,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.fieldPermission
>): FailedFlatEntityValidation<'fieldPermission', 'update'> {
@@ -187,12 +188,21 @@ export class FlatFieldPermissionValidatorService {
message: t`Role not found`,
userFriendlyMessage: msg`Role not found`,
});
} else if (!referencedRole.isEditable) {
validationResult.errors.push({
code: PermissionsExceptionCode.ROLE_NOT_EDITABLE,
message: t`Role is not editable`,
userFriendlyMessage: msg`This role cannot be modified because it is a system role. Only custom roles can be edited.`,
});
} else {
validationResult.errors.push(
...validateRoleBelongsToCallerApplication({
referencedRole,
buildOptions,
}),
);
if (!referencedRole.isEditable) {
validationResult.errors.push({
code: PermissionsExceptionCode.ROLE_NOT_EDITABLE,
message: t`Role is not editable`,
userFriendlyMessage: msg`This role cannot be modified because it is a system role. Only custom roles can be edited.`,
});
}
}
if (isDefined(flatEntityUpdate.objectMetadataUniversalIdentifier)) {
@@ -125,6 +125,7 @@ export class FlatObjectPermissionValidatorService {
flatRoleMaps,
flatObjectMetadataMaps,
},
buildOptions,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.objectPermission
>): FailedFlatEntityValidation<'objectPermission', 'update'> {
@@ -167,12 +168,21 @@ export class FlatObjectPermissionValidatorService {
message: t`Role not found`,
userFriendlyMessage: msg`Role not found`,
});
} else if (!referencedRole.isEditable) {
validationResult.errors.push({
code: PermissionsExceptionCode.ROLE_NOT_EDITABLE,
message: t`Role is not editable`,
userFriendlyMessage: msg`This role cannot be modified because it is a system role. Only custom roles can be edited.`,
});
} else {
validationResult.errors.push(
...validateRoleBelongsToCallerApplication({
referencedRole,
buildOptions,
}),
);
if (!referencedRole.isEditable) {
validationResult.errors.push({
code: PermissionsExceptionCode.ROLE_NOT_EDITABLE,
message: t`Role is not editable`,
userFriendlyMessage: msg`This role cannot be modified because it is a system role. Only custom roles can be edited.`,
});
}
}
if (isDefined(flatEntityUpdate.objectMetadataUniversalIdentifier)) {
@@ -120,6 +120,7 @@ export class FlatPermissionFlagValidatorService {
flatPermissionFlagMaps: optimisticFlatPermissionFlagMaps,
flatRoleMaps,
},
buildOptions,
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.permissionFlag
>): FailedFlatEntityValidation<'permissionFlag', 'update'> {
@@ -162,12 +163,21 @@ export class FlatPermissionFlagValidatorService {
message: t`Role not found`,
userFriendlyMessage: msg`Role not found`,
});
} else if (!referencedRole.isEditable) {
validationResult.errors.push({
code: PermissionsExceptionCode.ROLE_NOT_EDITABLE,
message: t`Role is not editable`,
userFriendlyMessage: msg`This role cannot be modified because it is a system role. Only custom roles can be edited.`,
});
} else {
validationResult.errors.push(
...validateRoleBelongsToCallerApplication({
referencedRole,
buildOptions,
}),
);
if (!referencedRole.isEditable) {
validationResult.errors.push({
code: PermissionsExceptionCode.ROLE_NOT_EDITABLE,
message: t`Role is not editable`,
userFriendlyMessage: msg`This role cannot be modified because it is a system role. Only custom roles can be edited.`,
});
}
}
if (isDefined(flatEntityUpdate.flag)) {
@@ -19,8 +19,8 @@ export const validateRoleBelongsToCallerApplication = ({
return [
{
code: PermissionsExceptionCode.ROLE_BELONGS_TO_ANOTHER_APPLICATION,
message: t`Cannot modify permissions on a role owned by another application`,
userFriendlyMessage: msg`Cannot modify permissions on a role owned by another application.`,
message: t`Cannot target a role owned by another application`,
userFriendlyMessage: msg`Cannot target a role owned by another application.`,
},
];
}