[permissions] Avoid N+1 on roles (#10041)

This commit is contained in:
Marie
2025-02-06 11:27:11 +01:00
committed by GitHub
parent 049a0118aa
commit 8a660d5d3f
5 changed files with 102 additions and 79 deletions

View File

@ -21,8 +21,9 @@ export class PermissionsService {
}: {
userWorkspaceId: string;
}): Promise<Record<SettingsFeatures, boolean>> {
const [roleOfUserWorkspace] =
await this.userRoleService.getRolesForUserWorkspace(userWorkspaceId);
const [roleOfUserWorkspace] = await this.userRoleService
.getRolesByUserWorkspaces([userWorkspaceId])
.then((roles) => roles?.get(userWorkspaceId) ?? []);
let hasPermissionOnSettingFeature = false;
@ -46,10 +47,11 @@ export class PermissionsService {
userWorkspaceId: string;
setting: SettingsFeatures;
}): Promise<void> {
const [userWorkspaceRole] =
await this.userRoleService.getRolesForUserWorkspace(userWorkspaceId);
const [roleOfUserWorkspace] = await this.userRoleService
.getRolesByUserWorkspaces([userWorkspaceId])
.then((roles) => roles?.get(userWorkspaceId) ?? []);
if (userWorkspaceRole?.canUpdateAllSettings === true) {
if (roleOfUserWorkspace?.canUpdateAllSettings === true) {
return;
}

View File

@ -101,9 +101,12 @@ export class RoleResolver {
});
}
const roles = await this.userRoleService.getRolesForUserWorkspace(
userWorkspace.id,
);
const roles = await this.userRoleService
.getRolesByUserWorkspaces([userWorkspace.id])
.then(
(rolesByUserWorkspaces) =>
rolesByUserWorkspaces?.get(userWorkspace.id) ?? [],
);
return {
...workspaceMember,

View File

@ -60,7 +60,9 @@ export class UserRoleService {
);
}
const [currentRole] = await this.getRolesForUserWorkspace(userWorkspace.id);
const roles = await this.getRolesByUserWorkspaces([userWorkspace.id]);
const currentRole = roles.get(userWorkspace.id)?.[0];
if (currentRole?.id === roleId) {
return;
@ -96,33 +98,42 @@ export class UserRoleService {
});
}
public async getRolesForUserWorkspace(
userWorkspaceId: string,
): Promise<RoleDTO[] | []> {
const userWorkspaceRole = await this.userWorkspaceRoleRepository.findOne({
where: {
userWorkspaceId,
},
});
if (!isDefined(userWorkspaceRole)) {
return [];
public async getRolesByUserWorkspaces(
userWorkspaceIds: string[],
): Promise<Map<string, RoleDTO[]>> {
if (!userWorkspaceIds.length) {
return new Map();
}
const role = await this.roleRepository.findOne({
const allUserWorkspaceRoles = await this.userWorkspaceRoleRepository.find({
where: {
id: userWorkspaceRole.roleId,
userWorkspaceId: In(userWorkspaceIds),
},
relations: {
role: true,
},
});
if (!isDefined(role)) {
throw new PermissionsException(
'Role not found',
PermissionsExceptionCode.ROLE_NOT_FOUND,
if (!allUserWorkspaceRoles.length) {
return new Map();
}
const rolesMap = new Map<string, RoleDTO[]>();
for (const userWorkspaceId of userWorkspaceIds) {
const userWorkspaceRolesOfUserWorkspace = allUserWorkspaceRoles.filter(
(userWorkspaceRole) =>
userWorkspaceRole.userWorkspaceId === userWorkspaceId,
);
const rolesOfUserWorkspace = userWorkspaceRolesOfUserWorkspace
.map((userWorkspaceRole) => userWorkspaceRole.role)
.filter(isDefined);
rolesMap.set(userWorkspaceId, rolesOfUserWorkspace);
}
return [role];
return rolesMap;
}
public async getWorkspaceMembersAssignedToRole(
@ -169,9 +180,13 @@ export class UserRoleService {
userWorkspaceId: string,
workspaceId: string,
): Promise<void> {
const roles = await this.getRolesForUserWorkspace(userWorkspaceId);
const roles = await this.getRolesByUserWorkspaces([userWorkspaceId]);
const adminRole = roles.find((role: RoleDTO) => role.isEditable === false);
const currentRoles = roles.get(userWorkspaceId);
const adminRole = currentRoles?.find(
(role: RoleDTO) => role.isEditable === false,
);
if (isDefined(adminRole)) {
const workspaceMembersWithAdminRole =