diff --git a/.changeset/great-rabbits-juggle.md b/.changeset/great-rabbits-juggle.md new file mode 100644 index 0000000000..afa170bfb8 --- /dev/null +++ b/.changeset/great-rabbits-juggle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-import': minor +--- + +Switched to using the `ScmAuthApi` for authentication rather than GitHub auth. If you are instantiating your `CatalogImportClient` manually you now need to pass in an instance of `ScmAuthApi` instead. Also be sure to register the `scmAuthApiRef` from the `@backstage/integration-react` in your app. diff --git a/plugins/catalog-import/api-report.md b/plugins/catalog-import/api-report.md index 4deb66e01b..9874956b5f 100644 --- a/plugins/catalog-import/api-report.md +++ b/plugins/catalog-import/api-report.md @@ -16,9 +16,9 @@ import { EntityName } from '@backstage/catalog-model'; import { FieldErrors } from 'react-hook-form'; import { IdentityApi } from '@backstage/core-plugin-api'; import { InfoCardVariants } from '@backstage/core-components'; -import { OAuthApi } from '@backstage/core-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; +import { ScmAuthApi } from '@backstage/integration-react'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { SubmitHandler } from 'react-hook-form'; import { TextFieldProps } from '@material-ui/core/TextField/TextField'; @@ -96,7 +96,7 @@ export const catalogImportApiRef: ApiRef; export class CatalogImportClient implements CatalogImportApi { constructor(options: { discoveryApi: DiscoveryApi; - githubAuthApi: OAuthApi; + scmAuthApi: ScmAuthApi; identityApi: IdentityApi; scmIntegrationsApi: ScmIntegrationRegistry; catalogApi: CatalogApi; diff --git a/plugins/catalog-import/src/api/CatalogImportClient.test.ts b/plugins/catalog-import/src/api/CatalogImportClient.test.ts index a87587c9c5..373acd4b5f 100644 --- a/plugins/catalog-import/src/api/CatalogImportClient.test.ts +++ b/plugins/catalog-import/src/api/CatalogImportClient.test.ts @@ -47,8 +47,8 @@ jest.doMock('@octokit/rest', () => { }); import { ConfigReader, UrlPatternDiscovery } from '@backstage/core-app-api'; -import { OAuthApi } from '@backstage/core-plugin-api'; import { ScmIntegrations } from '@backstage/integration'; +import { ScmAuthApi } from '@backstage/integration-react'; import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { msw } from '@backstage/test-utils'; import { Octokit } from '@octokit/rest'; @@ -63,8 +63,8 @@ describe('CatalogImportClient', () => { const mockBaseUrl = 'http://backstage:9191/api/catalog'; const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); - const githubAuthApi: jest.Mocked = { - getAccessToken: jest.fn(), + const scmAuthApi: jest.Mocked = { + getCredentials: jest.fn().mockResolvedValue({ token: 'token' }), }; const identityApi = { getUserId: () => { @@ -112,7 +112,7 @@ describe('CatalogImportClient', () => { beforeEach(() => { catalogImportClient = new CatalogImportClient({ discoveryApi, - githubAuthApi, + scmAuthApi, scmIntegrationsApi, identityApi, catalogApi, diff --git a/plugins/catalog-import/src/api/CatalogImportClient.ts b/plugins/catalog-import/src/api/CatalogImportClient.ts index c804d1193d..752899e6e8 100644 --- a/plugins/catalog-import/src/api/CatalogImportClient.ts +++ b/plugins/catalog-import/src/api/CatalogImportClient.ts @@ -20,12 +20,12 @@ import { ConfigApi, DiscoveryApi, IdentityApi, - OAuthApi, } from '@backstage/core-plugin-api'; import { GitHubIntegrationConfig, ScmIntegrationRegistry, } from '@backstage/integration'; +import { ScmAuthApi } from '@backstage/integration-react'; import { Octokit } from '@octokit/rest'; import { Base64 } from 'js-base64'; import { PartialEntity } from '../types'; @@ -36,21 +36,21 @@ import { trimEnd } from 'lodash'; export class CatalogImportClient implements CatalogImportApi { private readonly discoveryApi: DiscoveryApi; private readonly identityApi: IdentityApi; - private readonly githubAuthApi: OAuthApi; + private readonly scmAuthApi: ScmAuthApi; private readonly scmIntegrationsApi: ScmIntegrationRegistry; private readonly catalogApi: CatalogApi; private readonly configApi: ConfigApi; constructor(options: { discoveryApi: DiscoveryApi; - githubAuthApi: OAuthApi; + scmAuthApi: ScmAuthApi; identityApi: IdentityApi; scmIntegrationsApi: ScmIntegrationRegistry; catalogApi: CatalogApi; configApi: ConfigApi; }) { this.discoveryApi = options.discoveryApi; - this.githubAuthApi = options.githubAuthApi; + this.scmAuthApi = options.scmAuthApi; this.identityApi = options.identityApi; this.scmIntegrationsApi = options.scmIntegrationsApi; this.catalogApi = options.catalogApi; @@ -157,6 +157,7 @@ the component will become available.\n\nFor more information, read an \ if (ghConfig) { return await this.submitGitHubPrToRepo({ ...ghConfig, + repositoryUrl, fileContent, title, body, @@ -215,7 +216,7 @@ the component will become available.\n\nFor more information, read an \ entities: EntityName[]; }> > { - const token = await this.githubAuthApi.getAccessToken(['repo']); + const { token } = await this.scmAuthApi.getCredentials({ url }); const octo = new Octokit({ auth: token, baseUrl: githubIntegrationConfig.apiBaseUrl, @@ -270,6 +271,7 @@ the component will become available.\n\nFor more information, read an \ title, body, fileContent, + repositoryUrl, githubIntegrationConfig, }: { owner: string; @@ -277,9 +279,15 @@ the component will become available.\n\nFor more information, read an \ title: string; body: string; fileContent: string; + repositoryUrl: string; githubIntegrationConfig: GitHubIntegrationConfig; }): Promise<{ link: string; location: string }> { - const token = await this.githubAuthApi.getAccessToken(['repo']); + const { token } = await this.scmAuthApi.getCredentials({ + url: repositoryUrl, + additionalScope: { + repoWrite: true, + }, + }); const octo = new Octokit({ auth: token, diff --git a/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.test.tsx b/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.test.tsx index 57376c33f2..69ae38207d 100644 --- a/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.test.tsx +++ b/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.test.tsx @@ -55,8 +55,8 @@ describe('', () => { catalogImportApiRef, new CatalogImportClient({ discoveryApi: {} as any, - githubAuthApi: { - getAccessToken: async () => 'token', + scmAuthApi: { + getCredentials: async () => ({ token: 'token', headers: {} }), }, identityApi, scmIntegrationsApi: {} as any, diff --git a/plugins/catalog-import/src/plugin.ts b/plugins/catalog-import/src/plugin.ts index d7d6370de3..2dd90d36bc 100644 --- a/plugins/catalog-import/src/plugin.ts +++ b/plugins/catalog-import/src/plugin.ts @@ -21,10 +21,12 @@ import { createRoutableExtension, createRouteRef, discoveryApiRef, - githubAuthApiRef, identityApiRef, } from '@backstage/core-plugin-api'; -import { scmIntegrationsApiRef } from '@backstage/integration-react'; +import { + scmAuthApiRef, + scmIntegrationsApiRef, +} from '@backstage/integration-react'; import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { catalogImportApiRef, CatalogImportClient } from './api'; @@ -40,7 +42,7 @@ export const catalogImportPlugin = createPlugin({ api: catalogImportApiRef, deps: { discoveryApi: discoveryApiRef, - githubAuthApi: githubAuthApiRef, + scmAuthApi: scmAuthApiRef, identityApi: identityApiRef, scmIntegrationsApi: scmIntegrationsApiRef, catalogApi: catalogApiRef, @@ -48,7 +50,7 @@ export const catalogImportPlugin = createPlugin({ }, factory: ({ discoveryApi, - githubAuthApi, + scmAuthApi, identityApi, scmIntegrationsApi, catalogApi, @@ -56,7 +58,7 @@ export const catalogImportPlugin = createPlugin({ }) => new CatalogImportClient({ discoveryApi, - githubAuthApi, + scmAuthApi, scmIntegrationsApi, identityApi, catalogApi,