[permissions] Improve performances using a cache for userWorkspaces roles (#11587)
In this PR we are
- introducing a cached map `{ userworkspaceId: roleId } `to reduce calls
to get a userWorkspace's role (we were having N+1 around that with
combinedFindMany queries and generally having a lot of avoidable
queries)
- using the roles permissions cache (`{ roleId: { objectNameSingular:
{ canRead: bool, canUpdate: bool, ...} } `) in Permissions V1's
userHasObjectPermission, in order to 1) improve performances to avoid
calls to get roles 2) start using our permissions cache
This commit is contained in:
@ -13,7 +13,7 @@ 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';
|
||||
import { WorkspaceRolesPermissionsCacheModule } from 'src/engine/metadata-modules/workspace-roles-permissions-cache/workspace-roles-permissions-cache.module';
|
||||
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -25,7 +25,7 @@ import { WorkspaceRolesPermissionsCacheModule } from 'src/engine/metadata-module
|
||||
FeatureFlagModule,
|
||||
ObjectPermissionModule,
|
||||
SettingPermissionModule,
|
||||
WorkspaceRolesPermissionsCacheModule,
|
||||
WorkspacePermissionsCacheModule,
|
||||
],
|
||||
providers: [RoleService, RoleResolver],
|
||||
exports: [RoleService],
|
||||
|
||||
@ -20,7 +20,7 @@ import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { UserWorkspaceRoleEntity } from 'src/engine/metadata-modules/role/user-workspace-role.entity';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { isArgDefinedIfProvidedOrThrow } from 'src/engine/metadata-modules/utils/is-arg-defined-if-provided-or-throw.util';
|
||||
import { WorkspaceRolesPermissionsCacheService } from 'src/engine/metadata-modules/workspace-roles-permissions-cache/workspace-roles-permissions-cache.service';
|
||||
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
|
||||
|
||||
export class RoleService {
|
||||
constructor(
|
||||
@ -31,7 +31,7 @@ export class RoleService {
|
||||
@InjectRepository(UserWorkspaceRoleEntity, 'metadata')
|
||||
private readonly userWorkspaceRoleRepository: Repository<UserWorkspaceRoleEntity>,
|
||||
private readonly userRoleService: UserRoleService,
|
||||
private readonly workspaceRolesPermissionsCacheService: WorkspaceRolesPermissionsCacheService,
|
||||
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
|
||||
) {}
|
||||
|
||||
public async getWorkspaceRoles(workspaceId: string): Promise<RoleEntity[]> {
|
||||
@ -69,7 +69,7 @@ export class RoleService {
|
||||
}): Promise<RoleEntity> {
|
||||
await this.validateRoleInput({ input, workspaceId });
|
||||
|
||||
const role = this.roleRepository.save({
|
||||
const role = await this.roleRepository.save({
|
||||
label: input.label,
|
||||
description: input.description,
|
||||
icon: input.icon,
|
||||
@ -82,11 +82,10 @@ export class RoleService {
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.workspaceRolesPermissionsCacheService.recomputeRolesPermissionsCache(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
await this.workspacePermissionsCacheService.recomputeRolesPermissionsCache({
|
||||
workspaceId,
|
||||
roleIds: [role.id],
|
||||
});
|
||||
|
||||
return role;
|
||||
}
|
||||
@ -128,11 +127,10 @@ export class RoleService {
|
||||
...input.update,
|
||||
});
|
||||
|
||||
await this.workspaceRolesPermissionsCacheService.recomputeRolesPermissionsCache(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
await this.workspacePermissionsCacheService.recomputeRolesPermissionsCache({
|
||||
workspaceId,
|
||||
roleIds: [input.id],
|
||||
});
|
||||
|
||||
return { ...existingRole, ...updatedRole };
|
||||
}
|
||||
@ -196,11 +194,9 @@ export class RoleService {
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.workspaceRolesPermissionsCacheService.recomputeRolesPermissionsCache(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
await this.workspacePermissionsCacheService.recomputeRolesPermissionsCache({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
return roleId;
|
||||
}
|
||||
@ -317,10 +313,11 @@ export class RoleService {
|
||||
workspaceId: string;
|
||||
defaultRoleId: string;
|
||||
}): Promise<void> {
|
||||
const userWorkspaceIds = await this.getUserWorkspaceIdsForRole(
|
||||
roleId,
|
||||
workspaceId,
|
||||
);
|
||||
const userWorkspaceIds =
|
||||
await this.userRoleService.getUserWorkspaceIdsAssignedToRole(
|
||||
roleId,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
await Promise.all(
|
||||
userWorkspaceIds.map((userWorkspaceId) =>
|
||||
@ -333,24 +330,6 @@ export class RoleService {
|
||||
);
|
||||
}
|
||||
|
||||
private async getUserWorkspaceIdsForRole(
|
||||
roleId: string,
|
||||
workspaceId: string,
|
||||
): Promise<string[]> {
|
||||
return this.userWorkspaceRoleRepository
|
||||
.find({
|
||||
where: {
|
||||
roleId: roleId,
|
||||
workspaceId,
|
||||
},
|
||||
})
|
||||
.then((userWorkspaceRoles) =>
|
||||
userWorkspaceRoles.map(
|
||||
(userWorkspaceRole) => userWorkspaceRole.userWorkspaceId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private async getRole(
|
||||
roleId: string,
|
||||
workspaceId: string,
|
||||
|
||||
Reference in New Issue
Block a user