[permissions V2] Upsert object and setting permissions (#11119)
Closes https://github.com/twentyhq/core-team-issues/issues/639
This commit is contained in:
@ -9,9 +9,9 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { ObjectPermissionsEntity } from 'src/engine/metadata-modules/object-permissions/object-permissions.entity';
|
||||
import { ObjectPermissionEntity } from 'src/engine/metadata-modules/object-permission/object-permission.entity';
|
||||
import { UserWorkspaceRoleEntity } from 'src/engine/metadata-modules/role/user-workspace-role.entity';
|
||||
import { SettingsPermissionsEntity } from 'src/engine/metadata-modules/settings-permissions/settings-permissions.entity';
|
||||
import { SettingPermissionEntity } from 'src/engine/metadata-modules/setting-permission/setting-permission.entity';
|
||||
|
||||
@Entity('role')
|
||||
@Unique('IndexOnRoleUnique', ['label', 'workspaceId'])
|
||||
@ -62,15 +62,14 @@ export class RoleEntity {
|
||||
userWorkspaceRoles: Relation<UserWorkspaceRoleEntity[]>;
|
||||
|
||||
@OneToMany(
|
||||
() => ObjectPermissionsEntity,
|
||||
(objectPermissions: ObjectPermissionsEntity) => objectPermissions.role,
|
||||
() => ObjectPermissionEntity,
|
||||
(objectPermission: ObjectPermissionEntity) => objectPermission.role,
|
||||
)
|
||||
objectPermissions: Relation<ObjectPermissionsEntity[]>;
|
||||
objectPermissions: Relation<ObjectPermissionEntity[]>;
|
||||
|
||||
@OneToMany(
|
||||
() => SettingsPermissionsEntity,
|
||||
(settingsPermissions: SettingsPermissionsEntity) =>
|
||||
settingsPermissions.role,
|
||||
() => SettingPermissionEntity,
|
||||
(settingPermission: SettingPermissionEntity) => settingPermission.role,
|
||||
)
|
||||
settingsPermissions: Relation<SettingsPermissionsEntity[]>;
|
||||
settingPermissions: Relation<SettingPermissionEntity[]>;
|
||||
}
|
||||
|
||||
@ -4,11 +4,13 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module';
|
||||
import { ObjectPermissionModule } from 'src/engine/metadata-modules/object-permission/object-permission.module';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RoleResolver } from 'src/engine/metadata-modules/role/role.resolver';
|
||||
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
|
||||
import { UserWorkspaceRoleEntity } from 'src/engine/metadata-modules/role/user-workspace-role.entity';
|
||||
import { SettingPermissionModule } from 'src/engine/metadata-modules/setting-permission/setting-permission.module';
|
||||
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
|
||||
|
||||
@Module({
|
||||
@ -19,6 +21,8 @@ import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.
|
||||
PermissionsModule,
|
||||
UserWorkspaceModule,
|
||||
FeatureFlagModule,
|
||||
ObjectPermissionModule,
|
||||
SettingPermissionModule,
|
||||
],
|
||||
providers: [RoleService, RoleResolver],
|
||||
exports: [RoleService],
|
||||
|
||||
@ -16,22 +16,28 @@ import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthWorkspaceMemberId } from 'src/engine/decorators/auth/auth-workspace-member-id.decorator';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.guard';
|
||||
import { SettingsPermissions } from 'src/engine/metadata-modules/permissions/constants/settings-permissions.constants';
|
||||
import { ObjectPermissionDTO } from 'src/engine/metadata-modules/object-permission/dtos/object-permission.dto';
|
||||
import { UpsertObjectPermissionInput } from 'src/engine/metadata-modules/object-permission/dtos/upsert-object-permission-input';
|
||||
import { ObjectPermissionService } from 'src/engine/metadata-modules/object-permission/object-permission.service';
|
||||
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
|
||||
import {
|
||||
PermissionsException,
|
||||
PermissionsExceptionCode,
|
||||
PermissionsExceptionMessage,
|
||||
} from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter';
|
||||
import { CreateRoleInput } from 'src/engine/metadata-modules/role/dtos/createRoleInput.dto';
|
||||
import { CreateRoleInput } from 'src/engine/metadata-modules/role/dtos/create-role-input.dto';
|
||||
import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto';
|
||||
import { UpdateRoleInput } from 'src/engine/metadata-modules/role/dtos/updateRoleInput.dto';
|
||||
import { UpdateRoleInput } from 'src/engine/metadata-modules/role/dtos/update-role-input.dto';
|
||||
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
|
||||
import { SettingPermissionDTO } from 'src/engine/metadata-modules/setting-permission/dtos/setting-permission.dto';
|
||||
import { UpsertSettingPermissionInput } from 'src/engine/metadata-modules/setting-permission/dtos/upsert-setting-permission-input';
|
||||
import { SettingPermissionService } from 'src/engine/metadata-modules/setting-permission/setting-permission.service';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||
|
||||
@Resolver(() => RoleDTO)
|
||||
@UseGuards(SettingsPermissionsGuard(SettingsPermissions.ROLES))
|
||||
@UseGuards(SettingsPermissionsGuard(SettingPermissionType.ROLES))
|
||||
@UseFilters(PermissionsGraphqlApiExceptionFilter)
|
||||
export class RoleResolver {
|
||||
constructor(
|
||||
@ -39,6 +45,8 @@ export class RoleResolver {
|
||||
private readonly roleService: RoleService,
|
||||
private readonly userWorkspaceService: UserWorkspaceService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
private readonly objectPermissionService: ObjectPermissionService,
|
||||
private readonly settingPermissionService: SettingPermissionService,
|
||||
) {}
|
||||
|
||||
@Query(() => [RoleDTO])
|
||||
@ -101,18 +109,7 @@ export class RoleResolver {
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
@Args('createRoleInput') createRoleInput: CreateRoleInput,
|
||||
): Promise<RoleDTO> {
|
||||
const isPermissionsV2Enabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IsPermissionsV2Enabled,
|
||||
workspace.id,
|
||||
);
|
||||
|
||||
if (!isPermissionsV2Enabled) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.PERMISSIONS_V2_NOT_ENABLED,
|
||||
PermissionsExceptionCode.PERMISSIONS_V2_NOT_ENABLED,
|
||||
);
|
||||
}
|
||||
await this.validatePermissionsV2EnabledOrThrow(workspace);
|
||||
|
||||
return this.roleService.createRole({
|
||||
workspaceId: workspace.id,
|
||||
@ -125,18 +122,11 @@ export class RoleResolver {
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
@Args('updateRoleInput') updateRoleInput: UpdateRoleInput,
|
||||
): Promise<RoleDTO> {
|
||||
const isPermissionsV2Enabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IsPermissionsV2Enabled,
|
||||
workspace.id,
|
||||
);
|
||||
|
||||
if (!isPermissionsV2Enabled) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.PERMISSIONS_V2_NOT_ENABLED,
|
||||
PermissionsExceptionCode.PERMISSIONS_V2_NOT_ENABLED,
|
||||
);
|
||||
}
|
||||
await this.validatePermissionsV2EnabledOrThrow(workspace);
|
||||
await this.validateRoleIsEditableOrThrow({
|
||||
roleId: updateRoleInput.id,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
return this.roleService.updateRole({
|
||||
input: updateRoleInput,
|
||||
@ -144,6 +134,42 @@ export class RoleResolver {
|
||||
});
|
||||
}
|
||||
|
||||
@Mutation(() => ObjectPermissionDTO)
|
||||
async upsertOneObjectPermission(
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
@Args('upsertObjectPermissionInput')
|
||||
upsertObjectPermissionInput: UpsertObjectPermissionInput,
|
||||
) {
|
||||
await this.validatePermissionsV2EnabledOrThrow(workspace);
|
||||
await this.validateRoleIsEditableOrThrow({
|
||||
roleId: upsertObjectPermissionInput.roleId,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
return this.objectPermissionService.upsertObjectPermission({
|
||||
workspaceId: workspace.id,
|
||||
input: upsertObjectPermissionInput,
|
||||
});
|
||||
}
|
||||
|
||||
@Mutation(() => SettingPermissionDTO)
|
||||
async upsertOneSettingPermission(
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
@Args('upsertSettingPermissionInput')
|
||||
upsertSettingPermissionInput: UpsertSettingPermissionInput,
|
||||
) {
|
||||
await this.validatePermissionsV2EnabledOrThrow(workspace);
|
||||
await this.validateRoleIsEditableOrThrow({
|
||||
roleId: upsertSettingPermissionInput.roleId,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
return this.settingPermissionService.upsertSettingPermission({
|
||||
workspaceId: workspace.id,
|
||||
input: upsertSettingPermissionInput,
|
||||
});
|
||||
}
|
||||
|
||||
@ResolveField('workspaceMembers', () => [WorkspaceMember])
|
||||
async getWorkspaceMembersAssignedToRole(
|
||||
@Parent() role: RoleDTO,
|
||||
@ -154,4 +180,36 @@ export class RoleResolver {
|
||||
workspace.id,
|
||||
);
|
||||
}
|
||||
|
||||
private async validatePermissionsV2EnabledOrThrow(workspace: Workspace) {
|
||||
const isPermissionsV2Enabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IsPermissionsV2Enabled,
|
||||
workspace.id,
|
||||
);
|
||||
|
||||
if (!isPermissionsV2Enabled) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.PERMISSIONS_V2_NOT_ENABLED,
|
||||
PermissionsExceptionCode.PERMISSIONS_V2_NOT_ENABLED,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async validateRoleIsEditableOrThrow({
|
||||
roleId,
|
||||
workspaceId,
|
||||
}: {
|
||||
roleId: string;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
const role = await this.roleService.getRoleById(roleId, workspaceId);
|
||||
|
||||
if (!role?.isEditable) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.ROLE_NOT_EDITABLE,
|
||||
PermissionsExceptionCode.ROLE_NOT_EDITABLE,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
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';
|
||||
@ -10,11 +10,11 @@ import {
|
||||
PermissionsExceptionCode,
|
||||
PermissionsExceptionMessage,
|
||||
} from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { CreateRoleInput } from 'src/engine/metadata-modules/role/dtos/createRoleInput.dto';
|
||||
import { CreateRoleInput } from 'src/engine/metadata-modules/role/dtos/create-role-input.dto';
|
||||
import {
|
||||
UpdateRoleInput,
|
||||
UpdateRolePayload,
|
||||
} from 'src/engine/metadata-modules/role/dtos/updateRoleInput.dto';
|
||||
} from 'src/engine/metadata-modules/role/dtos/update-role-input.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';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user