diff --git a/components/server/src/authorization/authorizer.ts b/components/server/src/authorization/authorizer.ts index d57597cc28d60a..c6f2b041121fb2 100644 --- a/components/server/src/authorization/authorizer.ts +++ b/components/server/src/authorization/authorizer.ts @@ -416,21 +416,54 @@ export class Authorizer { if (!(await isFgaWritesEnabled(userID))) { return; } - return this.bulkAddWorkspaceToOrg([{ orgID, userID, workspaceID, shared }]); - } - - async bulkAddWorkspaceToOrg( - ids: { orgID: string; userID: string; workspaceID: string; shared: boolean }[], - ): Promise { const rels: v1.RelationshipUpdate[] = []; - for (const { orgID, userID, workspaceID, shared } of ids) { - rels.push(set(rel.workspace(workspaceID).org.organization(orgID))); - rels.push(set(rel.workspace(workspaceID).owner.user(userID))); - if (shared) { - rels.push(set(rel.workspace(workspaceID).shared.anyUser)); - } + rels.push(set(rel.workspace(workspaceID).org.organization(orgID))); + rels.push(set(rel.workspace(workspaceID).owner.user(userID))); + if (shared) { + rels.push(set(rel.workspace(workspaceID).shared.anyUser)); } await this.authorizer.writeRelationships(...rels); + + //TODO(se) remove this double checking once we're confident that the above works + // check if the relationships were written + try { + const wsToOrgRel = this.find(rel.workspace(workspaceID).org.organization(orgID)); + const wsToOwnerRel = this.find(rel.workspace(workspaceID).owner.user(userID)); + const wsSharedRel = shared ? this.find(rel.workspace(workspaceID).shared.anyUser) : Promise.resolve(true); + if (!(await wsToOrgRel)) { + log.error("Failed to write workspace to org relationship", { + orgID, + userID, + workspaceID, + + shared, + }); + } + if (!(await wsToOwnerRel)) { + log.error("Failed to write workspace to owner relationship", { + orgID, + userID, + workspaceID, + shared, + }); + } + if (!(await wsSharedRel)) { + log.error("Failed to write workspace shared relationship", { + orgID, + userID, + workspaceID, + shared, + }); + } + } catch (error) { + log.error("Failed to check workspace relationships", { + orgID, + userID, + workspaceID, + shared, + error, + }); + } } async removeWorkspaceFromOrg(orgID: string, userID: string, workspaceID: string): Promise { diff --git a/components/server/src/authorization/relationship-updater.spec.db.ts b/components/server/src/authorization/relationship-updater.spec.db.ts index b45c6c28435151..9224c45e57d7cc 100644 --- a/components/server/src/authorization/relationship-updater.spec.db.ts +++ b/components/server/src/authorization/relationship-updater.spec.db.ts @@ -286,7 +286,7 @@ describe("RelationshipUpdater", async () => { it("should create relationships for all user workspaces", async function () { const user = await userDB.newUser(); const org = await orgDB.createTeam(user.id, "MyOrg"); - const totalWorkspaces = 20; + const totalWorkspaces = 50; const expectedWorkspaces: Workspace[] = []; for (let i = 0; i < totalWorkspaces; i++) { const workspace = await workspaceDB.store({ diff --git a/components/server/src/authorization/relationship-updater.ts b/components/server/src/authorization/relationship-updater.ts index 11f70b2732ada6..bbb311a30e4d55 100644 --- a/components/server/src/authorization/relationship-updater.ts +++ b/components/server/src/authorization/relationship-updater.ts @@ -17,7 +17,7 @@ import { rel } from "./definitions"; @injectable() export class RelationshipUpdater { - public static readonly version = 2; + public static readonly version = 3; constructor( @inject(UserDB) private readonly userDB: UserDB, @@ -155,14 +155,18 @@ export class RelationshipUpdater { limit: 500, // The largest amount of workspaces is 189 today (2023-08-24) }); - await this.authorizer.bulkAddWorkspaceToOrg( - workspaces.map((ws) => ({ - orgID: ws.workspace.organizationId, - userID: ws.workspace.ownerId, - workspaceID: ws.workspace.id, - shared: !!ws.workspace.shareable, - })), - ); + for (const ws of workspaces) { + await this.authorizer + .addWorkspaceToOrg( + ws.workspace.organizationId, + ws.workspace.ownerId, + ws.workspace.id, + !!ws.workspace.shareable, + ) + .catch((err) => { + log.error({ userId: user.id, workspaceId: ws.workspace.id }, "Failed to update workspace", err); + }); + } } private async updateUser(user: User): Promise {