[permissions V2] Create and update a custom role (without granularity) (#11003)
First steps for https://github.com/twentyhq/core-team-issues/issues/595 and https://github.com/twentyhq/core-team-issues/issues/621 Not handling granular permissions through objectPermissions and settingsPermissions next; will come next !
This commit is contained in:
@ -1,10 +1,22 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { ADMIN_ROLE_LABEL } from 'src/engine/metadata-modules/permissions/constants/admin-role-label.constants';
|
||||
import { MEMBER_ROLE_LABEL } from 'src/engine/metadata-modules/permissions/constants/member-role-label.constants';
|
||||
import {
|
||||
PermissionsException,
|
||||
PermissionsExceptionCode,
|
||||
PermissionsExceptionMessage,
|
||||
} from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { CreateRoleInput } from 'src/engine/metadata-modules/role/dtos/createRoleInput.dto';
|
||||
import {
|
||||
UpdateRoleInput,
|
||||
UpdateRolePayload,
|
||||
} from 'src/engine/metadata-modules/role/dtos/updateRoleInput.dto';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { isArgDefinedIfProvidedOrThrow } from 'src/engine/metadata-modules/utils/is-arg-defined-if-provided-or-throw.util';
|
||||
|
||||
export class RoleService {
|
||||
constructor(
|
||||
@ -34,6 +46,64 @@ export class RoleService {
|
||||
});
|
||||
}
|
||||
|
||||
public async createRole({
|
||||
input,
|
||||
workspaceId,
|
||||
}: {
|
||||
input: CreateRoleInput;
|
||||
workspaceId: string;
|
||||
}): Promise<RoleEntity> {
|
||||
await this.validateRoleInput({ input, workspaceId });
|
||||
|
||||
return this.roleRepository.save({
|
||||
label: input.label,
|
||||
description: input.description,
|
||||
icon: input.icon,
|
||||
canUpdateAllSettings: input.canUpdateAllSettings,
|
||||
canReadAllObjectRecords: input.canReadAllObjectRecords,
|
||||
canUpdateAllObjectRecords: input.canUpdateAllObjectRecords,
|
||||
canSoftDeleteAllObjectRecords: input.canSoftDeleteAllObjectRecords,
|
||||
canDestroyAllObjectRecords: input.canDestroyAllObjectRecords,
|
||||
isEditable: true,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
public async updateRole({
|
||||
input,
|
||||
workspaceId,
|
||||
}: {
|
||||
input: UpdateRoleInput;
|
||||
workspaceId: string;
|
||||
}): Promise<RoleEntity> {
|
||||
const existingRole = await this.roleRepository.findOne({
|
||||
where: {
|
||||
id: input.id,
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!isDefined(existingRole)) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.ROLE_NOT_FOUND,
|
||||
PermissionsExceptionCode.ROLE_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
await this.validateRoleInput({
|
||||
input: input.update,
|
||||
workspaceId,
|
||||
roleId: input.id,
|
||||
});
|
||||
|
||||
const updatedRole = await this.roleRepository.save({
|
||||
id: input.id,
|
||||
...input.update,
|
||||
});
|
||||
|
||||
return { ...existingRole, ...updatedRole };
|
||||
}
|
||||
|
||||
public async createAdminRole({
|
||||
workspaceId,
|
||||
}: {
|
||||
@ -91,4 +161,53 @@ export class RoleService {
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
private async validateRoleInput({
|
||||
input,
|
||||
workspaceId,
|
||||
roleId,
|
||||
}: {
|
||||
input: CreateRoleInput | UpdateRolePayload;
|
||||
workspaceId: string;
|
||||
roleId?: string;
|
||||
}): Promise<void> {
|
||||
const keysToValidate = [
|
||||
'label',
|
||||
'canUpdateAllSettings',
|
||||
'canReadAllObjectRecords',
|
||||
'canUpdateAllObjectRecords',
|
||||
'canSoftDeleteAllObjectRecords',
|
||||
'canDestroyAllObjectRecords',
|
||||
];
|
||||
|
||||
for (const key of keysToValidate) {
|
||||
try {
|
||||
isArgDefinedIfProvidedOrThrow({
|
||||
input,
|
||||
key,
|
||||
value: input[key],
|
||||
});
|
||||
} catch (error) {
|
||||
throw new PermissionsException(
|
||||
error.message,
|
||||
PermissionsExceptionCode.INVALID_ARG,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(input.label)) {
|
||||
let workspaceRoles = await this.getWorkspaceRoles(workspaceId);
|
||||
|
||||
if (isDefined(roleId)) {
|
||||
workspaceRoles = workspaceRoles.filter((role) => role.id !== roleId);
|
||||
}
|
||||
|
||||
if (workspaceRoles.some((role) => role.label === input.label)) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.ROLE_LABEL_ALREADY_EXISTS,
|
||||
PermissionsExceptionCode.ROLE_LABEL_ALREADY_EXISTS,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user