diff --git a/.changeset/nice-beans-wait.md b/.changeset/nice-beans-wait.md new file mode 100644 index 0000000000..7cbdbc0fdf --- /dev/null +++ b/.changeset/nice-beans-wait.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-search-backend-module-techdocs': patch +'@backstage/plugin-search-backend-module-catalog': patch +'@backstage/plugin-search-backend-module-explore': patch +--- + +Migrated to support new auth services. diff --git a/plugins/search-backend-module-catalog/api-report.md b/plugins/search-backend-module-catalog/api-report.md index 6f5813ca9e..fc19ede2d4 100644 --- a/plugins/search-backend-module-catalog/api-report.md +++ b/plugins/search-backend-module-catalog/api-report.md @@ -5,6 +5,7 @@ ```ts /// +import { AuthService } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; import { Config } from '@backstage/config'; @@ -41,6 +42,7 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { // @public (undocumented) export type DefaultCatalogCollatorFactoryOptions = { + auth?: AuthService; discovery: PluginEndpointDiscovery; tokenManager: TokenManager; locationTemplate?: string; diff --git a/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.ts b/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.ts index 586346c385..166985f2d5 100644 --- a/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.ts +++ b/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.ts @@ -17,6 +17,7 @@ import { PluginEndpointDiscovery, TokenManager, + createLegacyAuthAdapters, } from '@backstage/backend-common'; import { CatalogApi, @@ -33,9 +34,11 @@ import { Readable } from 'stream'; import { CatalogCollatorEntityTransformer } from './CatalogCollatorEntityTransformer'; import { readCollatorConfigOptions } from './config'; import { defaultCatalogCollatorEntityTransformer } from './defaultCatalogCollatorEntityTransformer'; +import { AuthService } from '@backstage/backend-plugin-api'; /** @public */ export type DefaultCatalogCollatorFactoryOptions = { + auth?: AuthService; discovery: PluginEndpointDiscovery; tokenManager: TokenManager; /** @@ -71,20 +74,26 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { private filter?: GetEntitiesRequest['filter']; private batchSize: number; private readonly catalogClient: CatalogApi; - private tokenManager: TokenManager; private entityTransformer: CatalogCollatorEntityTransformer; + private auth: AuthService; static fromConfig( configRoot: Config, options: DefaultCatalogCollatorFactoryOptions, ) { const configOptions = readCollatorConfigOptions(configRoot); + const { auth: adaptedAuth } = createLegacyAuthAdapters({ + auth: options.auth, + discovery: options.discovery, + tokenManager: options.tokenManager, + }); return new DefaultCatalogCollatorFactory({ locationTemplate: options.locationTemplate ?? configOptions.locationTemplate, filter: options.filter ?? configOptions.filter, batchSize: options.batchSize ?? configOptions.batchSize, entityTransformer: options.entityTransformer, + auth: adaptedAuth, discovery: options.discovery, tokenManager: options.tokenManager, catalogClient: options.catalogClient, @@ -96,17 +105,18 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { filter: GetEntitiesRequest['filter']; batchSize: number; entityTransformer?: CatalogCollatorEntityTransformer; + auth: AuthService; discovery: PluginEndpointDiscovery; tokenManager: TokenManager; catalogClient?: CatalogApi; }) { const { + auth, batchSize, discovery, locationTemplate, filter, catalogClient, - tokenManager, entityTransformer, } = options; @@ -115,9 +125,9 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { this.batchSize = batchSize; this.catalogClient = catalogClient || new CatalogClient({ discoveryApi: discovery }); - this.tokenManager = tokenManager; this.entityTransformer = entityTransformer ?? defaultCatalogCollatorEntityTransformer; + this.auth = auth; } async getCollator(): Promise { @@ -125,7 +135,6 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { } private async *execute(): AsyncGenerator { - const { token } = await this.tokenManager.getToken(); let entitiesRetrieved = 0; let moreEntitiesToGet = true; @@ -133,6 +142,10 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { // limit (and allow some control over) memory used by the search backend // at index-time. while (moreEntitiesToGet) { + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); const entities = ( await this.catalogClient.getEntities( { diff --git a/plugins/search-backend-module-explore/api-report.md b/plugins/search-backend-module-explore/api-report.md index 50cda184a9..43788340c0 100644 --- a/plugins/search-backend-module-explore/api-report.md +++ b/plugins/search-backend-module-explore/api-report.md @@ -5,6 +5,7 @@ ```ts /// +import { AuthService } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { ExploreTool } from '@backstage/plugin-explore-common'; @@ -37,5 +38,6 @@ export type ToolDocumentCollatorFactoryOptions = { discovery: PluginEndpointDiscovery; logger: Logger; tokenManager?: TokenManager; + auth?: AuthService; }; ``` diff --git a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts index bf6f07839b..daf83ec02b 100644 --- a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts +++ b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts @@ -17,7 +17,9 @@ import { PluginEndpointDiscovery, TokenManager, + createLegacyAuthAdapters, } from '@backstage/backend-common'; +import { AuthService } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { ExploreTool } from '@backstage/plugin-explore-common'; import { @@ -44,6 +46,7 @@ export type ToolDocumentCollatorFactoryOptions = { discovery: PluginEndpointDiscovery; logger: Logger; tokenManager?: TokenManager; + auth?: AuthService; }; /** @@ -56,12 +59,13 @@ export class ToolDocumentCollatorFactory implements DocumentCollatorFactory { private readonly discovery: PluginEndpointDiscovery; private readonly logger: Logger; - private readonly tokenManager?: TokenManager; + private readonly auth: AuthService; private constructor(options: ToolDocumentCollatorFactoryOptions) { this.discovery = options.discovery; this.logger = options.logger; - this.tokenManager = options.tokenManager; + + this.auth = createLegacyAuthAdapters(options).auth; } static fromConfig( @@ -94,16 +98,13 @@ export class ToolDocumentCollatorFactory implements DocumentCollatorFactory { private async fetchTools() { const baseUrl = await this.discovery.getBaseUrl('explore'); - let headers = {}; - - if (this.tokenManager) { - const { token } = await this.tokenManager.getToken(); - headers = { - Authorization: `Bearer ${token}`, - }; - } - - const response = await fetch(`${baseUrl}/tools`, headers); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'explore', + }); + const response = await fetch(`${baseUrl}/tools`, { + headers: { Authorization: `Bearer ${token}` }, + }); if (!response.ok) { throw new Error( diff --git a/plugins/search-backend-module-techdocs/api-report.md b/plugins/search-backend-module-techdocs/api-report.md index 592cf5065a..1a8c92e5bc 100644 --- a/plugins/search-backend-module-techdocs/api-report.md +++ b/plugins/search-backend-module-techdocs/api-report.md @@ -5,10 +5,12 @@ ```ts /// +import { AuthService } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { Entity } from '@backstage/catalog-model'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { Logger } from 'winston'; import { Permission } from '@backstage/plugin-permission-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; @@ -44,6 +46,8 @@ export type TechDocsCollatorFactoryOptions = { discovery: PluginEndpointDiscovery; logger: Logger; tokenManager: TokenManager; + auth?: AuthService; + httpAuth?: HttpAuthService; locationTemplate?: string; catalogClient?: CatalogApi; parallelismLimit?: number; diff --git a/plugins/search-backend-module-techdocs/src/alpha.ts b/plugins/search-backend-module-techdocs/src/alpha.ts index e8be7cc864..f7a6bb0d36 100644 --- a/plugins/search-backend-module-techdocs/src/alpha.ts +++ b/plugins/search-backend-module-techdocs/src/alpha.ts @@ -74,6 +74,8 @@ export default createBackendModule({ deps: { config: coreServices.rootConfig, logger: coreServices.logger, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, discovery: coreServices.discovery, tokenManager: coreServices.tokenManager, scheduler: coreServices.scheduler, @@ -83,6 +85,8 @@ export default createBackendModule({ async init({ config, logger, + auth, + httpAuth, discovery, tokenManager, scheduler, @@ -106,6 +110,8 @@ export default createBackendModule({ factory: DefaultTechDocsCollatorFactory.fromConfig(config, { discovery, tokenManager, + auth, + httpAuth, logger: loggerToWinstonLogger(logger), catalogClient: catalog, entityTransformer: transformer, diff --git a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts index b76fedbdf9..1234c5c6fa 100644 --- a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts +++ b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts @@ -17,6 +17,7 @@ import { PluginEndpointDiscovery, TokenManager, + createLegacyAuthAdapters, } from '@backstage/backend-common'; import { CatalogApi, @@ -41,6 +42,7 @@ import { Readable } from 'stream'; import { Logger } from 'winston'; import { TechDocsCollatorEntityTransformer } from './TechDocsCollatorEntityTransformer'; import { defaultTechDocsCollatorEntityTransformer } from './defaultTechDocsCollatorEntityTransformer'; +import { AuthService, HttpAuthService } from '@backstage/backend-plugin-api'; interface MkSearchIndexDoc { title: string; @@ -57,6 +59,8 @@ export type TechDocsCollatorFactoryOptions = { discovery: PluginEndpointDiscovery; logger: Logger; tokenManager: TokenManager; + auth?: AuthService; + httpAuth?: HttpAuthService; locationTemplate?: string; catalogClient?: CatalogApi; parallelismLimit?: number; @@ -84,8 +88,8 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { private discovery: PluginEndpointDiscovery; private locationTemplate: string; private readonly logger: Logger; + private readonly auth: AuthService; private readonly catalogClient: CatalogApi; - private readonly tokenManager: TokenManager; private readonly parallelismLimit: number; private readonly legacyPathCasing: boolean; private entityTransformer: TechDocsCollatorEntityTransformer; @@ -100,9 +104,14 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { new CatalogClient({ discoveryApi: options.discovery }); this.parallelismLimit = options.parallelismLimit ?? 10; this.legacyPathCasing = options.legacyPathCasing ?? false; - this.tokenManager = options.tokenManager; this.entityTransformer = options.entityTransformer ?? defaultTechDocsCollatorEntityTransformer; + + this.auth = createLegacyAuthAdapters({ + auth: options.auth, + discovery: options.discovery, + tokenManager: options.tokenManager, + }).auth; } static fromConfig(config: Config, options: TechDocsCollatorFactoryOptions) { @@ -131,7 +140,7 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { private async *execute(): AsyncGenerator { const limit = pLimit(this.parallelismLimit); const techDocsBaseUrl = await this.discovery.getBaseUrl('techdocs'); - const { token } = await this.tokenManager.getToken(); + let entitiesRetrieved = 0; let moreEntitiesToGet = true; @@ -141,6 +150,11 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { // parallelism limit to simplify configuration. const batchSize = this.parallelismLimit * 50; while (moreEntitiesToGet) { + const { token: catalogToken } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); + const entities = ( await this.catalogClient.getEntities( { @@ -151,7 +165,7 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { limit: batchSize, offset: entitiesRetrieved, }, - { token }, + { token: catalogToken }, ) ).items; @@ -174,6 +188,12 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { ); try { + const { token: techdocsToken } = + await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'techdocs', + }); + const searchIndexResponse = await fetch( DefaultTechDocsCollatorFactory.constructDocsIndexUrl( techDocsBaseUrl, @@ -181,7 +201,7 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { ), { headers: { - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${techdocsToken}`, }, }, );