diff --git a/.changeset/old-coats-suffer.md b/.changeset/old-coats-suffer.md new file mode 100644 index 0000000000..8391f77ee0 --- /dev/null +++ b/.changeset/old-coats-suffer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': minor +--- + +Add authorization header on techdocs api requests diff --git a/plugins/techdocs/dev/api.ts b/plugins/techdocs/dev/api.ts index 7d0679f6f6..add1415526 100644 --- a/plugins/techdocs/dev/api.ts +++ b/plugins/techdocs/dev/api.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { DiscoveryApi } from '@backstage/core'; +import { DiscoveryApi, IdentityApi } from '@backstage/core'; import { Config } from '@backstage/config'; import { EntityName } from '@backstage/catalog-model'; import { TechDocsStorage } from '../src/api'; @@ -21,16 +21,20 @@ import { TechDocsStorage } from '../src/api'; export class TechDocsDevStorageApi implements TechDocsStorage { public configApi: Config; public discoveryApi: DiscoveryApi; + public identityApi: IdentityApi; constructor({ configApi, discoveryApi, + identityApi, }: { configApi: Config; discoveryApi: DiscoveryApi; + identityApi: IdentityApi; }) { this.configApi = configApi; this.discoveryApi = discoveryApi; + this.identityApi = identityApi; } async getApiOrigin() { @@ -45,9 +49,13 @@ export class TechDocsDevStorageApi implements TechDocsStorage { const apiOrigin = await this.getApiOrigin(); const url = `${apiOrigin}/${name}/${path}`; + const idToken = await this.identityApi.getIdToken(); const request = await fetch( `${url.endsWith('/') ? url : `${url}/`}index.html`, + { + headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, + }, ); if (request.status === 404) { diff --git a/plugins/techdocs/dev/index.tsx b/plugins/techdocs/dev/index.tsx index 4cf74c9622..3eefa0a814 100644 --- a/plugins/techdocs/dev/index.tsx +++ b/plugins/techdocs/dev/index.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { configApiRef, discoveryApiRef } from '@backstage/core'; +import { configApiRef, discoveryApiRef, identityApiRef } from '@backstage/core'; import { createDevApp } from '@backstage/dev-utils'; import { techdocsPlugin } from '../src/plugin'; import { TechDocsDevStorageApi } from './api'; @@ -23,11 +23,16 @@ import { techdocsStorageApiRef } from '../src'; createDevApp() .registerApi({ api: techdocsStorageApiRef, - deps: { configApi: configApiRef, discoveryApi: discoveryApiRef }, - factory: ({ configApi, discoveryApi }) => + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + identityApi: identityApiRef, + }, + factory: ({ configApi, discoveryApi, identityApi }) => new TechDocsDevStorageApi({ configApi, discoveryApi, + identityApi, }), }) .registerPlugin(techdocsPlugin) diff --git a/plugins/techdocs/src/api.ts b/plugins/techdocs/src/api.ts index 7f77be44e2..5518ab4be8 100644 --- a/plugins/techdocs/src/api.ts +++ b/plugins/techdocs/src/api.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { createApiRef, DiscoveryApi } from '@backstage/core'; +import { createApiRef, DiscoveryApi, IdentityApi } from '@backstage/core'; import { Config } from '@backstage/config'; import { EntityName } from '@backstage/catalog-model'; import { TechDocsMetadata } from './types'; @@ -51,16 +51,20 @@ export interface TechDocs { export class TechDocsApi implements TechDocs { public configApi: Config; public discoveryApi: DiscoveryApi; + public identityApi: IdentityApi; constructor({ configApi, discoveryApi, + identityApi, }: { configApi: Config; discoveryApi: DiscoveryApi; + identityApi: IdentityApi; }) { this.configApi = configApi; this.discoveryApi = discoveryApi; + this.identityApi = identityApi; } async getApiOrigin() { @@ -84,8 +88,11 @@ export class TechDocsApi implements TechDocs { const apiOrigin = await this.getApiOrigin(); const requestUrl = `${apiOrigin}/metadata/techdocs/${namespace}/${kind}/${name}`; + const idToken = await this.identityApi.getIdToken(); - const request = await fetch(`${requestUrl}`); + const request = await fetch(`${requestUrl}`, { + headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, + }); const res = await request.json(); return res; @@ -104,8 +111,11 @@ export class TechDocsApi implements TechDocs { const apiOrigin = await this.getApiOrigin(); const requestUrl = `${apiOrigin}/metadata/entity/${namespace}/${kind}/${name}`; + const idToken = await this.identityApi.getIdToken(); - const request = await fetch(`${requestUrl}`); + const request = await fetch(`${requestUrl}`, { + headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, + }); const res = await request.json(); return res; @@ -120,16 +130,20 @@ export class TechDocsApi implements TechDocs { export class TechDocsStorageApi implements TechDocsStorage { public configApi: Config; public discoveryApi: DiscoveryApi; + public identityApi: IdentityApi; constructor({ configApi, discoveryApi, + identityApi, }: { configApi: Config; discoveryApi: DiscoveryApi; + identityApi: IdentityApi; }) { this.configApi = configApi; this.discoveryApi = discoveryApi; + this.identityApi = identityApi; } async getApiOrigin() { @@ -152,9 +166,13 @@ export class TechDocsStorageApi implements TechDocsStorage { const apiOrigin = await this.getApiOrigin(); const url = `${apiOrigin}/docs/${namespace}/${kind}/${name}/${path}`; + const idToken = await this.identityApi.getIdToken(); const request = await fetch( `${url.endsWith('/') ? url : `${url}/`}index.html`, + { + headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, + }, ); let errorMessage = ''; diff --git a/plugins/techdocs/src/plugin.ts b/plugins/techdocs/src/plugin.ts index 0b4063c237..a945ca1494 100644 --- a/plugins/techdocs/src/plugin.ts +++ b/plugins/techdocs/src/plugin.ts @@ -35,6 +35,7 @@ import { createApiFactory, configApiRef, discoveryApiRef, + identityApiRef, createRoutableExtension, } from '@backstage/core'; import { @@ -64,20 +65,30 @@ export const techdocsPlugin = createPlugin({ apis: [ createApiFactory({ api: techdocsStorageApiRef, - deps: { configApi: configApiRef, discoveryApi: discoveryApiRef }, - factory: ({ configApi, discoveryApi }) => + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + identityApi: identityApiRef, + }, + factory: ({ configApi, discoveryApi, identityApi }) => new TechDocsStorageApi({ configApi, discoveryApi, + identityApi, }), }), createApiFactory({ api: techdocsApiRef, - deps: { configApi: configApiRef, discoveryApi: discoveryApiRef }, - factory: ({ configApi, discoveryApi }) => + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + identityApi: identityApiRef, + }, + factory: ({ configApi, discoveryApi, identityApi }) => new TechDocsApi({ configApi, discoveryApi, + identityApi, }), }), ],