diff --git a/plugins/auth-backend/src/authPlugin.ts b/plugins/auth-backend/src/authPlugin.ts index 8e55fccdea..f3877d48cd 100644 --- a/plugins/auth-backend/src/authPlugin.ts +++ b/plugins/auth-backend/src/authPlugin.ts @@ -24,7 +24,7 @@ import { AuthProviderFactory, authProvidersExtensionPoint, } from '@backstage/plugin-auth-node'; -import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; +import { catalogServiceRef } from '@backstage/plugin-catalog-node'; import { createRouter } from './service/router'; /** @@ -66,7 +66,7 @@ export const authPlugin = createBackendPlugin({ database: coreServices.database, discovery: coreServices.discovery, auth: coreServices.auth, - catalogApi: catalogServiceRef, + catalog: catalogServiceRef, }, async init({ httpRouter, @@ -75,7 +75,7 @@ export const authPlugin = createBackendPlugin({ database, discovery, auth, - catalogApi, + catalog, }) { const router = await createRouter({ logger, @@ -83,7 +83,7 @@ export const authPlugin = createBackendPlugin({ database, discovery, auth, - catalogApi, + catalog, providerFactories: Object.fromEntries(providers), ownershipResolver, }); diff --git a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts index b873b043aa..ddfa792fa1 100644 --- a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts +++ b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts @@ -20,15 +20,15 @@ import { } from '@backstage/catalog-model'; import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; import { CatalogIdentityClient } from './CatalogIdentityClient'; -import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { mockServices } from '@backstage/backend-test-utils'; describe('CatalogIdentityClient', () => { - const auth = mockServices.auth(); + const auth = mockServices.auth({ pluginId: 'auth' }); afterEach(() => jest.resetAllMocks()); it('findUser passes through the correct search params', async () => { - const catalogApi = catalogServiceMock({ + const catalog = catalogServiceMock({ entities: [ { apiVersion: 'backstage.io/v1beta1', @@ -42,16 +42,16 @@ describe('CatalogIdentityClient', () => { }, ], }); - jest.spyOn(catalogApi, 'getEntities'); + jest.spyOn(catalog, 'getEntities'); const client = new CatalogIdentityClient({ - catalogApi, + catalog, auth, }); await client.findUser({ annotations: { key: 'value' } }); - expect(catalogApi.getEntities).toHaveBeenCalledWith( + expect(catalog.getEntities).toHaveBeenCalledWith( { filter: { kind: 'user', @@ -59,10 +59,7 @@ describe('CatalogIdentityClient', () => { }, }, { - token: mockCredentials.service.token({ - onBehalfOf: mockCredentials.service('plugin:test'), - targetPluginId: 'catalog', - }), + credentials: await auth.getOwnServiceCredentials(), }, ); }); @@ -103,11 +100,11 @@ describe('CatalogIdentityClient', () => { ], }, ]; - const catalogApi = catalogServiceMock({ entities: mockUsers }); - jest.spyOn(catalogApi, 'getEntities'); + const catalog = catalogServiceMock({ entities: mockUsers }); + jest.spyOn(catalog, 'getEntities'); const client = new CatalogIdentityClient({ - catalogApi, + catalog, auth, }); @@ -115,7 +112,7 @@ describe('CatalogIdentityClient', () => { entityRefs: ['inigom', 'User:default/imontoya', 'User:reality/mpatinkin'], }); - expect(catalogApi.getEntities).toHaveBeenCalledWith( + expect(catalog.getEntities).toHaveBeenCalledWith( { filter: [ { @@ -136,10 +133,7 @@ describe('CatalogIdentityClient', () => { ], }, { - token: mockCredentials.service.token({ - onBehalfOf: mockCredentials.service('plugin:test'), - targetPluginId: 'catalog', - }), + credentials: await auth.getOwnServiceCredentials(), }, ); diff --git a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts index 074a402bca..bdec031e6a 100644 --- a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts +++ b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts @@ -16,7 +16,7 @@ import { AuthService, LoggerService } from '@backstage/backend-plugin-api'; import { ConflictError, NotFoundError } from '@backstage/errors'; -import { CatalogApi } from '@backstage/catalog-client'; +import { CatalogService } from '@backstage/plugin-catalog-node'; import { CompoundEntityRef, parseEntityRef, @@ -29,11 +29,11 @@ import { * A catalog client tailored for reading out identity data from the catalog. */ export class CatalogIdentityClient { - private readonly catalogApi: CatalogApi; + private readonly catalog: CatalogService; private readonly auth: AuthService; - constructor(options: { catalogApi: CatalogApi; auth: AuthService }) { - this.catalogApi = options.catalogApi; + constructor(options: { catalog: CatalogService; auth: AuthService }) { + this.catalog = options.catalog; this.auth = options.auth; } @@ -52,12 +52,10 @@ export class CatalogIdentityClient { filter[`metadata.annotations.${key}`] = value; } - const { token } = await this.auth.getPluginRequestToken({ - onBehalfOf: await this.auth.getOwnServiceCredentials(), - targetPluginId: 'catalog', - }); - - const { items } = await this.catalogApi.getEntities({ filter }, { token }); + const { items } = await this.catalog.getEntities( + { filter }, + { credentials: await this.auth.getOwnServiceCredentials() }, + ); if (items.length !== 1) { if (items.length > 1) { @@ -103,13 +101,11 @@ export class CatalogIdentityClient { 'metadata.name': ref.name, })); - const { token } = await this.auth.getPluginRequestToken({ - onBehalfOf: await this.auth.getOwnServiceCredentials(), - targetPluginId: 'catalog', - }); - - const entities = await this.catalogApi - .getEntities({ filter }, { token }) + const entities = await this.catalog + .getEntities( + { filter }, + { credentials: await this.auth.getOwnServiceCredentials() }, + ) .then(r => r.items); if (entityRefs.length !== entities.length) { diff --git a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.test.ts b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.test.ts index e79b4ee75d..4426cb7815 100644 --- a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.test.ts +++ b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.test.ts @@ -25,15 +25,16 @@ describe('CatalogAuthResolverContext', () => { jest.clearAllMocks(); }); - const catalogApi = catalogServiceMock(); - jest.spyOn(catalogApi, 'getEntities'); + const catalog = catalogServiceMock(); + jest.spyOn(catalog, 'getEntities'); it('adds kind to filter when missing', async () => { + const auth = mockServices.auth(); const context = CatalogAuthResolverContext.create({ logger: mockServices.logger.mock(), - catalogApi, + catalog, tokenIssuer: {} as TokenIssuer, - auth: mockServices.auth(), + auth, }); await expect( @@ -41,11 +42,11 @@ describe('CatalogAuthResolverContext', () => { filter: [{}, { kind: 'group' }, { KIND: 'USER' }], }), ).rejects.toThrow(NotFoundError); - expect(catalogApi.getEntities).toHaveBeenCalledWith( + expect(catalog.getEntities).toHaveBeenCalledWith( { filter: [{ kind: 'user' }, { kind: 'group' }, { KIND: 'USER' }], }, - { token: 'mock-service-token:{"sub":"plugin:test","target":"catalog"}' }, + { credentials: await auth.getOwnServiceCredentials() }, ); }); }); diff --git a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts index a27954d6c4..bbf42c70eb 100644 --- a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts +++ b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { CatalogApi } from '@backstage/catalog-client'; import { DEFAULT_NAMESPACE, Entity, @@ -24,6 +23,7 @@ import { } from '@backstage/catalog-model'; import { ConflictError, InputError, NotFoundError } from '@backstage/errors'; import { AuthService, LoggerService } from '@backstage/backend-plugin-api'; +import { CatalogService } from '@backstage/plugin-catalog-node'; import { TokenIssuer } from '../../identity/types'; import { AuthOwnershipResolver, @@ -47,13 +47,13 @@ function getDefaultOwnershipEntityRefs(entity: Entity) { export class CatalogAuthResolverContext implements AuthResolverContext { static create(options: { logger: LoggerService; - catalogApi: CatalogApi; + catalog: CatalogService; tokenIssuer: TokenIssuer; auth: AuthService; ownershipResolver?: AuthOwnershipResolver; }): CatalogAuthResolverContext { const catalogIdentityClient = new CatalogIdentityClient({ - catalogApi: options.catalogApi, + catalog: options.catalog, auth: options.auth, }); @@ -61,7 +61,7 @@ export class CatalogAuthResolverContext implements AuthResolverContext { options.logger, options.tokenIssuer, catalogIdentityClient, - options.catalogApi, + options.catalog, options.auth, options.ownershipResolver, ); @@ -71,7 +71,7 @@ export class CatalogAuthResolverContext implements AuthResolverContext { public readonly logger: LoggerService, public readonly tokenIssuer: TokenIssuer, public readonly catalogIdentityClient: CatalogIdentityClient, - private readonly catalogApi: CatalogApi, + private readonly catalog: CatalogService, private readonly auth: AuthService, private readonly ownershipResolver?: AuthOwnershipResolver, ) {} @@ -83,17 +83,15 @@ export class CatalogAuthResolverContext implements AuthResolverContext { async findCatalogUser(query: AuthResolverCatalogUserQuery) { let result: Entity[] | Entity | undefined = undefined; - const { token } = await this.auth.getPluginRequestToken({ - onBehalfOf: await this.auth.getOwnServiceCredentials(), - targetPluginId: 'catalog', - }); if ('entityRef' in query) { const entityRef = parseEntityRef(query.entityRef, { defaultKind: 'User', defaultNamespace: DEFAULT_NAMESPACE, }); - result = await this.catalogApi.getEntityByRef(entityRef, { token }); + result = await this.catalog.getEntityByRef(entityRef, { + credentials: await this.auth.getOwnServiceCredentials(), + }); } else if ('annotations' in query) { const filter: Record = { kind: 'user', @@ -101,7 +99,10 @@ export class CatalogAuthResolverContext implements AuthResolverContext { for (const [key, value] of Object.entries(query.annotations)) { filter[`metadata.annotations.${key}`] = value; } - const res = await this.catalogApi.getEntities({ filter }, { token }); + const res = await this.catalog.getEntities( + { filter }, + { credentials: await this.auth.getOwnServiceCredentials() }, + ); result = res.items; } else if ('filter' in query) { const filter = [query.filter].flat().map(value => { @@ -117,9 +118,9 @@ export class CatalogAuthResolverContext implements AuthResolverContext { } return value; }); - const res = await this.catalogApi.getEntities( + const res = await this.catalog.getEntities( { filter: filter }, - { token }, + { credentials: await this.auth.getOwnServiceCredentials() }, ); result = res.items; } else { diff --git a/plugins/auth-backend/src/providers/router.ts b/plugins/auth-backend/src/providers/router.ts index 63e37a5035..d04347e7b3 100644 --- a/plugins/auth-backend/src/providers/router.ts +++ b/plugins/auth-backend/src/providers/router.ts @@ -14,18 +14,14 @@ * limitations under the License. */ -import { - AuthService, - DiscoveryService, - LoggerService, -} from '@backstage/backend-plugin-api'; -import { CatalogApi, CatalogClient } from '@backstage/catalog-client'; +import { AuthService, LoggerService } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { assertError, NotFoundError } from '@backstage/errors'; import { AuthOwnershipResolver, AuthProviderFactory, } from '@backstage/plugin-auth-node'; +import { CatalogService } from '@backstage/plugin-catalog-node'; import express from 'express'; import Router from 'express-promise-router'; import { Minimatch } from 'minimatch'; @@ -42,11 +38,10 @@ export function bindProviderRouters( baseUrl: string; config: Config; logger: LoggerService; - discovery: DiscoveryService; auth: AuthService; tokenIssuer: TokenIssuer; ownershipResolver?: AuthOwnershipResolver; - catalogApi?: CatalogApi; + catalog: CatalogService; }, ) { const { @@ -55,10 +50,9 @@ export function bindProviderRouters( baseUrl, config, logger, - discovery, auth, tokenIssuer, - catalogApi, + catalog, ownershipResolver, } = options; @@ -84,8 +78,7 @@ export function bindProviderRouters( logger, resolverContext: CatalogAuthResolverContext.create({ logger, - catalogApi: - catalogApi ?? new CatalogClient({ discoveryApi: discovery }), + catalog, tokenIssuer, auth, ownershipResolver, diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index d58d1bc976..1952e9d648 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -25,8 +25,8 @@ import { RootConfigService, } from '@backstage/backend-plugin-api'; import { AuthOwnershipResolver } from '@backstage/plugin-auth-node'; +import { CatalogService } from '@backstage/plugin-catalog-node'; import { NotFoundError } from '@backstage/errors'; -import { CatalogApi } from '@backstage/catalog-client'; import { bindOidcRouter } from '../identity/router'; import { KeyStores } from '../identity/KeyStores'; import { TokenFactory } from '../identity/TokenFactory'; @@ -49,7 +49,7 @@ interface RouterOptions { auth: AuthService; tokenFactoryAlgorithm?: string; providerFactories?: ProviderFactories; - catalogApi?: CatalogApi; + catalog: CatalogService; ownershipResolver?: AuthOwnershipResolver; }