From 0daa328c3a5b065313760a7ef1e2eabfd0cc2e5a Mon Sep 17 00:00:00 2001 From: Alex Crome Date: Sat, 21 Jan 2023 11:41:30 +0000 Subject: [PATCH 1/2] Extract default transformers to their own file Signed-off-by: Alex Crome --- .changeset/nervous-mangos-rhyme.md | 5 + .../src/microsoftGraph/defaultTransformers.ts | 153 ++++++++++++++++++ .../src/microsoftGraph/index.ts | 4 +- .../src/microsoftGraph/read.ts | 142 +--------------- 4 files changed, 165 insertions(+), 139 deletions(-) create mode 100644 .changeset/nervous-mangos-rhyme.md create mode 100644 plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts diff --git a/.changeset/nervous-mangos-rhyme.md b/.changeset/nervous-mangos-rhyme.md new file mode 100644 index 0000000000..23e92c65a7 --- /dev/null +++ b/.changeset/nervous-mangos-rhyme.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-msgraph': patch +--- + +Extract default transformers to their own file diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts new file mode 100644 index 0000000000..9d123505e8 --- /dev/null +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts @@ -0,0 +1,153 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + MICROSOFT_EMAIL_ANNOTATION, + MICROSOFT_GRAPH_GROUP_ID_ANNOTATION, + MICROSOFT_GRAPH_TENANT_ID_ANNOTATION, + MICROSOFT_GRAPH_USER_ID_ANNOTATION, +} from './constants'; +import { normalizeEntityName } from './helper'; +import { GroupEntity, UserEntity } from '@backstage/catalog-model'; +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; + +export async function defaultOrganizationTransformer( + organization: MicrosoftGraph.Organization, +): Promise { + if (!organization.id || !organization.displayName) { + return undefined; + } + + const name = normalizeEntityName(organization.displayName!); + return { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: name, + description: organization.displayName!, + annotations: { + [MICROSOFT_GRAPH_TENANT_ID_ANNOTATION]: organization.id!, + }, + }, + spec: { + type: 'root', + profile: { + displayName: organization.displayName!, + }, + children: [], + }, + }; +} + +function extractGroupName(group: MicrosoftGraph.Group): string { + if (group.securityEnabled) { + return group.displayName as string; + } + return (group.mailNickname || group.displayName) as string; +} + +/** + * The default implementation of the transformation from a graph group entry to + * a Group entity. + * + * @public + */ +export async function defaultGroupTransformer( + group: MicrosoftGraph.Group, + groupPhoto?: string, +): Promise { + if (!group.id || !group.displayName) { + return undefined; + } + + const name = normalizeEntityName(extractGroupName(group)); + const entity: GroupEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: name, + annotations: { + [MICROSOFT_GRAPH_GROUP_ID_ANNOTATION]: group.id, + }, + }, + spec: { + type: 'team', + profile: {}, + children: [], + }, + }; + + if (group.description) { + entity.metadata.description = group.description; + } + if (group.displayName) { + entity.spec.profile!.displayName = group.displayName; + } + if (group.mail) { + entity.spec.profile!.email = group.mail; + } + if (groupPhoto) { + entity.spec.profile!.picture = groupPhoto; + } + + return entity; +} + +/** + * The default implementation of the transformation from a graph user entry to + * a User entity. + * + * @public + */ +export async function defaultUserTransformer( + user: MicrosoftGraph.User, + userPhoto?: string, +): Promise { + if (!user.id || !user.displayName || !user.mail) { + return undefined; + } + + const name = normalizeEntityName(user.mail); + const entity: UserEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name, + annotations: { + [MICROSOFT_EMAIL_ANNOTATION]: user.mail!, + [MICROSOFT_GRAPH_USER_ID_ANNOTATION]: user.id!, + }, + }, + spec: { + profile: { + displayName: user.displayName!, + email: user.mail!, + + // TODO: Additional fields? + // jobTitle: user.jobTitle || undefined, + // officeLocation: user.officeLocation || undefined, + // mobilePhone: user.mobilePhone || undefined, + }, + memberOf: [], + }, + }; + + if (userPhoto) { + entity.spec.profile!.picture = userPhoto; + } + + return entity; +} diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/index.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/index.ts index e9ab49f7d1..37dcffec22 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/index.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/index.ts @@ -29,8 +29,8 @@ export { defaultGroupTransformer, defaultOrganizationTransformer, defaultUserTransformer, - readMicrosoftGraphOrg, -} from './read'; +} from './defaultTransformers'; +export { readMicrosoftGraphOrg } from './read'; export type { GroupTransformer, OrganizationTransformer, diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts index 0ed411bfea..6699af7764 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts @@ -19,69 +19,25 @@ import { stringifyEntityRef, UserEntity, } from '@backstage/catalog-model'; -import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; import limiterFactory from 'p-limit'; import { Logger } from 'winston'; import { MicrosoftGraphClient } from './client'; import { - MICROSOFT_EMAIL_ANNOTATION, MICROSOFT_GRAPH_GROUP_ID_ANNOTATION, MICROSOFT_GRAPH_TENANT_ID_ANNOTATION, MICROSOFT_GRAPH_USER_ID_ANNOTATION, } from './constants'; -import { normalizeEntityName } from './helper'; import { buildMemberOf, buildOrgHierarchy } from './org'; import { GroupTransformer, OrganizationTransformer, UserTransformer, } from './types'; - -/** - * The default implementation of the transformation from a graph user entry to - * a User entity. - * - * @public - */ -export async function defaultUserTransformer( - user: MicrosoftGraph.User, - userPhoto?: string, -): Promise { - if (!user.id || !user.displayName || !user.mail) { - return undefined; - } - - const name = normalizeEntityName(user.mail); - const entity: UserEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'User', - metadata: { - name, - annotations: { - [MICROSOFT_EMAIL_ANNOTATION]: user.mail!, - [MICROSOFT_GRAPH_USER_ID_ANNOTATION]: user.id!, - }, - }, - spec: { - profile: { - displayName: user.displayName!, - email: user.mail!, - - // TODO: Additional fields? - // jobTitle: user.jobTitle || undefined, - // officeLocation: user.officeLocation || undefined, - // mobilePhone: user.mobilePhone || undefined, - }, - memberOf: [], - }, - }; - - if (userPhoto) { - entity.spec.profile!.picture = userPhoto; - } - - return entity; -} +import { + defaultGroupTransformer, + defaultOrganizationTransformer, + defaultUserTransformer, +} from './defaultTransformers'; export async function readMicrosoftGraphUsers( client: MicrosoftGraphClient, @@ -237,40 +193,6 @@ export async function readMicrosoftGraphUsersInGroups( return { users }; } -/** - * The default implementation of the transformation from a graph organization - * entry to a Group entity. - * - * @public - */ -export async function defaultOrganizationTransformer( - organization: MicrosoftGraph.Organization, -): Promise { - if (!organization.id || !organization.displayName) { - return undefined; - } - - const name = normalizeEntityName(organization.displayName!); - return { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Group', - metadata: { - name: name, - description: organization.displayName!, - annotations: { - [MICROSOFT_GRAPH_TENANT_ID_ANNOTATION]: organization.id!, - }, - }, - spec: { - type: 'root', - profile: { - displayName: organization.displayName!, - }, - children: [], - }, - }; -} - export async function readMicrosoftGraphOrganization( client: MicrosoftGraphClient, tenantId: string, @@ -286,60 +208,6 @@ export async function readMicrosoftGraphOrganization( return { rootGroup }; } -function extractGroupName(group: MicrosoftGraph.Group): string { - if (group.securityEnabled) { - return group.displayName as string; - } - return (group.mailNickname || group.displayName) as string; -} - -/** - * The default implementation of the transformation from a graph group entry to - * a Group entity. - * - * @public - */ -export async function defaultGroupTransformer( - group: MicrosoftGraph.Group, - groupPhoto?: string, -): Promise { - if (!group.id || !group.displayName) { - return undefined; - } - - const name = normalizeEntityName(extractGroupName(group)); - const entity: GroupEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Group', - metadata: { - name: name, - annotations: { - [MICROSOFT_GRAPH_GROUP_ID_ANNOTATION]: group.id, - }, - }, - spec: { - type: 'team', - profile: {}, - children: [], - }, - }; - - if (group.description) { - entity.metadata.description = group.description; - } - if (group.displayName) { - entity.spec.profile!.displayName = group.displayName; - } - if (group.mail) { - entity.spec.profile!.email = group.mail; - } - if (groupPhoto) { - entity.spec.profile!.picture = groupPhoto; - } - - return entity; -} - export async function readMicrosoftGraphGroups( client: MicrosoftGraphClient, tenantId: string, From 135242e78a8bbc0206e4c979ce168638d93c0bc5 Mon Sep 17 00:00:00 2001 From: Alex Crome Date: Mon, 23 Jan 2023 14:07:13 +0000 Subject: [PATCH 2/2] Added missing doc comment Signed-off-by: Alex Crome --- .../src/microsoftGraph/defaultTransformers.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts index 9d123505e8..7a8c4ec463 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts @@ -24,6 +24,12 @@ import { normalizeEntityName } from './helper'; import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +/** + * The default implementation of the transformation from a graph organization + * entry to a Group entity. + * + * @public + */ export async function defaultOrganizationTransformer( organization: MicrosoftGraph.Organization, ): Promise {