From 7d96f52c41cf9bca8d4ea2ab32468368c0645d40 Mon Sep 17 00:00:00 2001 From: Juan Pablo Garcia Ripa Date: Mon, 24 Mar 2025 09:08:19 +0100 Subject: [PATCH] fix some test and types Signed-off-by: Juan Pablo Garcia Ripa --- .../auth/authServiceFactory.test.ts | 103 +++++++++++++----- .../external/ExternalTokenHandler.test.ts | 9 +- .../src/entrypoints/auth/external/jwks.ts | 1 + .../src/entrypoints/auth/external/legacy.ts | 1 + .../src/entrypoints/auth/external/static.ts | 1 + .../src/entrypoints/auth/external/types.ts | 2 +- 6 files changed, 85 insertions(+), 32 deletions(-) diff --git a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts index 990668083f..51df123555 100644 --- a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts @@ -22,7 +22,6 @@ import { import { authServiceFactory, externalTokenHandlersServiceRef, - // externalTokenHandlersServiceRef, pluginTokenHandlerDecoratorServiceRef, } from './authServiceFactory'; import { base64url, decodeJwt } from 'jose'; @@ -34,7 +33,6 @@ import { PluginTokenHandler } from './plugin/PluginTokenHandler'; import { createServiceFactory } from '@backstage/backend-plugin-api'; import { AccessRestriptionsMap, TokenHandler } from './external/types'; import { Config } from '@backstage/config'; -import { x } from 'tar'; // import { ExternalTokenHandler } from './external/ExternalTokenHandler'; // import { TokenHandler } from './external/types'; @@ -65,13 +63,6 @@ const mockDeps = [ subject: 'unlimited-static-subject', }, }, - { - type: 'custom', - options: { - [`custom-config`]: 'custom-config', - foo: 'bar', - }, - }, ], }, }, @@ -472,36 +463,84 @@ describe('authServiceFactory', () => { it('should allow custom logic to be injected into the plugin token handler', async () => { const customLogic = jest.fn(); const customAddEntry = jest.fn(); + const customConfig = jest.fn(); + const deps = [ + discoveryServiceFactory, + mockServices.rootConfig.factory({ + data: { + backend: { + baseUrl: 'http://localhost', + auth: { + keys: [{ secret: 'abc' }], + externalAccess: [ + { + type: 'static', + options: { + token: 'limited-static-token', + subject: 'limited-static-subject', + }, + accessRestrictions: [ + { plugin: 'catalog', permission: 'do.it' }, + ], + }, + { + type: 'static', + options: { + token: 'unlimited-static-token', + subject: 'unlimited-static-subject', + }, + }, + { + type: 'custom', + options: { + [`custom-config`]: 'custom-config', + foo: 'bar', + }, + }, + ], + }, + }, + }, + }), + ]; + + const customHandler = new (class CustomHandler implements TokenHandler { + add(options: Config): TokenHandler { + customAddEntry(options); + return this; + } + async verifyToken(token: string): Promise< + | { + subject: string; + allAccessRestrictions?: AccessRestriptionsMap; + } + | undefined + > { + customLogic(token); + return { + subject: 'foo', + }; + } + })(); + const customPluginTokenHandler = createServiceFactory({ service: externalTokenHandlersServiceRef, deps: {}, async factory() { return { - custom: new (class CustomHandler implements TokenHandler { - add(options: Config): void { - customAddEntry(options); - } - async verifyToken(token: string): Promise< - | { - subject: string; - allAccessRestrictions?: AccessRestriptionsMap; - } - | undefined - > { - customLogic(token); - return { - subject: 'foo', - }; - } - })(), + custom: (options: Config) => { + customConfig(options); + return customHandler.add(options); + }, }; }, }); const tester = ServiceFactoryTester.from(authServiceFactory, { - dependencies: [...mockDeps, customPluginTokenHandler], + dependencies: [...deps, customPluginTokenHandler], }); const searchAuth = await tester.getSubject('search'); await searchAuth.authenticate('custom-token'); + expect(customAddEntry).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ @@ -513,6 +552,16 @@ describe('authServiceFactory', () => { }), ); expect(customLogic).toHaveBeenCalledWith('custom-token'); + expect(customConfig).toHaveBeenCalledWith( + expect.objectContaining({ + data: expect.objectContaining({ + options: expect.objectContaining({ + [`custom-config`]: 'custom-config', + foo: 'bar', + }), + }), + }), + ); }); }); }); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts index de9c9e162b..3567061f03 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts @@ -228,6 +228,7 @@ describe('ExternalTokenHandler', () => { add: jest.fn(), verifyToken: jest.fn(), }; + const customHandlerCreator = jest.fn(() => customHandler); const handler = ExternalTokenHandler.create({ ownPluginId: 'catalog', @@ -253,10 +254,10 @@ describe('ExternalTokenHandler', () => { }, }, }), - externalTokenHandlers: [{ ['internal-custom']: customHandler }], + externalTokenHandlers: [{ ['internal-custom']: customHandlerCreator }], }); - expect(customHandler.add).toHaveBeenCalledWith( + expect(customHandlerCreator).toHaveBeenCalledWith( expect.objectContaining({ data: { type: 'internal-custom', @@ -340,10 +341,10 @@ describe('ExternalTokenHandler', () => { }), externalTokenHandlers: [ { - ['internal-custom']: { + ['internal-custom']: () => ({ add: jest.fn(), verifyToken: jest.fn(), - }, + }), }, ], }); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/jwks.ts b/packages/backend-defaults/src/entrypoints/auth/external/jwks.ts index d88dc62a47..32271972fb 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/jwks.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/jwks.ts @@ -68,6 +68,7 @@ export class JWKSHandler implements TokenHandler { url, allAccessRestrictions, }); + return this; } async verifyToken(token: string) { diff --git a/packages/backend-defaults/src/entrypoints/auth/external/legacy.ts b/packages/backend-defaults/src/entrypoints/auth/external/legacy.ts index 9c60e70707..fbd96aafd7 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/legacy.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/legacy.ts @@ -40,6 +40,7 @@ export class LegacyTokenHandler implements TokenHandler { config.getString('options.subject'), allAccessRestrictions, ); + return this; } // used only for the old backend.auth.keys array diff --git a/packages/backend-defaults/src/entrypoints/auth/external/static.ts b/packages/backend-defaults/src/entrypoints/auth/external/static.ts index 1e89d8c6a1..b335b89e58 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/static.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/static.ts @@ -54,6 +54,7 @@ export class StaticTokenHandler implements TokenHandler { } this.#entries.set(token, { subject, allAccessRestrictions }); + return this; } async verifyToken(token: string) { diff --git a/packages/backend-defaults/src/entrypoints/auth/external/types.ts b/packages/backend-defaults/src/entrypoints/auth/external/types.ts index 6a1fd084ed..e3cad90e17 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/types.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/types.ts @@ -23,7 +23,7 @@ export type AccessRestriptionsMap = Map< >; export interface TokenHandler { - add(options: Config): void; + add?(options: Config): TokenHandler; verifyToken(token: string): Promise< | { subject: string;