From b2d67bde044a332f1db034b7ef3f0669d598211a Mon Sep 17 00:00:00 2001 From: Brian Fletcher Date: Mon, 20 Dec 2021 13:54:19 +0000 Subject: [PATCH] adds factory type for creds provider and rename default Signed-off-by: Brian Fletcher --- .../src/reading/GithubUrlReader.ts | 7 +++--- packages/integration/api-report.md | 25 +++++++++++-------- .../DefaultGithubCredentialsProvider.test.ts | 10 ++++---- ...ingleInstanceGithubCredentialsProvider.ts} | 11 ++++---- packages/integration/src/github/index.ts | 5 ++-- packages/integration/src/github/types.ts | 12 +++++++++ .../processors/GithubDiscoveryProcessor.ts | 4 +-- .../GithubMultiOrgReaderProcessor.ts | 4 +-- .../GithubOrgReaderProcessor.test.ts | 18 +++++++------ .../processors/GithubOrgReaderProcessor.ts | 4 +-- .../providers/GitHubOrgEntityProvider.test.ts | 10 +++++--- .../providers/GitHubOrgEntityProvider.ts | 4 +-- .../actions/builtin/github/OctokitProvider.ts | 4 +-- .../builtin/publish/githubPullRequest.ts | 4 +-- 14 files changed, 71 insertions(+), 51 deletions(-) rename packages/integration/src/github/{DefaultGithubCredentialsProvider.ts => SingleInstanceGithubCredentialsProvider.ts} (97%) diff --git a/packages/backend-common/src/reading/GithubUrlReader.ts b/packages/backend-common/src/reading/GithubUrlReader.ts index e6c0572ca7..6b18cfbe1a 100644 --- a/packages/backend-common/src/reading/GithubUrlReader.ts +++ b/packages/backend-common/src/reading/GithubUrlReader.ts @@ -16,7 +16,7 @@ import { getGitHubFileFetchUrl, - DefaultGithubCredentialsProvider, + SingleInstanceGithubCredentialsProvider, GithubCredentialsProvider, GitHubIntegration, ScmIntegrations, @@ -59,9 +59,8 @@ export class GithubUrlReader implements UrlReader { static factory: ReaderFactory = ({ config, treeResponseFactory }) => { const integrations = ScmIntegrations.fromConfig(config); return integrations.github.list().map(integration => { - const credentialsProvider = DefaultGithubCredentialsProvider.create( - integration.config, - ); + const credentialsProvider = + SingleInstanceGithubCredentialsProvider.create(integration.config); const reader = new GithubUrlReader(integration, { treeResponseFactory, credentialsProvider, diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md index 385d337e0d..ca24848db8 100644 --- a/packages/integration/api-report.md +++ b/packages/integration/api-report.md @@ -92,17 +92,6 @@ export type BitbucketIntegrationConfig = { appPassword?: string; }; -// @public -export class DefaultGithubCredentialsProvider - implements GithubCredentialsProvider -{ - // (undocumented) - static create( - config: GitHubIntegrationConfig, - ): DefaultGithubCredentialsProvider; - getCredentials(opts: { url: string }): Promise; -} - // @public export function defaultScmResolveUrl(options: { url: string; @@ -214,6 +203,11 @@ export interface GithubCredentialsProvider { getCredentials(opts: { url: string }): Promise; } +// @public +export type GithubCredentialsProviderFactory = ( + config: GitHubIntegrationConfig, +) => GithubCredentialsProvider; + // @public export type GithubCredentialType = 'app' | 'token'; @@ -433,6 +427,15 @@ export interface ScmIntegrationsGroup { list(): T[]; } +// @public +export class SingleInstanceGithubCredentialsProvider + implements GithubCredentialsProvider +{ + // (undocumented) + static create: GithubCredentialsProviderFactory; + getCredentials(opts: { url: string }): Promise; +} + // Warnings were encountered during analysis: // // src/gitlab/config.d.ts:29:68 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag diff --git a/packages/integration/src/github/DefaultGithubCredentialsProvider.test.ts b/packages/integration/src/github/DefaultGithubCredentialsProvider.test.ts index 4ed682aea1..6bea9647a1 100644 --- a/packages/integration/src/github/DefaultGithubCredentialsProvider.test.ts +++ b/packages/integration/src/github/DefaultGithubCredentialsProvider.test.ts @@ -31,11 +31,11 @@ jest.doMock('@octokit/rest', () => { return { Octokit }; }); -import { DefaultGithubCredentialsProvider } from './DefaultGithubCredentialsProvider'; +import { SingleInstanceGithubCredentialsProvider } from './SingleInstanceGithubCredentialsProvider'; import { RestEndpointMethodTypes } from '@octokit/rest'; import { DateTime } from 'luxon'; -const github = DefaultGithubCredentialsProvider.create({ +const github = SingleInstanceGithubCredentialsProvider.create({ host: 'github.com', apps: [ { @@ -204,7 +204,7 @@ describe('DefaultGithubCredentialsProvider tests', () => { }); it('should return the default token if no app is configured', async () => { - const githubProvider = DefaultGithubCredentialsProvider.create({ + const githubProvider = SingleInstanceGithubCredentialsProvider.create({ host: 'github.com', apps: [], token: 'fallback_token', @@ -218,7 +218,7 @@ describe('DefaultGithubCredentialsProvider tests', () => { }); it('should return the configured token if there are no installations', async () => { - const githubProvider = DefaultGithubCredentialsProvider.create({ + const githubProvider = SingleInstanceGithubCredentialsProvider.create({ host: 'github.com', apps: [ { @@ -243,7 +243,7 @@ describe('DefaultGithubCredentialsProvider tests', () => { }); it('should return undefined if no token or apps are configured', async () => { - const githubProvider = DefaultGithubCredentialsProvider.create({ + const githubProvider = SingleInstanceGithubCredentialsProvider.create({ host: 'github.com', }); diff --git a/packages/integration/src/github/DefaultGithubCredentialsProvider.ts b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts similarity index 97% rename from packages/integration/src/github/DefaultGithubCredentialsProvider.ts rename to packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts index 259fcf71a8..5b6fa39e75 100644 --- a/packages/integration/src/github/DefaultGithubCredentialsProvider.ts +++ b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts @@ -22,6 +22,7 @@ import { DateTime } from 'luxon'; import { GithubCredentials, GithubCredentialsProvider, + GithubCredentialsProviderFactory, GithubCredentialType, } from './types'; @@ -228,17 +229,15 @@ export class GithubAppCredentialsMux { * * TODO: Possibly move this to a backend only package so that it's not used in the frontend by mistake */ -export class DefaultGithubCredentialsProvider +export class SingleInstanceGithubCredentialsProvider implements GithubCredentialsProvider { - static create( - config: GitHubIntegrationConfig, - ): DefaultGithubCredentialsProvider { - return new DefaultGithubCredentialsProvider( + static create: GithubCredentialsProviderFactory = config => { + return new SingleInstanceGithubCredentialsProvider( new GithubAppCredentialsMux(config), config.token, ); - } + }; private constructor( private readonly githubAppCredentialsMux: GithubAppCredentialsMux, diff --git a/packages/integration/src/github/index.ts b/packages/integration/src/github/index.ts index 142249b0a7..fa8dfb4b86 100644 --- a/packages/integration/src/github/index.ts +++ b/packages/integration/src/github/index.ts @@ -22,11 +22,12 @@ export type { GithubAppConfig, GitHubIntegrationConfig } from './config'; export { getGitHubFileFetchUrl, getGitHubRequestOptions } from './core'; export { GithubAppCredentialsMux, - DefaultGithubCredentialsProvider, -} from './DefaultGithubCredentialsProvider'; + SingleInstanceGithubCredentialsProvider, +} from './SingleInstanceGithubCredentialsProvider'; export type { GithubCredentials, GithubCredentialsProvider, + GithubCredentialsProviderFactory, GithubCredentialType, } from './types'; export { GitHubIntegration, replaceGitHubUrlType } from './GitHubIntegration'; diff --git a/packages/integration/src/github/types.ts b/packages/integration/src/github/types.ts index 15f5375570..48609d46f0 100644 --- a/packages/integration/src/github/types.ts +++ b/packages/integration/src/github/types.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { GitHubIntegrationConfig } from './config'; + /** * The type of credentials produced by the credential provider. * @@ -41,3 +43,13 @@ export type GithubCredentials = { export interface GithubCredentialsProvider { getCredentials(opts: { url: string }): Promise; } + +/** + * This allows implementations to provide factories to create credential providers + * + * @public + * + */ +export type GithubCredentialsProviderFactory = ( + config: GitHubIntegrationConfig, +) => GithubCredentialsProvider; diff --git a/plugins/catalog-backend/src/ingestion/processors/GithubDiscoveryProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/GithubDiscoveryProcessor.ts index d2498a39d8..046455c484 100644 --- a/plugins/catalog-backend/src/ingestion/processors/GithubDiscoveryProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/GithubDiscoveryProcessor.ts @@ -17,7 +17,7 @@ import { LocationSpec } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { - DefaultGithubCredentialsProvider, + SingleInstanceGithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; import { graphql } from '@octokit/graphql'; @@ -84,7 +84,7 @@ export class GithubDiscoveryProcessor implements CatalogProcessor { // about how to handle the wild card which is special for this processor. const orgUrl = `https://${host}/${org}`; - const { headers } = await DefaultGithubCredentialsProvider.create( + const { headers } = await SingleInstanceGithubCredentialsProvider.create( gitHubConfig, ).getCredentials({ url: orgUrl }); diff --git a/plugins/catalog-backend/src/ingestion/processors/GithubMultiOrgReaderProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/GithubMultiOrgReaderProcessor.ts index ba346fa0c6..5ad735ceeb 100644 --- a/plugins/catalog-backend/src/ingestion/processors/GithubMultiOrgReaderProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/GithubMultiOrgReaderProcessor.ts @@ -18,7 +18,7 @@ import { LocationSpec } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { GithubAppCredentialsMux, - DefaultGithubCredentialsProvider, + SingleInstanceGithubCredentialsProvider, GitHubIntegrationConfig, ScmIntegrations, } from '@backstage/integration'; @@ -87,7 +87,7 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor { const allUsersMap = new Map(); const baseUrl = new URL(location.target).origin; const credentialsProvider = - DefaultGithubCredentialsProvider.create(gitHubConfig); + SingleInstanceGithubCredentialsProvider.create(gitHubConfig); const orgsToProcess = this.orgs.length ? this.orgs diff --git a/plugins/catalog-backend/src/ingestion/processors/GithubOrgReaderProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/GithubOrgReaderProcessor.test.ts index 0e1a65df93..9124637e52 100644 --- a/plugins/catalog-backend/src/ingestion/processors/GithubOrgReaderProcessor.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/GithubOrgReaderProcessor.test.ts @@ -17,7 +17,7 @@ import { getVoidLogger } from '@backstage/backend-common'; import { LocationSpec } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import { - DefaultGithubCredentialsProvider, + SingleInstanceGithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; import { graphql } from '@octokit/graphql'; @@ -87,9 +87,11 @@ describe('GithubOrgReaderProcessor', () => { (graphql.defaults as jest.Mock).mockReturnValue(mockClient); - jest.spyOn(DefaultGithubCredentialsProvider, 'create').mockReturnValue({ - getCredentials: mockGetCredentials, - } as any); + jest + .spyOn(SingleInstanceGithubCredentialsProvider, 'create') + .mockReturnValue({ + getCredentials: mockGetCredentials, + } as any); const processor = new GithubOrgReaderProcessor({ integrations, @@ -135,9 +137,11 @@ describe('GithubOrgReaderProcessor', () => { (graphql.defaults as jest.Mock).mockReturnValue(mockClient); - jest.spyOn(DefaultGithubCredentialsProvider, 'create').mockReturnValue({ - getCredentials: mockGetCredentials, - } as any); + jest + .spyOn(SingleInstanceGithubCredentialsProvider, 'create') + .mockReturnValue({ + getCredentials: mockGetCredentials, + } as any); const processor = new GithubOrgReaderProcessor({ integrations, diff --git a/plugins/catalog-backend/src/ingestion/processors/GithubOrgReaderProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/GithubOrgReaderProcessor.ts index cb455005fe..95db344818 100644 --- a/plugins/catalog-backend/src/ingestion/processors/GithubOrgReaderProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/GithubOrgReaderProcessor.ts @@ -17,7 +17,7 @@ import { LocationSpec } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { - DefaultGithubCredentialsProvider, + SingleInstanceGithubCredentialsProvider, GithubCredentialType, ScmIntegrations, } from '@backstage/integration'; @@ -108,7 +108,7 @@ export class GithubOrgReaderProcessor implements CatalogProcessor { } const credentialsProvider = - DefaultGithubCredentialsProvider.create(gitHubConfig); + SingleInstanceGithubCredentialsProvider.create(gitHubConfig); const { headers, type: tokenType } = await credentialsProvider.getCredentials({ url: orgUrl, diff --git a/plugins/catalog-backend/src/ingestion/providers/GitHubOrgEntityProvider.test.ts b/plugins/catalog-backend/src/ingestion/providers/GitHubOrgEntityProvider.test.ts index 17c0b7054b..6fde975a2b 100644 --- a/plugins/catalog-backend/src/ingestion/providers/GitHubOrgEntityProvider.test.ts +++ b/plugins/catalog-backend/src/ingestion/providers/GitHubOrgEntityProvider.test.ts @@ -17,7 +17,7 @@ import { getVoidLogger } from '@backstage/backend-common'; import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { - DefaultGithubCredentialsProvider, + SingleInstanceGithubCredentialsProvider, GitHubIntegrationConfig, } from '@backstage/integration'; import { GitHubOrgEntityProvider } from '.'; @@ -93,9 +93,11 @@ describe('GitHubOrgEntityProvider', () => { type: 'app', }); - jest.spyOn(DefaultGithubCredentialsProvider, 'create').mockReturnValue({ - getCredentials: mockGetCredentials, - } as any); + jest + .spyOn(SingleInstanceGithubCredentialsProvider, 'create') + .mockReturnValue({ + getCredentials: mockGetCredentials, + } as any); const entityProvider = new GitHubOrgEntityProvider({ id: 'my-id', diff --git a/plugins/catalog-backend/src/ingestion/providers/GitHubOrgEntityProvider.ts b/plugins/catalog-backend/src/ingestion/providers/GitHubOrgEntityProvider.ts index 63d915d817..b8059a783c 100644 --- a/plugins/catalog-backend/src/ingestion/providers/GitHubOrgEntityProvider.ts +++ b/plugins/catalog-backend/src/ingestion/providers/GitHubOrgEntityProvider.ts @@ -20,7 +20,7 @@ import { } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { - DefaultGithubCredentialsProvider, + SingleInstanceGithubCredentialsProvider, GithubCredentialsProvider, GitHubIntegrationConfig, ScmIntegrations, @@ -78,7 +78,7 @@ export class GitHubOrgEntityProvider implements EntityProvider { logger: Logger; }, ) { - this.credentialsProvider = DefaultGithubCredentialsProvider.create( + this.credentialsProvider = SingleInstanceGithubCredentialsProvider.create( options.gitHubConfig, ); } diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts index 4fbd45c0ee..9fdc6ced17 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts @@ -16,7 +16,7 @@ import { InputError } from '@backstage/errors'; import { - DefaultGithubCredentialsProvider, + SingleInstanceGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrationRegistry, } from '@backstage/integration'; @@ -41,7 +41,7 @@ export class OctokitProvider { this.integrations = integrations; this.credentialsProviders = new Map( integrations.github.list().map(integration => { - const provider = DefaultGithubCredentialsProvider.create( + const provider = SingleInstanceGithubCredentialsProvider.create( integration.config, ); return [integration.config.host, provider]; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts index 79b393a16a..299eb07f2e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts @@ -18,7 +18,7 @@ import fs from 'fs-extra'; import { parseRepoUrl, isExecutable } from './util'; import { - DefaultGithubCredentialsProvider, + SingleInstanceGithubCredentialsProvider, ScmIntegrationRegistry, } from '@backstage/integration'; import { zipObject } from 'lodash'; @@ -76,7 +76,7 @@ export const defaultClientFactory = async ({ } const credentialsProvider = - DefaultGithubCredentialsProvider.create(integrationConfig); + SingleInstanceGithubCredentialsProvider.create(integrationConfig); if (!credentialsProvider) { throw new InputError(