@backstage/plugin-catalog-backend-module-msgraph 0.8.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @backstage/plugin-catalog-backend-module-msgraph
2
2
 
3
+ ## 0.8.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 115b378: Changed the logger level from 'warning' to 'debug' when we are unable to load the user's photo.
8
+ - Updated dependencies
9
+ - @backstage/backend-plugin-api@1.6.1
10
+
3
11
  ## 0.8.3
4
12
 
5
13
  ### Patch Changes
@@ -304,7 +304,7 @@ async function transformUsers(client, users, logger, loadUserPhotos = true, tran
304
304
  );
305
305
  }
306
306
  } catch (e) {
307
- logger.warn(`Unable to load user photo for`, {
307
+ logger.debug(`Unable to load user photo for`, {
308
308
  user: user.id,
309
309
  error: e
310
310
  });
@@ -1 +1 @@
1
- {"version":3,"file":"read.cjs.js","sources":["../../src/microsoftGraph/read.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n GroupEntity,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport limiterFactory from 'p-limit';\nimport { MicrosoftGraphClient } from './client';\nimport {\n MICROSOFT_GRAPH_GROUP_ID_ANNOTATION,\n MICROSOFT_GRAPH_TENANT_ID_ANNOTATION,\n MICROSOFT_GRAPH_USER_ID_ANNOTATION,\n} from './constants';\nimport { buildMemberOf, buildOrgHierarchy } from './org';\nimport {\n GroupTransformer,\n OrganizationTransformer,\n UserTransformer,\n} from './types';\nimport {\n defaultGroupTransformer,\n defaultOrganizationTransformer,\n defaultUserTransformer,\n} from './defaultTransformers';\nimport * as MicrosoftGraph from '@microsoft/microsoft-graph-types';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nconst PAGE_SIZE = 999;\n\nexport async function readMicrosoftGraphUsers(\n client: MicrosoftGraphClient,\n options: {\n queryMode?: 'basic' | 'advanced';\n userExpand?: string;\n userFilter?: string;\n userSelect?: string[];\n userPath?: string;\n loadUserPhotos?: boolean;\n transformer?: UserTransformer;\n logger: LoggerService;\n },\n): Promise<{\n users: UserEntity[]; // With all relations empty\n}> {\n const users = client.getUsers(\n {\n filter: options.userFilter,\n expand: options.userExpand,\n select: options.userSelect,\n top: PAGE_SIZE,\n },\n options.queryMode,\n options.userPath,\n );\n\n return {\n users: await transformUsers(\n client,\n users,\n options.logger,\n options.loadUserPhotos,\n options.transformer,\n ),\n };\n}\n\nexport async function readMicrosoftGraphUsersInGroups(\n client: MicrosoftGraphClient,\n options: {\n queryMode?: 'basic' | 'advanced';\n userExpand?: string;\n userFilter?: string;\n userSelect?: string[];\n loadUserPhotos?: boolean;\n userGroupMemberSearch?: string;\n userGroupMemberFilter?: string;\n userGroupMemberPath?: string;\n groupExpand?: string;\n transformer?: UserTransformer;\n logger: LoggerService;\n },\n): Promise<{\n users: UserEntity[]; // With all relations empty\n}> {\n const limiter = limiterFactory(10);\n\n const userGroupMemberPromises: Promise<void>[] = [];\n const userGroupMembers = new Map<string, MicrosoftGraph.User>();\n\n for await (const group of client.getGroups(\n {\n expand: options.groupExpand,\n filter: options.userGroupMemberFilter,\n search: options.userGroupMemberSearch,\n select: ['id', 'displayName'],\n top: PAGE_SIZE,\n },\n options.queryMode,\n options.userGroupMemberPath,\n )) {\n // Process all groups in parallel, otherwise it can take quite some time\n userGroupMemberPromises.push(\n limiter(async () => {\n let groupMemberCount = 0;\n for await (const user of client.getGroupUserMembers(\n group.id!,\n {\n expand: options.userExpand,\n filter: options.userFilter,\n select: options.userSelect,\n top: PAGE_SIZE,\n },\n options.queryMode,\n )) {\n userGroupMembers.set(user.id!, user);\n groupMemberCount++;\n }\n options.logger.debug('Read users from group', {\n groupId: group.id,\n groupName: group.displayName,\n memberCount: groupMemberCount,\n });\n }),\n );\n }\n\n // Wait for all group members\n await Promise.all(userGroupMemberPromises);\n\n options.logger.info('Read users from group membership', {\n groupCount: userGroupMemberPromises.length,\n userCount: userGroupMembers.size,\n });\n\n return {\n users: await transformUsers(\n client,\n userGroupMembers.values(),\n options.logger,\n options.loadUserPhotos,\n options.transformer,\n ),\n };\n}\n\nexport async function readMicrosoftGraphOrganization(\n client: MicrosoftGraphClient,\n tenantId: string,\n options?: { transformer?: OrganizationTransformer },\n): Promise<{\n rootGroup?: GroupEntity; // With all relations empty\n}> {\n // For now we expect a single root organization\n const organization = await client.getOrganization(tenantId);\n const transformer = options?.transformer ?? defaultOrganizationTransformer;\n const rootGroup = await transformer(organization);\n\n return { rootGroup };\n}\n\nexport async function readMicrosoftGraphGroups(\n client: MicrosoftGraphClient,\n tenantId: string,\n options?: {\n queryMode?: 'basic' | 'advanced';\n groupExpand?: string;\n groupFilter?: string;\n groupSearch?: string;\n groupSelect?: string[];\n groupPath?: string;\n groupIncludeSubGroups?: boolean;\n groupTransformer?: GroupTransformer;\n organizationTransformer?: OrganizationTransformer;\n },\n): Promise<{\n groups: GroupEntity[]; // With all relations empty\n rootGroup: GroupEntity | undefined; // With all relations empty\n groupMember: Map<string, Set<string>>;\n groupMemberOf: Map<string, Set<string>>;\n}> {\n const groups: GroupEntity[] = [];\n const groupMember: Map<string, Set<string>> = new Map();\n const groupMemberOf: Map<string, Set<string>> = new Map();\n const limiter = limiterFactory(10);\n\n const { rootGroup } = await readMicrosoftGraphOrganization(client, tenantId, {\n transformer: options?.organizationTransformer,\n });\n if (rootGroup) {\n groupMember.set(rootGroup.metadata.name, new Set<string>());\n groups.push(rootGroup);\n }\n\n const transformer = options?.groupTransformer ?? defaultGroupTransformer;\n const promises: Promise<void>[] = [];\n\n for await (const group of client.getGroups(\n {\n expand: options?.groupExpand,\n filter: options?.groupFilter,\n search: options?.groupSearch,\n select: options?.groupSelect,\n top: PAGE_SIZE,\n },\n options?.queryMode,\n options?.groupPath,\n )) {\n // Process all groups in parallel, otherwise it can take quite some time\n promises.push(\n limiter(async () => {\n // TODO: Loading groups photos doesn't work right now as Microsoft Graph\n // doesn't allows this yet: https://microsoftgraph.uservoice.com/forums/920506-microsoft-graph-feature-requests/suggestions/37884922-allow-application-to-set-or-update-a-group-s-photo\n /* const groupPhoto = await client.getGroupPhotoWithSizeLimit(\n group.id!,\n // We are limiting the photo size, as groups with full resolution photos\n // can make the Backstage API slow\n 120,\n );*/\n\n const entity = await transformer(group /* , groupPhoto*/);\n\n if (!entity) {\n return;\n }\n\n for await (const member of client.getGroupMembers(group.id!, {\n top: PAGE_SIZE,\n })) {\n if (!member.id) {\n continue;\n }\n\n if (member['@odata.type'] === '#microsoft.graph.user') {\n ensureItem(groupMemberOf, member.id, group.id!);\n }\n\n if (member['@odata.type'] === '#microsoft.graph.group') {\n ensureItem(groupMember, group.id!, member.id);\n\n if (options?.groupIncludeSubGroups) {\n const groupMemberEntity = await transformer(member);\n\n if (groupMemberEntity) {\n groups.push(groupMemberEntity);\n\n for await (const subMember of client.getGroupMembers(\n member.id!,\n { top: PAGE_SIZE },\n )) {\n if (!subMember.id) {\n continue;\n }\n\n if (subMember['@odata.type'] === '#microsoft.graph.user') {\n ensureItem(groupMemberOf, subMember.id, member.id!);\n }\n\n if (subMember['@odata.type'] === '#microsoft.graph.group') {\n ensureItem(groupMember, member.id!, subMember.id);\n }\n }\n }\n }\n }\n }\n\n groups.push(entity);\n }),\n );\n }\n\n // Wait for all group members and photos to be loaded\n await Promise.all(promises);\n\n return {\n groups,\n rootGroup,\n groupMember,\n groupMemberOf,\n };\n}\n\nexport function resolveRelations(\n rootGroup: GroupEntity | undefined,\n groups: GroupEntity[],\n users: UserEntity[],\n groupMember: Map<string, Set<string>>,\n groupMemberOf: Map<string, Set<string>>,\n) {\n // Build reference lookup tables, we reference them by the id of the graph\n const groupMap: Map<string, GroupEntity> = new Map(); // by group-id or tenant-id\n\n for (const group of groups) {\n if (group.metadata.annotations![MICROSOFT_GRAPH_GROUP_ID_ANNOTATION]) {\n groupMap.set(\n group.metadata.annotations![MICROSOFT_GRAPH_GROUP_ID_ANNOTATION],\n group,\n );\n }\n if (group.metadata.annotations![MICROSOFT_GRAPH_TENANT_ID_ANNOTATION]) {\n groupMap.set(\n group.metadata.annotations![MICROSOFT_GRAPH_TENANT_ID_ANNOTATION],\n group,\n );\n }\n }\n\n // Resolve all member relationships into the reverse direction\n const parentGroups = new Map<string, Set<string>>();\n\n groupMember.forEach((members, groupId) =>\n members.forEach(m => ensureItem(parentGroups, m, groupId)),\n );\n\n // Make sure every group (except root) has at least one parent. If the parent is missing, add the root.\n if (rootGroup) {\n const tenantId =\n rootGroup.metadata.annotations![MICROSOFT_GRAPH_TENANT_ID_ANNOTATION];\n\n groups.forEach(group => {\n const groupId =\n group.metadata.annotations![MICROSOFT_GRAPH_GROUP_ID_ANNOTATION];\n\n if (!groupId) {\n return;\n }\n\n if (retrieveItems(parentGroups, groupId).size === 0) {\n ensureItem(parentGroups, groupId, tenantId);\n ensureItem(groupMember, tenantId, groupId);\n }\n });\n }\n\n groups.forEach(group => {\n const id =\n group.metadata.annotations![MICROSOFT_GRAPH_GROUP_ID_ANNOTATION] ??\n group.metadata.annotations![MICROSOFT_GRAPH_TENANT_ID_ANNOTATION];\n\n retrieveItems(groupMember, id).forEach(m => {\n const childGroup = groupMap.get(m);\n if (childGroup) {\n group.spec.children.push(stringifyEntityRef(childGroup));\n }\n });\n\n // TODO: Until we have better support for multiple parents in the model,\n // the order of the parents is important as changing it causes\n // unnecessary entity stitching randomly.\n retrieveItems(parentGroups, id).forEach(p => {\n // Only set the parent if it doesn't exist yet\n if (group.spec.parent) {\n return;\n }\n const parentGroup = groupMap.get(p);\n if (parentGroup) {\n // TODO: Only having a single parent group might not match every companies model, but fine for now.\n group.spec.parent = stringifyEntityRef(parentGroup);\n }\n });\n });\n\n // Make sure that all groups have proper parents and children\n buildOrgHierarchy(groups);\n\n // Set relations for all users\n users.forEach(user => {\n const id = user.metadata.annotations![MICROSOFT_GRAPH_USER_ID_ANNOTATION];\n\n retrieveItems(groupMemberOf, id).forEach(p => {\n const parentGroup = groupMap.get(p);\n if (parentGroup) {\n if (!user.spec.memberOf) {\n user.spec.memberOf = [];\n }\n user.spec.memberOf.push(stringifyEntityRef(parentGroup));\n }\n });\n });\n\n // Make sure all transitive memberships are available\n buildMemberOf(groups, users);\n}\n\n/**\n * Reads an entire org as Group and User entities.\n *\n * @public\n */\nexport async function readMicrosoftGraphOrg(\n client: MicrosoftGraphClient,\n tenantId: string,\n options: {\n userExpand?: string;\n userFilter?: string;\n userSelect?: string[];\n userPath?: string;\n loadUserPhotos?: boolean;\n userGroupMemberSearch?: string;\n userGroupMemberFilter?: string;\n userGroupMemberPath?: string;\n groupExpand?: string;\n groupSearch?: string;\n groupFilter?: string;\n groupSelect?: string[];\n groupPath?: string;\n groupIncludeSubGroups?: boolean;\n queryMode?: 'basic' | 'advanced';\n userTransformer?: UserTransformer;\n groupTransformer?: GroupTransformer;\n organizationTransformer?: OrganizationTransformer;\n logger: LoggerService;\n },\n): Promise<{ users: UserEntity[]; groups: GroupEntity[] }> {\n let users: UserEntity[] = [];\n\n if (\n options.userGroupMemberFilter ||\n options.userGroupMemberSearch ||\n options.userGroupMemberPath\n ) {\n const { users: usersInGroups } = await readMicrosoftGraphUsersInGroups(\n client,\n {\n queryMode: options.queryMode,\n userExpand: options.userExpand,\n userFilter: options.userFilter,\n userSelect: options.userSelect,\n userGroupMemberFilter: options.userGroupMemberFilter,\n userGroupMemberSearch: options.userGroupMemberSearch,\n userGroupMemberPath: options.userGroupMemberPath,\n loadUserPhotos: options.loadUserPhotos,\n transformer: options.userTransformer,\n logger: options.logger,\n },\n );\n users = usersInGroups;\n } else {\n const { users: usersWithFilter } = await readMicrosoftGraphUsers(client, {\n queryMode: options.queryMode,\n userExpand: options.userExpand,\n userFilter: options.userFilter,\n userSelect: options.userSelect,\n userPath: options.userPath,\n loadUserPhotos: options.loadUserPhotos,\n transformer: options.userTransformer,\n logger: options.logger,\n });\n users = usersWithFilter;\n }\n const { groups, rootGroup, groupMember, groupMemberOf } =\n await readMicrosoftGraphGroups(client, tenantId, {\n queryMode: options.queryMode,\n groupExpand: options.groupExpand,\n groupFilter: options.groupFilter,\n groupSearch: options.groupSearch,\n groupSelect: options.groupSelect,\n groupPath: options.groupPath,\n groupIncludeSubGroups: options.groupIncludeSubGroups,\n groupTransformer: options.groupTransformer,\n organizationTransformer: options.organizationTransformer,\n });\n\n resolveRelations(rootGroup, groups, users, groupMember, groupMemberOf);\n users.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n groups.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n\n return { users, groups };\n}\n\nasync function transformUsers(\n client: MicrosoftGraphClient,\n users: Iterable<MicrosoftGraph.User> | AsyncIterable<MicrosoftGraph.User>,\n logger: LoggerService,\n loadUserPhotos = true,\n transformer?: UserTransformer,\n) {\n const limiter = limiterFactory(10);\n\n const resolvedTransformer = transformer ?? defaultUserTransformer;\n const promises: Promise<void>[] = [];\n const entities: UserEntity[] = [];\n\n // Process all users in parallel, otherwise it can take quite some time\n for await (const user of users) {\n promises.push(\n limiter(async () => {\n let userPhoto;\n try {\n if (loadUserPhotos) {\n userPhoto = await client.getUserPhotoWithSizeLimit(\n user.id!,\n // We are limiting the photo size, as users with full resolution photos\n // can make the Backstage API slow\n 120,\n );\n }\n } catch (e) {\n logger.warn(`Unable to load user photo for`, {\n user: user.id,\n error: e,\n });\n }\n\n const entity = await resolvedTransformer(user, userPhoto);\n\n if (entity) {\n entities.push(entity);\n }\n }),\n );\n }\n\n // Wait for all users and photos to be downloaded\n await Promise.all(promises);\n\n logger.debug('Finished transforming users', {\n microsoftUserCount: promises.length,\n backstageUserCount: entities.length,\n });\n return entities;\n}\n\nfunction ensureItem(\n target: Map<string, Set<string>>,\n key: string,\n value: string,\n) {\n let set = target.get(key);\n if (!set) {\n set = new Set();\n target.set(key, set);\n }\n set!.add(value);\n}\n\nfunction retrieveItems(\n target: Map<string, Set<string>>,\n key: string,\n): Set<string> {\n return new Set([...(target.get(key) ?? [])].sort());\n}\n"],"names":["limiterFactory","defaultOrganizationTransformer","defaultGroupTransformer","MICROSOFT_GRAPH_GROUP_ID_ANNOTATION","MICROSOFT_GRAPH_TENANT_ID_ANNOTATION","stringifyEntityRef","buildOrgHierarchy","MICROSOFT_GRAPH_USER_ID_ANNOTATION","buildMemberOf","defaultUserTransformer"],"mappings":"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"}
1
+ {"version":3,"file":"read.cjs.js","sources":["../../src/microsoftGraph/read.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n GroupEntity,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport limiterFactory from 'p-limit';\nimport { MicrosoftGraphClient } from './client';\nimport {\n MICROSOFT_GRAPH_GROUP_ID_ANNOTATION,\n MICROSOFT_GRAPH_TENANT_ID_ANNOTATION,\n MICROSOFT_GRAPH_USER_ID_ANNOTATION,\n} from './constants';\nimport { buildMemberOf, buildOrgHierarchy } from './org';\nimport {\n GroupTransformer,\n OrganizationTransformer,\n UserTransformer,\n} from './types';\nimport {\n defaultGroupTransformer,\n defaultOrganizationTransformer,\n defaultUserTransformer,\n} from './defaultTransformers';\nimport * as MicrosoftGraph from '@microsoft/microsoft-graph-types';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nconst PAGE_SIZE = 999;\n\nexport async function readMicrosoftGraphUsers(\n client: MicrosoftGraphClient,\n options: {\n queryMode?: 'basic' | 'advanced';\n userExpand?: string;\n userFilter?: string;\n userSelect?: string[];\n userPath?: string;\n loadUserPhotos?: boolean;\n transformer?: UserTransformer;\n logger: LoggerService;\n },\n): Promise<{\n users: UserEntity[]; // With all relations empty\n}> {\n const users = client.getUsers(\n {\n filter: options.userFilter,\n expand: options.userExpand,\n select: options.userSelect,\n top: PAGE_SIZE,\n },\n options.queryMode,\n options.userPath,\n );\n\n return {\n users: await transformUsers(\n client,\n users,\n options.logger,\n options.loadUserPhotos,\n options.transformer,\n ),\n };\n}\n\nexport async function readMicrosoftGraphUsersInGroups(\n client: MicrosoftGraphClient,\n options: {\n queryMode?: 'basic' | 'advanced';\n userExpand?: string;\n userFilter?: string;\n userSelect?: string[];\n loadUserPhotos?: boolean;\n userGroupMemberSearch?: string;\n userGroupMemberFilter?: string;\n userGroupMemberPath?: string;\n groupExpand?: string;\n transformer?: UserTransformer;\n logger: LoggerService;\n },\n): Promise<{\n users: UserEntity[]; // With all relations empty\n}> {\n const limiter = limiterFactory(10);\n\n const userGroupMemberPromises: Promise<void>[] = [];\n const userGroupMembers = new Map<string, MicrosoftGraph.User>();\n\n for await (const group of client.getGroups(\n {\n expand: options.groupExpand,\n filter: options.userGroupMemberFilter,\n search: options.userGroupMemberSearch,\n select: ['id', 'displayName'],\n top: PAGE_SIZE,\n },\n options.queryMode,\n options.userGroupMemberPath,\n )) {\n // Process all groups in parallel, otherwise it can take quite some time\n userGroupMemberPromises.push(\n limiter(async () => {\n let groupMemberCount = 0;\n for await (const user of client.getGroupUserMembers(\n group.id!,\n {\n expand: options.userExpand,\n filter: options.userFilter,\n select: options.userSelect,\n top: PAGE_SIZE,\n },\n options.queryMode,\n )) {\n userGroupMembers.set(user.id!, user);\n groupMemberCount++;\n }\n options.logger.debug('Read users from group', {\n groupId: group.id,\n groupName: group.displayName,\n memberCount: groupMemberCount,\n });\n }),\n );\n }\n\n // Wait for all group members\n await Promise.all(userGroupMemberPromises);\n\n options.logger.info('Read users from group membership', {\n groupCount: userGroupMemberPromises.length,\n userCount: userGroupMembers.size,\n });\n\n return {\n users: await transformUsers(\n client,\n userGroupMembers.values(),\n options.logger,\n options.loadUserPhotos,\n options.transformer,\n ),\n };\n}\n\nexport async function readMicrosoftGraphOrganization(\n client: MicrosoftGraphClient,\n tenantId: string,\n options?: { transformer?: OrganizationTransformer },\n): Promise<{\n rootGroup?: GroupEntity; // With all relations empty\n}> {\n // For now we expect a single root organization\n const organization = await client.getOrganization(tenantId);\n const transformer = options?.transformer ?? defaultOrganizationTransformer;\n const rootGroup = await transformer(organization);\n\n return { rootGroup };\n}\n\nexport async function readMicrosoftGraphGroups(\n client: MicrosoftGraphClient,\n tenantId: string,\n options?: {\n queryMode?: 'basic' | 'advanced';\n groupExpand?: string;\n groupFilter?: string;\n groupSearch?: string;\n groupSelect?: string[];\n groupPath?: string;\n groupIncludeSubGroups?: boolean;\n groupTransformer?: GroupTransformer;\n organizationTransformer?: OrganizationTransformer;\n },\n): Promise<{\n groups: GroupEntity[]; // With all relations empty\n rootGroup: GroupEntity | undefined; // With all relations empty\n groupMember: Map<string, Set<string>>;\n groupMemberOf: Map<string, Set<string>>;\n}> {\n const groups: GroupEntity[] = [];\n const groupMember: Map<string, Set<string>> = new Map();\n const groupMemberOf: Map<string, Set<string>> = new Map();\n const limiter = limiterFactory(10);\n\n const { rootGroup } = await readMicrosoftGraphOrganization(client, tenantId, {\n transformer: options?.organizationTransformer,\n });\n if (rootGroup) {\n groupMember.set(rootGroup.metadata.name, new Set<string>());\n groups.push(rootGroup);\n }\n\n const transformer = options?.groupTransformer ?? defaultGroupTransformer;\n const promises: Promise<void>[] = [];\n\n for await (const group of client.getGroups(\n {\n expand: options?.groupExpand,\n filter: options?.groupFilter,\n search: options?.groupSearch,\n select: options?.groupSelect,\n top: PAGE_SIZE,\n },\n options?.queryMode,\n options?.groupPath,\n )) {\n // Process all groups in parallel, otherwise it can take quite some time\n promises.push(\n limiter(async () => {\n // TODO: Loading groups photos doesn't work right now as Microsoft Graph\n // doesn't allows this yet: https://microsoftgraph.uservoice.com/forums/920506-microsoft-graph-feature-requests/suggestions/37884922-allow-application-to-set-or-update-a-group-s-photo\n /* const groupPhoto = await client.getGroupPhotoWithSizeLimit(\n group.id!,\n // We are limiting the photo size, as groups with full resolution photos\n // can make the Backstage API slow\n 120,\n );*/\n\n const entity = await transformer(group /* , groupPhoto*/);\n\n if (!entity) {\n return;\n }\n\n for await (const member of client.getGroupMembers(group.id!, {\n top: PAGE_SIZE,\n })) {\n if (!member.id) {\n continue;\n }\n\n if (member['@odata.type'] === '#microsoft.graph.user') {\n ensureItem(groupMemberOf, member.id, group.id!);\n }\n\n if (member['@odata.type'] === '#microsoft.graph.group') {\n ensureItem(groupMember, group.id!, member.id);\n\n if (options?.groupIncludeSubGroups) {\n const groupMemberEntity = await transformer(member);\n\n if (groupMemberEntity) {\n groups.push(groupMemberEntity);\n\n for await (const subMember of client.getGroupMembers(\n member.id!,\n { top: PAGE_SIZE },\n )) {\n if (!subMember.id) {\n continue;\n }\n\n if (subMember['@odata.type'] === '#microsoft.graph.user') {\n ensureItem(groupMemberOf, subMember.id, member.id!);\n }\n\n if (subMember['@odata.type'] === '#microsoft.graph.group') {\n ensureItem(groupMember, member.id!, subMember.id);\n }\n }\n }\n }\n }\n }\n\n groups.push(entity);\n }),\n );\n }\n\n // Wait for all group members and photos to be loaded\n await Promise.all(promises);\n\n return {\n groups,\n rootGroup,\n groupMember,\n groupMemberOf,\n };\n}\n\nexport function resolveRelations(\n rootGroup: GroupEntity | undefined,\n groups: GroupEntity[],\n users: UserEntity[],\n groupMember: Map<string, Set<string>>,\n groupMemberOf: Map<string, Set<string>>,\n) {\n // Build reference lookup tables, we reference them by the id of the graph\n const groupMap: Map<string, GroupEntity> = new Map(); // by group-id or tenant-id\n\n for (const group of groups) {\n if (group.metadata.annotations![MICROSOFT_GRAPH_GROUP_ID_ANNOTATION]) {\n groupMap.set(\n group.metadata.annotations![MICROSOFT_GRAPH_GROUP_ID_ANNOTATION],\n group,\n );\n }\n if (group.metadata.annotations![MICROSOFT_GRAPH_TENANT_ID_ANNOTATION]) {\n groupMap.set(\n group.metadata.annotations![MICROSOFT_GRAPH_TENANT_ID_ANNOTATION],\n group,\n );\n }\n }\n\n // Resolve all member relationships into the reverse direction\n const parentGroups = new Map<string, Set<string>>();\n\n groupMember.forEach((members, groupId) =>\n members.forEach(m => ensureItem(parentGroups, m, groupId)),\n );\n\n // Make sure every group (except root) has at least one parent. If the parent is missing, add the root.\n if (rootGroup) {\n const tenantId =\n rootGroup.metadata.annotations![MICROSOFT_GRAPH_TENANT_ID_ANNOTATION];\n\n groups.forEach(group => {\n const groupId =\n group.metadata.annotations![MICROSOFT_GRAPH_GROUP_ID_ANNOTATION];\n\n if (!groupId) {\n return;\n }\n\n if (retrieveItems(parentGroups, groupId).size === 0) {\n ensureItem(parentGroups, groupId, tenantId);\n ensureItem(groupMember, tenantId, groupId);\n }\n });\n }\n\n groups.forEach(group => {\n const id =\n group.metadata.annotations![MICROSOFT_GRAPH_GROUP_ID_ANNOTATION] ??\n group.metadata.annotations![MICROSOFT_GRAPH_TENANT_ID_ANNOTATION];\n\n retrieveItems(groupMember, id).forEach(m => {\n const childGroup = groupMap.get(m);\n if (childGroup) {\n group.spec.children.push(stringifyEntityRef(childGroup));\n }\n });\n\n // TODO: Until we have better support for multiple parents in the model,\n // the order of the parents is important as changing it causes\n // unnecessary entity stitching randomly.\n retrieveItems(parentGroups, id).forEach(p => {\n // Only set the parent if it doesn't exist yet\n if (group.spec.parent) {\n return;\n }\n const parentGroup = groupMap.get(p);\n if (parentGroup) {\n // TODO: Only having a single parent group might not match every companies model, but fine for now.\n group.spec.parent = stringifyEntityRef(parentGroup);\n }\n });\n });\n\n // Make sure that all groups have proper parents and children\n buildOrgHierarchy(groups);\n\n // Set relations for all users\n users.forEach(user => {\n const id = user.metadata.annotations![MICROSOFT_GRAPH_USER_ID_ANNOTATION];\n\n retrieveItems(groupMemberOf, id).forEach(p => {\n const parentGroup = groupMap.get(p);\n if (parentGroup) {\n if (!user.spec.memberOf) {\n user.spec.memberOf = [];\n }\n user.spec.memberOf.push(stringifyEntityRef(parentGroup));\n }\n });\n });\n\n // Make sure all transitive memberships are available\n buildMemberOf(groups, users);\n}\n\n/**\n * Reads an entire org as Group and User entities.\n *\n * @public\n */\nexport async function readMicrosoftGraphOrg(\n client: MicrosoftGraphClient,\n tenantId: string,\n options: {\n userExpand?: string;\n userFilter?: string;\n userSelect?: string[];\n userPath?: string;\n loadUserPhotos?: boolean;\n userGroupMemberSearch?: string;\n userGroupMemberFilter?: string;\n userGroupMemberPath?: string;\n groupExpand?: string;\n groupSearch?: string;\n groupFilter?: string;\n groupSelect?: string[];\n groupPath?: string;\n groupIncludeSubGroups?: boolean;\n queryMode?: 'basic' | 'advanced';\n userTransformer?: UserTransformer;\n groupTransformer?: GroupTransformer;\n organizationTransformer?: OrganizationTransformer;\n logger: LoggerService;\n },\n): Promise<{ users: UserEntity[]; groups: GroupEntity[] }> {\n let users: UserEntity[] = [];\n\n if (\n options.userGroupMemberFilter ||\n options.userGroupMemberSearch ||\n options.userGroupMemberPath\n ) {\n const { users: usersInGroups } = await readMicrosoftGraphUsersInGroups(\n client,\n {\n queryMode: options.queryMode,\n userExpand: options.userExpand,\n userFilter: options.userFilter,\n userSelect: options.userSelect,\n userGroupMemberFilter: options.userGroupMemberFilter,\n userGroupMemberSearch: options.userGroupMemberSearch,\n userGroupMemberPath: options.userGroupMemberPath,\n loadUserPhotos: options.loadUserPhotos,\n transformer: options.userTransformer,\n logger: options.logger,\n },\n );\n users = usersInGroups;\n } else {\n const { users: usersWithFilter } = await readMicrosoftGraphUsers(client, {\n queryMode: options.queryMode,\n userExpand: options.userExpand,\n userFilter: options.userFilter,\n userSelect: options.userSelect,\n userPath: options.userPath,\n loadUserPhotos: options.loadUserPhotos,\n transformer: options.userTransformer,\n logger: options.logger,\n });\n users = usersWithFilter;\n }\n const { groups, rootGroup, groupMember, groupMemberOf } =\n await readMicrosoftGraphGroups(client, tenantId, {\n queryMode: options.queryMode,\n groupExpand: options.groupExpand,\n groupFilter: options.groupFilter,\n groupSearch: options.groupSearch,\n groupSelect: options.groupSelect,\n groupPath: options.groupPath,\n groupIncludeSubGroups: options.groupIncludeSubGroups,\n groupTransformer: options.groupTransformer,\n organizationTransformer: options.organizationTransformer,\n });\n\n resolveRelations(rootGroup, groups, users, groupMember, groupMemberOf);\n users.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n groups.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n\n return { users, groups };\n}\n\nasync function transformUsers(\n client: MicrosoftGraphClient,\n users: Iterable<MicrosoftGraph.User> | AsyncIterable<MicrosoftGraph.User>,\n logger: LoggerService,\n loadUserPhotos = true,\n transformer?: UserTransformer,\n) {\n const limiter = limiterFactory(10);\n\n const resolvedTransformer = transformer ?? defaultUserTransformer;\n const promises: Promise<void>[] = [];\n const entities: UserEntity[] = [];\n\n // Process all users in parallel, otherwise it can take quite some time\n for await (const user of users) {\n promises.push(\n limiter(async () => {\n let userPhoto;\n try {\n if (loadUserPhotos) {\n userPhoto = await client.getUserPhotoWithSizeLimit(\n user.id!,\n // We are limiting the photo size, as users with full resolution photos\n // can make the Backstage API slow\n 120,\n );\n }\n } catch (e) {\n logger.debug(`Unable to load user photo for`, {\n user: user.id,\n error: e,\n });\n }\n\n const entity = await resolvedTransformer(user, userPhoto);\n\n if (entity) {\n entities.push(entity);\n }\n }),\n );\n }\n\n // Wait for all users and photos to be downloaded\n await Promise.all(promises);\n\n logger.debug('Finished transforming users', {\n microsoftUserCount: promises.length,\n backstageUserCount: entities.length,\n });\n return entities;\n}\n\nfunction ensureItem(\n target: Map<string, Set<string>>,\n key: string,\n value: string,\n) {\n let set = target.get(key);\n if (!set) {\n set = new Set();\n target.set(key, set);\n }\n set!.add(value);\n}\n\nfunction retrieveItems(\n target: Map<string, Set<string>>,\n key: string,\n): Set<string> {\n return new Set([...(target.get(key) ?? [])].sort());\n}\n"],"names":["limiterFactory","defaultOrganizationTransformer","defaultGroupTransformer","MICROSOFT_GRAPH_GROUP_ID_ANNOTATION","MICROSOFT_GRAPH_TENANT_ID_ANNOTATION","stringifyEntityRef","buildOrgHierarchy","MICROSOFT_GRAPH_USER_ID_ANNOTATION","buildMemberOf","defaultUserTransformer"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend-module-msgraph",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph",
5
5
  "backstage": {
6
6
  "role": "backend-plugin-module",
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@azure/identity": "^4.0.0",
69
- "@backstage/backend-plugin-api": "^1.6.0",
69
+ "@backstage/backend-plugin-api": "^1.6.1",
70
70
  "@backstage/catalog-model": "^1.7.6",
71
71
  "@backstage/config": "^1.3.6",
72
72
  "@backstage/plugin-catalog-common": "^1.1.7",
@@ -78,8 +78,8 @@
78
78
  "uuid": "^11.0.0"
79
79
  },
80
80
  "devDependencies": {
81
- "@backstage/backend-test-utils": "^1.10.2",
82
- "@backstage/cli": "^0.35.0",
81
+ "@backstage/backend-test-utils": "^1.10.3",
82
+ "@backstage/cli": "^0.35.2",
83
83
  "@types/lodash": "^4.14.151",
84
84
  "msw": "^1.0.0"
85
85
  },