Forbid other app role extension (#19783)
# Introduction Even though this would not possible through API at the moment, from neither API metadata or manifest ( as manifest `permissionsFlag` declarations etc are done from within a declared role ) Prevent any app to create permissions entities over another app role from the validation engine itself ## `isEditable` We might wanna deprecate this column at some point from the entity it self as now the grain would rather be `what app owns that role ?` --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
co-authored by
Charles Bochet
parent
a93f23a150
commit
bb464b2ffb
+3
@@ -49,6 +49,7 @@ export enum PermissionsExceptionCode {
|
||||
ROLE_MUST_HAVE_AT_LEAST_ONE_TARGET = 'ROLE_MUST_HAVE_AT_LEAST_ONE_TARGET',
|
||||
ROLE_CANNOT_BE_ASSIGNED_TO_USERS = 'ROLE_CANNOT_BE_ASSIGNED_TO_USERS',
|
||||
APPLICATION_ROLE_NOT_FOUND = 'APPLICATION_ROLE_NOT_FOUND',
|
||||
ROLE_BELONGS_TO_ANOTHER_APPLICATION = 'ROLE_BELONGS_TO_ANOTHER_APPLICATION',
|
||||
}
|
||||
|
||||
const getPermissionsExceptionUserFriendlyMessage = (
|
||||
@@ -143,6 +144,8 @@ const getPermissionsExceptionUserFriendlyMessage = (
|
||||
return msg`This role cannot be assigned to users.`;
|
||||
case PermissionsExceptionCode.APPLICATION_ROLE_NOT_FOUND:
|
||||
return msg`No role assigned to the application.`;
|
||||
case PermissionsExceptionCode.ROLE_BELONGS_TO_ANOTHER_APPLICATION:
|
||||
return msg`Cannot modify permissions on a role owned by another application.`;
|
||||
default:
|
||||
assertUnreachable(code);
|
||||
}
|
||||
|
||||
+1
@@ -71,6 +71,7 @@ export const permissionGraphqlApiExceptionHandler = (
|
||||
case PermissionsExceptionCode.COMPOSITE_TYPE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.USER_WORKSPACE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.APPLICATION_ROLE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.ROLE_BELONGS_TO_ANOTHER_APPLICATION:
|
||||
throw error;
|
||||
default: {
|
||||
return assertUnreachable(error.code);
|
||||
|
||||
+17
-6
@@ -10,6 +10,7 @@ import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspa
|
||||
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';
|
||||
import { validateRoleBelongsToCallerApplication } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-role-belongs-to-caller-application.util';
|
||||
|
||||
@Injectable()
|
||||
export class FlatFieldPermissionValidatorService {
|
||||
@@ -21,6 +22,7 @@ export class FlatFieldPermissionValidatorService {
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
},
|
||||
buildOptions,
|
||||
}: UniversalFlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.fieldPermission
|
||||
>): FailedFlatEntityValidation<'fieldPermission', 'create'> {
|
||||
@@ -63,12 +65,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.`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const referencedObjectMetadata = findFlatEntityByUniversalIdentifier({
|
||||
|
||||
+17
-6
@@ -10,6 +10,7 @@ import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspa
|
||||
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';
|
||||
import { validateRoleBelongsToCallerApplication } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-role-belongs-to-caller-application.util';
|
||||
|
||||
@Injectable()
|
||||
export class FlatObjectPermissionValidatorService {
|
||||
@@ -20,6 +21,7 @@ export class FlatObjectPermissionValidatorService {
|
||||
flatRoleMaps,
|
||||
flatObjectMetadataMaps,
|
||||
},
|
||||
buildOptions,
|
||||
}: UniversalFlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.objectPermission
|
||||
>): FailedFlatEntityValidation<'objectPermission', 'create'> {
|
||||
@@ -60,12 +62,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.`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const referencedObjectMetadata = findFlatEntityByUniversalIdentifier({
|
||||
|
||||
+17
-6
@@ -11,6 +11,7 @@ import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspa
|
||||
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';
|
||||
import { validateRoleBelongsToCallerApplication } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/utils/validate-role-belongs-to-caller-application.util';
|
||||
|
||||
@Injectable()
|
||||
export class FlatPermissionFlagValidatorService {
|
||||
@@ -20,6 +21,7 @@ export class FlatPermissionFlagValidatorService {
|
||||
flatPermissionFlagMaps: optimisticFlatPermissionFlagMaps,
|
||||
flatRoleMaps,
|
||||
},
|
||||
buildOptions,
|
||||
}: UniversalFlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.permissionFlag
|
||||
>): FailedFlatEntityValidation<'permissionFlag', 'create'> {
|
||||
@@ -57,12 +59,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.`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const isValidFlag =
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
|
||||
import { PermissionsExceptionCode } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { type UniversalFlatRole } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-role.type';
|
||||
import { type FlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
|
||||
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
|
||||
|
||||
export const validateRoleBelongsToCallerApplication = ({
|
||||
referencedRole,
|
||||
buildOptions,
|
||||
}: {
|
||||
referencedRole: UniversalFlatRole;
|
||||
buildOptions: WorkspaceMigrationBuilderOptions;
|
||||
}): FlatEntityValidationError[] => {
|
||||
if (
|
||||
referencedRole.applicationUniversalIdentifier !==
|
||||
buildOptions.applicationUniversalIdentifier
|
||||
) {
|
||||
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.`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
Reference in New Issue
Block a user