[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:
@ -12,6 +12,7 @@ import {
|
||||
} from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { UserWorkspaceRoleEntity } from 'src/engine/metadata-modules/role/user-workspace-role.entity';
|
||||
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||
|
||||
@ -24,6 +25,7 @@ export class UserRoleService {
|
||||
@InjectRepository(UserWorkspace, 'core')
|
||||
private readonly userWorkspaceRepository: Repository<UserWorkspace>,
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
|
||||
) {}
|
||||
|
||||
public async assignRoleToUserWorkspace({
|
||||
@ -56,6 +58,12 @@ export class UserRoleService {
|
||||
workspaceId,
|
||||
id: Not(newUserWorkspaceRole.id),
|
||||
});
|
||||
|
||||
await this.workspacePermissionsCacheService.recomputeUserWorkspaceRoleMapCache(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public async getRoleIdForUserWorkspace({
|
||||
@ -69,11 +77,14 @@ export class UserRoleService {
|
||||
return;
|
||||
}
|
||||
|
||||
const userWorkspaceRole = await this.userWorkspaceRoleRepository.findOne({
|
||||
where: { userWorkspaceId, workspaceId },
|
||||
});
|
||||
const userWorkspaceRoleMap =
|
||||
await this.workspacePermissionsCacheService.getUserWorkspaceRoleMapFromCache(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
return userWorkspaceRole?.roleId;
|
||||
return userWorkspaceRoleMap.data[userWorkspaceId];
|
||||
}
|
||||
|
||||
public async getRolesByUserWorkspaces({
|
||||
@ -125,21 +136,13 @@ export class UserRoleService {
|
||||
roleId: string,
|
||||
workspaceId: string,
|
||||
): Promise<WorkspaceMemberWorkspaceEntity[]> {
|
||||
const userWorkspaceRoles = await this.userWorkspaceRoleRepository.find({
|
||||
where: {
|
||||
roleId,
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
const userWorkspaceIdsWithRole =
|
||||
await this.getUserWorkspaceIdsAssignedToRole(roleId, workspaceId);
|
||||
|
||||
const userIds = await this.userWorkspaceRepository
|
||||
.find({
|
||||
where: {
|
||||
id: In(
|
||||
userWorkspaceRoles.map(
|
||||
(userWorkspaceRole) => userWorkspaceRole.userWorkspaceId,
|
||||
),
|
||||
),
|
||||
id: In(userWorkspaceIdsWithRole),
|
||||
},
|
||||
})
|
||||
.then((userWorkspaces) =>
|
||||
@ -161,6 +164,22 @@ export class UserRoleService {
|
||||
return workspaceMembers;
|
||||
}
|
||||
|
||||
public async getUserWorkspaceIdsAssignedToRole(
|
||||
roleId: string,
|
||||
workspaceId: string,
|
||||
): Promise<string[]> {
|
||||
const userWorkspaceRoleMap =
|
||||
await this.workspacePermissionsCacheService.getUserWorkspaceRoleMapFromCache(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
return Object.entries(userWorkspaceRoleMap.data)
|
||||
.filter(([_, roleIdFromMap]) => roleIdFromMap === roleId)
|
||||
.map(([userWorkspaceId]) => userWorkspaceId);
|
||||
}
|
||||
|
||||
public async validateUserWorkspaceIsNotUniqueAdminOrThrow({
|
||||
userWorkspaceId,
|
||||
workspaceId,
|
||||
|
||||
Reference in New Issue
Block a user