Fix seeding perf + batch role targets creation (#16337)

This commit is contained in:
Weiko
2025-12-04 20:29:48 +01:00
committed by GitHub
parent e653385485
commit 1991ee850e
11 changed files with 156 additions and 110 deletions
@@ -29,31 +29,38 @@ export class UserRoleService {
private readonly workspaceCacheService: WorkspaceCacheService,
) {}
public async assignRoleToUserWorkspace({
public async assignRoleToManyUserWorkspace({
workspaceId,
userWorkspaceId,
userWorkspaceIds,
roleId,
}: {
workspaceId: string;
userWorkspaceId: string;
userWorkspaceIds: string[];
roleId: string;
}): Promise<void> {
const validationResult = await this.validateAssignRoleInput({
userWorkspaceId,
workspaceId,
roleId,
});
if (validationResult?.roleToAssignIsSameAsCurrentRole) {
if (userWorkspaceIds.length === 0) {
return;
}
await this.roleTargetService.create({
createRoleTargetInput: {
const userWorkspaceIdsToAssign =
await this.validateAssignRoleInputsAndGetUserWorkspaceIdsToAssign({
userWorkspaceIds,
workspaceId,
roleId,
targetId: userWorkspaceId,
targetMetadataForeignKey: 'userWorkspaceId',
},
});
if (userWorkspaceIdsToAssign.length === 0) {
return;
}
await this.roleTargetService.createMany({
createRoleTargetInputs: userWorkspaceIdsToAssign.map(
(userWorkspaceId) => ({
roleId,
targetId: userWorkspaceId,
targetMetadataForeignKey: 'userWorkspaceId' as const,
}),
),
workspaceId,
});
}
@@ -208,57 +215,72 @@ export class UserRoleService {
}
}
private async validateAssignRoleInput({
userWorkspaceId,
private async validateAssignRoleInputsAndGetUserWorkspaceIdsToAssign({
userWorkspaceIds,
workspaceId,
roleId,
}: {
userWorkspaceId: string;
userWorkspaceIds: string[];
workspaceId: string;
roleId: string;
}) {
const userWorkspace = await this.userWorkspaceRepository.findOne({
}): Promise<string[]> {
const userWorkspaces = await this.userWorkspaceRepository.find({
where: {
id: userWorkspaceId,
id: In(userWorkspaceIds),
},
});
if (!isDefined(userWorkspace)) {
const foundUserWorkspaceIds = new Set(
userWorkspaces.map((userWorkspace) => userWorkspace.id),
);
const missingUserWorkspaceIds = userWorkspaceIds.filter(
(id) => !foundUserWorkspaceIds.has(id),
);
if (missingUserWorkspaceIds.length > 0) {
throw new PermissionsException(
'User workspace not found',
`User workspaces not found: ${missingUserWorkspaceIds.join(', ')}`,
PermissionsExceptionCode.USER_WORKSPACE_NOT_FOUND,
{
userFriendlyMessage: msg`Your workspace membership could not be found. You may no longer have access to this workspace.`,
userFriendlyMessage: msg`Some workspace memberships could not be found. They may no longer have access to this workspace.`,
},
);
}
const roles = await this.getRolesByUserWorkspaces({
userWorkspaceIds: [userWorkspace.id],
const rolesByUserWorkspaces = await this.getRolesByUserWorkspaces({
userWorkspaceIds,
workspaceId,
});
const currentRole = roles.get(userWorkspace.id)?.[0];
const userWorkspaceIdsToAssign: string[] = [];
let adminRoleIdToValidate: string | undefined;
if (currentRole?.id === roleId) {
return {
roleToAssignIsSameAsCurrentRole: true,
};
}
for (const userWorkspaceId of userWorkspaceIds) {
const currentRole = rolesByUserWorkspaces.get(userWorkspaceId)?.[0];
if (
!(
if (currentRole?.id === roleId) {
continue;
}
if (
isDefined(currentRole) &&
currentRole.standardId === ADMIN_ROLE.standardId
)
) {
return;
) {
adminRoleIdToValidate = currentRole.id;
}
userWorkspaceIdsToAssign.push(userWorkspaceId);
}
await this.validateMoreThanOneWorkspaceMemberHasAdminRoleOrThrow({
workspaceId,
adminRoleId: currentRole.id,
});
if (isDefined(adminRoleIdToValidate)) {
await this.validateMoreThanOneWorkspaceMemberHasAdminRoleOrThrow({
workspaceId,
adminRoleId: adminRoleIdToValidate,
});
}
return userWorkspaceIdsToAssign;
}
private async validateMoreThanOneWorkspaceMemberHasAdminRoleOrThrow({