@backstage-community/plugin-catalog-backend-module-keycloak 3.11.0 → 3.11.1
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 +6 -0
- package/dist/lib/read.cjs.js +2 -1
- package/dist/lib/read.cjs.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/lib/read.cjs.js
CHANGED
|
@@ -120,7 +120,8 @@ async function processGroupsRecursively(kcAdminClient, config, logger, topLevelG
|
|
|
120
120
|
parentId: group.id,
|
|
121
121
|
first: 0,
|
|
122
122
|
max: group.subGroupCount,
|
|
123
|
-
briefRepresentation: brief
|
|
123
|
+
briefRepresentation: brief,
|
|
124
|
+
realm: config.realm
|
|
124
125
|
});
|
|
125
126
|
const subGroupResults = await processGroupsRecursively(
|
|
126
127
|
kcAdminClient,
|
package/dist/lib/read.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.cjs.js","sources":["../../src/lib/read.ts"],"sourcesContent":["/*\n * Copyright 2024 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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { GroupEntity, UserEntity } from '@backstage/catalog-model';\n\nimport type KeycloakAdminClient from '@keycloak/keycloak-admin-client';\nimport type GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation';\nimport type UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation';\nimport type { Groups } from '@keycloak/keycloak-admin-client/lib/resources/groups';\nimport type { Users } from '@keycloak/keycloak-admin-client/lib/resources/users';\nimport { LimitFunction } from 'p-limit';\n\nimport { KeycloakProviderConfig } from './config';\nimport {\n KEYCLOAK_ENTITY_QUERY_SIZE,\n KEYCLOAK_ID_ANNOTATION,\n KEYCLOAK_REALM_ANNOTATION,\n KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT,\n} from './constants';\nimport { noopGroupTransformer, noopUserTransformer } from './transformers';\nimport {\n GroupRepresentationWithParent,\n GroupRepresentationWithParentAndEntity,\n GroupTransformer,\n UserRepresentationWithEntity,\n UserTransformer,\n} from './types';\nimport { ensureTokenValid } from './authenticate';\nimport { Attributes, Counter } from '@opentelemetry/api';\n\nexport const parseGroup = async (\n keycloakGroup: GroupRepresentationWithParent,\n realm: string,\n groupTransformer?: GroupTransformer,\n): Promise<GroupEntity | undefined> => {\n const transformer = groupTransformer ?? noopGroupTransformer;\n const entity: GroupEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'Group',\n metadata: {\n name: keycloakGroup.name!,\n annotations: {\n [KEYCLOAK_ID_ANNOTATION]: keycloakGroup.id!,\n [KEYCLOAK_REALM_ANNOTATION]: realm,\n },\n },\n spec: {\n type: 'group',\n profile: {\n displayName: keycloakGroup.name!,\n },\n // children, parent and members are updated again after all group and user transformers applied.\n children: keycloakGroup.subGroups?.map(g => g.name!) ?? [],\n parent: keycloakGroup.parent,\n members: keycloakGroup.members,\n },\n };\n\n return await transformer(entity, keycloakGroup, realm);\n};\n\nexport const parseUser = async (\n user: UserRepresentation,\n realm: string,\n keycloakGroups: GroupRepresentationWithParentAndEntity[],\n groupIndex: Map<string, string[]>,\n userTransformer?: UserTransformer,\n): Promise<UserEntity | undefined> => {\n const transformer = userTransformer ?? noopUserTransformer;\n const entity: UserEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'User',\n metadata: {\n name: user.username!,\n annotations: {\n [KEYCLOAK_ID_ANNOTATION]: user.id!,\n [KEYCLOAK_REALM_ANNOTATION]: realm,\n },\n },\n spec: {\n profile: {\n email: user.email,\n ...(user.firstName || user.lastName\n ? {\n displayName: [user.firstName, user.lastName]\n .filter(Boolean)\n .join(' '),\n }\n : {}),\n },\n memberOf: groupIndex.get(user.username!) ?? [],\n },\n };\n\n return await transformer(entity, user, realm, keycloakGroups);\n};\n\nexport async function getEntities<T extends Users | Groups>(\n getEntitiesFn: () => Promise<T>,\n config: KeycloakProviderConfig,\n logger: LoggerService,\n dataBatchFailureCounter: Counter<Attributes>,\n taskInstanceId: string,\n limit: LimitFunction,\n entityQuerySize: number = KEYCLOAK_ENTITY_QUERY_SIZE,\n): Promise<Awaited<ReturnType<T['find']>>> {\n const entitiesAPI = await getEntitiesFn();\n const rawEntityCount = await entitiesAPI.count({ realm: config.realm });\n const entityCount =\n typeof rawEntityCount === 'number' ? rawEntityCount : rawEntityCount.count;\n\n const pageCount = Math.ceil(entityCount / entityQuerySize);\n const brief =\n config.briefRepresentation ?? KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT;\n\n // The next line acts like range in python\n const entityPromises = Array.from({ length: pageCount }, (_, i) =>\n limit(() =>\n getEntitiesFn().then(entities => {\n return entities\n .find({\n realm: config.realm,\n max: entityQuerySize,\n first: i * entityQuerySize,\n briefRepresentation: brief,\n })\n .then(ents => {\n logger.debug(\n `Importing keycloak entities batch with index ${i} from pages: ${pageCount}`,\n );\n return ents;\n })\n .catch(err => {\n dataBatchFailureCounter.add(1, { taskInstanceId: taskInstanceId });\n logger.warn(\n `Failed to retieve Keycloak entities for taskInstanceId: ${taskInstanceId}. Error: ${err}`,\n );\n return [];\n }) as ReturnType<T['find']>;\n }),\n ),\n );\n\n const entityResults = (await Promise.all(entityPromises)).flat() as Awaited<\n ReturnType<T['find']>\n >;\n\n return entityResults;\n}\n\nasync function getAllGroupMembers<T extends Groups>(\n groupsAPI: () => Promise<T>,\n groupId: string,\n config: KeycloakProviderConfig,\n options?: { userQuerySize?: number },\n): Promise<string[]> {\n const querySize = options?.userQuerySize || 100;\n\n let allMembers: string[] = [];\n let page = 0;\n let totalMembers = 0;\n\n do {\n const groups = await groupsAPI();\n const members = await groups.listMembers({\n id: groupId,\n max: querySize,\n realm: config.realm,\n first: page * querySize,\n });\n\n if (members.length > 0) {\n allMembers = allMembers.concat(members.map(m => m.username!));\n totalMembers = members.length; // Get the number of members retrieved\n } else {\n totalMembers = 0; // No members retrieved\n }\n\n page++;\n } while (totalMembers > 0);\n\n return allMembers;\n}\n\nexport async function processGroupsRecursively(\n kcAdminClient: KeycloakAdminClient,\n config: KeycloakProviderConfig,\n logger: LoggerService,\n topLevelGroups: GroupRepresentationWithParent[],\n) {\n const allGroups: GroupRepresentationWithParent[] = [];\n const brief =\n config.briefRepresentation ?? KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT;\n\n for (const group of topLevelGroups) {\n allGroups.push(group);\n\n if (group.subGroupCount! > 0) {\n await ensureTokenValid(kcAdminClient, config, logger);\n const subgroups = await kcAdminClient.groups.listSubGroups({\n parentId: group.id!,\n first: 0,\n max: group.subGroupCount,\n briefRepresentation: brief,\n });\n const subGroupResults = await processGroupsRecursively(\n kcAdminClient,\n config,\n logger,\n subgroups,\n );\n allGroups.push(...subGroupResults);\n }\n }\n\n return allGroups;\n}\n\nexport function* traverseGroups(\n group: GroupRepresentation,\n): IterableIterator<GroupRepresentationWithParent> {\n yield group;\n for (const g of group.subGroups ?? []) {\n (g as GroupRepresentationWithParent).parent = group.name!;\n yield* traverseGroups(g);\n }\n}\n\nexport const readKeycloakRealm = async (\n client: KeycloakAdminClient,\n config: KeycloakProviderConfig,\n logger: LoggerService,\n limit: LimitFunction,\n taskInstanceId: string,\n dataBatchFailureCounter: Counter<Attributes>,\n options?: {\n userQuerySize?: number;\n groupQuerySize?: number;\n userTransformer?: UserTransformer;\n groupTransformer?: GroupTransformer;\n },\n): Promise<{\n users: UserEntity[];\n groups: GroupEntity[];\n}> => {\n const kUsers = await getEntities(\n async () => {\n await ensureTokenValid(client, config, logger);\n return client.users;\n },\n config,\n logger,\n dataBatchFailureCounter,\n taskInstanceId,\n limit,\n options?.userQuerySize,\n );\n logger.debug(`Fetched ${kUsers.length} users from Keycloak`);\n\n const topLevelKGroups = (await getEntities(\n async () => {\n await ensureTokenValid(client, config, logger);\n return client.groups;\n },\n config,\n logger,\n dataBatchFailureCounter,\n taskInstanceId,\n limit,\n options?.groupQuerySize,\n )) as GroupRepresentationWithParent[];\n logger.debug(`Fetched ${topLevelKGroups.length} groups from Keycloak`);\n\n let serverVersion: number;\n\n try {\n await ensureTokenValid(client, config, logger);\n const serverInfo = await client.serverInfo.find();\n serverVersion = parseInt(\n serverInfo.systemInfo?.version?.slice(0, 2) || '',\n 10,\n );\n } catch (error) {\n throw new Error(`Failed to retrieve Keycloak server information: ${error}`);\n }\n\n const isVersion23orHigher = serverVersion >= 23;\n\n let rawKGroups: GroupRepresentationWithParent[] = [];\n\n logger.debug(`Processing groups recursively`);\n if (isVersion23orHigher) {\n rawKGroups = await processGroupsRecursively(\n client,\n config,\n logger,\n topLevelKGroups,\n );\n } else {\n rawKGroups = topLevelKGroups.reduce(\n (acc, g) => acc.concat(...traverseGroups(g)),\n [] as GroupRepresentationWithParent[],\n );\n }\n\n logger.debug(`Fetching group members for keycloak groups and list subgroups`);\n const brief =\n config.briefRepresentation ?? KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT;\n\n const kGroups = await Promise.all(\n rawKGroups.map(g =>\n limit(async () => {\n g.members = await getAllGroupMembers(\n async () => {\n await ensureTokenValid(client, config, logger);\n return client.groups as Groups;\n },\n g.id!,\n config,\n options,\n );\n\n if (isVersion23orHigher) {\n if (g.subGroupCount! > 0) {\n await ensureTokenValid(client, config, logger);\n g.subGroups = await client.groups.listSubGroups({\n parentId: g.id!,\n first: 0,\n max: g.subGroupCount,\n briefRepresentation: brief,\n realm: config.realm,\n });\n }\n if (g.parentId) {\n await ensureTokenValid(client, config, logger);\n const groupParent = await client.groups.findOne({\n id: g.parentId,\n realm: config.realm,\n });\n g.parent = groupParent?.name;\n }\n }\n\n return g;\n }),\n ),\n );\n\n logger.debug(`Parsing groups`);\n const parsedGroups = await Promise.all(\n kGroups.map(async g => {\n // it is possible if fetch request failed\n if (!g) {\n return null;\n }\n const entity = await parseGroup(\n g,\n config.realm,\n options?.groupTransformer,\n );\n if (entity) {\n return { ...g, entity } as GroupRepresentationWithParentAndEntity;\n }\n return null;\n }),\n );\n const filteredParsedGroups = parsedGroups.filter(\n (group): group is GroupRepresentationWithParentAndEntity => group !== null,\n );\n\n const groupIndex = new Map<string, string[]>();\n filteredParsedGroups.forEach(group => {\n if (group.members) {\n group.members.forEach(member => {\n if (!groupIndex.has(member)) {\n groupIndex.set(member, []);\n }\n groupIndex.get(member)?.push(group.entity.metadata.name);\n });\n }\n });\n\n logger.debug('Parsing users');\n const parsedUsers = await Promise.all(\n kUsers.map(async u => {\n // it is possible if fetch request failed\n if (!u) {\n return null;\n }\n const entity = await parseUser(\n u,\n config.realm,\n filteredParsedGroups,\n groupIndex,\n options?.userTransformer,\n );\n if (entity) {\n return { ...u, entity } as UserRepresentationWithEntity;\n }\n return null;\n }),\n );\n const filteredParsedUsers = parsedUsers.filter(\n (user): user is UserRepresentationWithEntity => user !== null,\n );\n\n logger.debug(`Set up group members and children information`);\n\n const userMap = new Map(\n filteredParsedUsers.map(user => [user.username, user.entity.metadata.name]),\n );\n\n const groupMap = new Map(\n filteredParsedGroups.map(group => [group.name, group.entity.metadata.name]),\n );\n\n const groups = filteredParsedGroups.map(g => {\n const entity = g.entity;\n entity.spec.members =\n g.entity.spec.members?.flatMap(m => userMap.get(m) ?? []) ?? [];\n entity.spec.children =\n g.entity.spec.children?.flatMap(c => groupMap.get(c) ?? []) ?? [];\n entity.spec.parent = groupMap.get(entity.spec.parent);\n return entity;\n });\n\n logger.info(\n `Prepared to ingest ${parsedUsers.length} users and ${groups.length} groups into the catalog from Keycloak`,\n );\n\n return { users: filteredParsedUsers.map(u => u.entity), groups };\n};\n"],"names":["noopGroupTransformer","KEYCLOAK_ID_ANNOTATION","KEYCLOAK_REALM_ANNOTATION","noopUserTransformer","KEYCLOAK_ENTITY_QUERY_SIZE","KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT","ensureTokenValid"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"read.cjs.js","sources":["../../src/lib/read.ts"],"sourcesContent":["/*\n * Copyright 2024 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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { GroupEntity, UserEntity } from '@backstage/catalog-model';\n\nimport type KeycloakAdminClient from '@keycloak/keycloak-admin-client';\nimport type GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation';\nimport type UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation';\nimport type { Groups } from '@keycloak/keycloak-admin-client/lib/resources/groups';\nimport type { Users } from '@keycloak/keycloak-admin-client/lib/resources/users';\nimport { LimitFunction } from 'p-limit';\n\nimport { KeycloakProviderConfig } from './config';\nimport {\n KEYCLOAK_ENTITY_QUERY_SIZE,\n KEYCLOAK_ID_ANNOTATION,\n KEYCLOAK_REALM_ANNOTATION,\n KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT,\n} from './constants';\nimport { noopGroupTransformer, noopUserTransformer } from './transformers';\nimport {\n GroupRepresentationWithParent,\n GroupRepresentationWithParentAndEntity,\n GroupTransformer,\n UserRepresentationWithEntity,\n UserTransformer,\n} from './types';\nimport { ensureTokenValid } from './authenticate';\nimport { Attributes, Counter } from '@opentelemetry/api';\n\nexport const parseGroup = async (\n keycloakGroup: GroupRepresentationWithParent,\n realm: string,\n groupTransformer?: GroupTransformer,\n): Promise<GroupEntity | undefined> => {\n const transformer = groupTransformer ?? noopGroupTransformer;\n const entity: GroupEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'Group',\n metadata: {\n name: keycloakGroup.name!,\n annotations: {\n [KEYCLOAK_ID_ANNOTATION]: keycloakGroup.id!,\n [KEYCLOAK_REALM_ANNOTATION]: realm,\n },\n },\n spec: {\n type: 'group',\n profile: {\n displayName: keycloakGroup.name!,\n },\n // children, parent and members are updated again after all group and user transformers applied.\n children: keycloakGroup.subGroups?.map(g => g.name!) ?? [],\n parent: keycloakGroup.parent,\n members: keycloakGroup.members,\n },\n };\n\n return await transformer(entity, keycloakGroup, realm);\n};\n\nexport const parseUser = async (\n user: UserRepresentation,\n realm: string,\n keycloakGroups: GroupRepresentationWithParentAndEntity[],\n groupIndex: Map<string, string[]>,\n userTransformer?: UserTransformer,\n): Promise<UserEntity | undefined> => {\n const transformer = userTransformer ?? noopUserTransformer;\n const entity: UserEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'User',\n metadata: {\n name: user.username!,\n annotations: {\n [KEYCLOAK_ID_ANNOTATION]: user.id!,\n [KEYCLOAK_REALM_ANNOTATION]: realm,\n },\n },\n spec: {\n profile: {\n email: user.email,\n ...(user.firstName || user.lastName\n ? {\n displayName: [user.firstName, user.lastName]\n .filter(Boolean)\n .join(' '),\n }\n : {}),\n },\n memberOf: groupIndex.get(user.username!) ?? [],\n },\n };\n\n return await transformer(entity, user, realm, keycloakGroups);\n};\n\nexport async function getEntities<T extends Users | Groups>(\n getEntitiesFn: () => Promise<T>,\n config: KeycloakProviderConfig,\n logger: LoggerService,\n dataBatchFailureCounter: Counter<Attributes>,\n taskInstanceId: string,\n limit: LimitFunction,\n entityQuerySize: number = KEYCLOAK_ENTITY_QUERY_SIZE,\n): Promise<Awaited<ReturnType<T['find']>>> {\n const entitiesAPI = await getEntitiesFn();\n const rawEntityCount = await entitiesAPI.count({ realm: config.realm });\n const entityCount =\n typeof rawEntityCount === 'number' ? rawEntityCount : rawEntityCount.count;\n\n const pageCount = Math.ceil(entityCount / entityQuerySize);\n const brief =\n config.briefRepresentation ?? KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT;\n\n // The next line acts like range in python\n const entityPromises = Array.from({ length: pageCount }, (_, i) =>\n limit(() =>\n getEntitiesFn().then(entities => {\n return entities\n .find({\n realm: config.realm,\n max: entityQuerySize,\n first: i * entityQuerySize,\n briefRepresentation: brief,\n })\n .then(ents => {\n logger.debug(\n `Importing keycloak entities batch with index ${i} from pages: ${pageCount}`,\n );\n return ents;\n })\n .catch(err => {\n dataBatchFailureCounter.add(1, { taskInstanceId: taskInstanceId });\n logger.warn(\n `Failed to retieve Keycloak entities for taskInstanceId: ${taskInstanceId}. Error: ${err}`,\n );\n return [];\n }) as ReturnType<T['find']>;\n }),\n ),\n );\n\n const entityResults = (await Promise.all(entityPromises)).flat() as Awaited<\n ReturnType<T['find']>\n >;\n\n return entityResults;\n}\n\nasync function getAllGroupMembers<T extends Groups>(\n groupsAPI: () => Promise<T>,\n groupId: string,\n config: KeycloakProviderConfig,\n options?: { userQuerySize?: number },\n): Promise<string[]> {\n const querySize = options?.userQuerySize || 100;\n\n let allMembers: string[] = [];\n let page = 0;\n let totalMembers = 0;\n\n do {\n const groups = await groupsAPI();\n const members = await groups.listMembers({\n id: groupId,\n max: querySize,\n realm: config.realm,\n first: page * querySize,\n });\n\n if (members.length > 0) {\n allMembers = allMembers.concat(members.map(m => m.username!));\n totalMembers = members.length; // Get the number of members retrieved\n } else {\n totalMembers = 0; // No members retrieved\n }\n\n page++;\n } while (totalMembers > 0);\n\n return allMembers;\n}\n\nexport async function processGroupsRecursively(\n kcAdminClient: KeycloakAdminClient,\n config: KeycloakProviderConfig,\n logger: LoggerService,\n topLevelGroups: GroupRepresentationWithParent[],\n) {\n const allGroups: GroupRepresentationWithParent[] = [];\n const brief =\n config.briefRepresentation ?? KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT;\n\n for (const group of topLevelGroups) {\n allGroups.push(group);\n\n if (group.subGroupCount! > 0) {\n await ensureTokenValid(kcAdminClient, config, logger);\n const subgroups = await kcAdminClient.groups.listSubGroups({\n parentId: group.id!,\n first: 0,\n max: group.subGroupCount,\n briefRepresentation: brief,\n realm: config.realm,\n });\n const subGroupResults = await processGroupsRecursively(\n kcAdminClient,\n config,\n logger,\n subgroups,\n );\n allGroups.push(...subGroupResults);\n }\n }\n\n return allGroups;\n}\n\nexport function* traverseGroups(\n group: GroupRepresentation,\n): IterableIterator<GroupRepresentationWithParent> {\n yield group;\n for (const g of group.subGroups ?? []) {\n (g as GroupRepresentationWithParent).parent = group.name!;\n yield* traverseGroups(g);\n }\n}\n\nexport const readKeycloakRealm = async (\n client: KeycloakAdminClient,\n config: KeycloakProviderConfig,\n logger: LoggerService,\n limit: LimitFunction,\n taskInstanceId: string,\n dataBatchFailureCounter: Counter<Attributes>,\n options?: {\n userQuerySize?: number;\n groupQuerySize?: number;\n userTransformer?: UserTransformer;\n groupTransformer?: GroupTransformer;\n },\n): Promise<{\n users: UserEntity[];\n groups: GroupEntity[];\n}> => {\n const kUsers = await getEntities(\n async () => {\n await ensureTokenValid(client, config, logger);\n return client.users;\n },\n config,\n logger,\n dataBatchFailureCounter,\n taskInstanceId,\n limit,\n options?.userQuerySize,\n );\n logger.debug(`Fetched ${kUsers.length} users from Keycloak`);\n\n const topLevelKGroups = (await getEntities(\n async () => {\n await ensureTokenValid(client, config, logger);\n return client.groups;\n },\n config,\n logger,\n dataBatchFailureCounter,\n taskInstanceId,\n limit,\n options?.groupQuerySize,\n )) as GroupRepresentationWithParent[];\n logger.debug(`Fetched ${topLevelKGroups.length} groups from Keycloak`);\n\n let serverVersion: number;\n\n try {\n await ensureTokenValid(client, config, logger);\n const serverInfo = await client.serverInfo.find();\n serverVersion = parseInt(\n serverInfo.systemInfo?.version?.slice(0, 2) || '',\n 10,\n );\n } catch (error) {\n throw new Error(`Failed to retrieve Keycloak server information: ${error}`);\n }\n\n const isVersion23orHigher = serverVersion >= 23;\n\n let rawKGroups: GroupRepresentationWithParent[] = [];\n\n logger.debug(`Processing groups recursively`);\n if (isVersion23orHigher) {\n rawKGroups = await processGroupsRecursively(\n client,\n config,\n logger,\n topLevelKGroups,\n );\n } else {\n rawKGroups = topLevelKGroups.reduce(\n (acc, g) => acc.concat(...traverseGroups(g)),\n [] as GroupRepresentationWithParent[],\n );\n }\n\n logger.debug(`Fetching group members for keycloak groups and list subgroups`);\n const brief =\n config.briefRepresentation ?? KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT;\n\n const kGroups = await Promise.all(\n rawKGroups.map(g =>\n limit(async () => {\n g.members = await getAllGroupMembers(\n async () => {\n await ensureTokenValid(client, config, logger);\n return client.groups as Groups;\n },\n g.id!,\n config,\n options,\n );\n\n if (isVersion23orHigher) {\n if (g.subGroupCount! > 0) {\n await ensureTokenValid(client, config, logger);\n g.subGroups = await client.groups.listSubGroups({\n parentId: g.id!,\n first: 0,\n max: g.subGroupCount,\n briefRepresentation: brief,\n realm: config.realm,\n });\n }\n if (g.parentId) {\n await ensureTokenValid(client, config, logger);\n const groupParent = await client.groups.findOne({\n id: g.parentId,\n realm: config.realm,\n });\n g.parent = groupParent?.name;\n }\n }\n\n return g;\n }),\n ),\n );\n\n logger.debug(`Parsing groups`);\n const parsedGroups = await Promise.all(\n kGroups.map(async g => {\n // it is possible if fetch request failed\n if (!g) {\n return null;\n }\n const entity = await parseGroup(\n g,\n config.realm,\n options?.groupTransformer,\n );\n if (entity) {\n return { ...g, entity } as GroupRepresentationWithParentAndEntity;\n }\n return null;\n }),\n );\n const filteredParsedGroups = parsedGroups.filter(\n (group): group is GroupRepresentationWithParentAndEntity => group !== null,\n );\n\n const groupIndex = new Map<string, string[]>();\n filteredParsedGroups.forEach(group => {\n if (group.members) {\n group.members.forEach(member => {\n if (!groupIndex.has(member)) {\n groupIndex.set(member, []);\n }\n groupIndex.get(member)?.push(group.entity.metadata.name);\n });\n }\n });\n\n logger.debug('Parsing users');\n const parsedUsers = await Promise.all(\n kUsers.map(async u => {\n // it is possible if fetch request failed\n if (!u) {\n return null;\n }\n const entity = await parseUser(\n u,\n config.realm,\n filteredParsedGroups,\n groupIndex,\n options?.userTransformer,\n );\n if (entity) {\n return { ...u, entity } as UserRepresentationWithEntity;\n }\n return null;\n }),\n );\n const filteredParsedUsers = parsedUsers.filter(\n (user): user is UserRepresentationWithEntity => user !== null,\n );\n\n logger.debug(`Set up group members and children information`);\n\n const userMap = new Map(\n filteredParsedUsers.map(user => [user.username, user.entity.metadata.name]),\n );\n\n const groupMap = new Map(\n filteredParsedGroups.map(group => [group.name, group.entity.metadata.name]),\n );\n\n const groups = filteredParsedGroups.map(g => {\n const entity = g.entity;\n entity.spec.members =\n g.entity.spec.members?.flatMap(m => userMap.get(m) ?? []) ?? [];\n entity.spec.children =\n g.entity.spec.children?.flatMap(c => groupMap.get(c) ?? []) ?? [];\n entity.spec.parent = groupMap.get(entity.spec.parent);\n return entity;\n });\n\n logger.info(\n `Prepared to ingest ${parsedUsers.length} users and ${groups.length} groups into the catalog from Keycloak`,\n );\n\n return { users: filteredParsedUsers.map(u => u.entity), groups };\n};\n"],"names":["noopGroupTransformer","KEYCLOAK_ID_ANNOTATION","KEYCLOAK_REALM_ANNOTATION","noopUserTransformer","KEYCLOAK_ENTITY_QUERY_SIZE","KEYCLOAK_BRIEF_REPRESENTATION_DEFAULT","ensureTokenValid"],"mappings":"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"}
|
package/package.json
CHANGED