From c675f4549142201cbe07ca5b0e66ab95dc70590b Mon Sep 17 00:00:00 2001 From: Alexey Zinoviev Date: Sat, 3 Aug 2024 10:10:44 +0400 Subject: [PATCH] uberf-7764: improve space permissions query (#6236) Signed-off-by: Alexey Zinoviev --- plugins/view-resources/src/utils.ts | 107 +++++++++++++++++----------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/plugins/view-resources/src/utils.ts b/plugins/view-resources/src/utils.ts index 7f5ba88114..df58df7436 100644 --- a/plugins/view-resources/src/utils.ts +++ b/plugins/view-resources/src/utils.ts @@ -1495,59 +1495,80 @@ export const permissionsStore = writable({ ap: {}, whitelist: new Set() }) + +const spaceTypesQuery = createQuery(true) const permissionsQuery = createQuery(true) +type TargetClassesProjection = Record>, number> -permissionsQuery.query(core.class.Space, {}, (res) => { - const whitelistedSpaces = new Set>() - const permissionsBySpace: PermissionsBySpace = {} - const accountsByPermission: AccountsByPermission = {} - const client = getClient() - const hierarchy = client.getHierarchy() - const me = getCurrentAccount() +spaceTypesQuery.query(core.class.SpaceType, {}, (types) => { + const targetClasses = types.reduce((acc, st) => { + acc[st.targetClass] = 1 + return acc + }, {}) - for (const s of res) { - if (hierarchy.isDerived(s._class, core.class.TypedSpace)) { - const type = client.getModel().findAllSync(core.class.SpaceType, { _id: (s as TypedSpace).type })[0] - const mixin = type?.targetClass + permissionsQuery.query( + core.class.Space, + {}, + (res) => { + const whitelistedSpaces = new Set>() + const permissionsBySpace: PermissionsBySpace = {} + const accountsByPermission: AccountsByPermission = {} + const client = getClient() + const hierarchy = client.getHierarchy() + const me = getCurrentAccount() - if (mixin === undefined) { - permissionsBySpace[s._id] = new Set() - accountsByPermission[s._id] = {} - continue - } + for (const s of res) { + if (hierarchy.isDerived(s._class, core.class.TypedSpace)) { + const type = client.getModel().findAllSync(core.class.SpaceType, { _id: (s as TypedSpace).type })[0] + const mixin = type?.targetClass - const asMixin = hierarchy.as(s, mixin) - const roles = client.getModel().findAllSync(core.class.Role, { attachedTo: type._id }) - const myRoles = roles.filter((r) => ((asMixin as any)[r._id] ?? []).includes(me._id)) - permissionsBySpace[s._id] = new Set(myRoles.flatMap((r) => r.permissions)) - - accountsByPermission[s._id] = {} - - for (const role of roles) { - const assignment: Array> = (asMixin as any)[role._id] ?? [] - - if (assignment.length === 0) { - continue - } - - for (const permissionId of role.permissions) { - if (accountsByPermission[s._id][permissionId] === undefined) { - accountsByPermission[s._id][permissionId] = new Set() + if (mixin === undefined) { + permissionsBySpace[s._id] = new Set() + accountsByPermission[s._id] = {} + continue } - assignment.forEach((acc) => accountsByPermission[s._id][permissionId].add(acc)) + const asMixin = hierarchy.as(s, mixin) + const roles = client.getModel().findAllSync(core.class.Role, { attachedTo: type._id }) + const myRoles = roles.filter((r) => ((asMixin as any)[r._id] ?? []).includes(me._id)) + permissionsBySpace[s._id] = new Set(myRoles.flatMap((r) => r.permissions)) + + accountsByPermission[s._id] = {} + + for (const role of roles) { + const assignment: Array> = (asMixin as any)[role._id] ?? [] + + if (assignment.length === 0) { + continue + } + + for (const permissionId of role.permissions) { + if (accountsByPermission[s._id][permissionId] === undefined) { + accountsByPermission[s._id][permissionId] = new Set() + } + + assignment.forEach((acc) => accountsByPermission[s._id][permissionId].add(acc)) + } + } + } else { + whitelistedSpaces.add(s._id) } } - } else { - whitelistedSpaces.add(s._id) - } - } - permissionsStore.set({ - ps: permissionsBySpace, - ap: accountsByPermission, - whitelist: whitelistedSpaces - }) + permissionsStore.set({ + ps: permissionsBySpace, + ap: accountsByPermission, + whitelist: whitelistedSpaces + }) + }, + { + projection: { + _id: 1, + type: 1, + ...targetClasses + } as any + } + ) }) export function getCollaborationUser (): CollaborationUser {