From 0d078740e85dbdd2f8891a7076dbb5814ffe3982 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 8 Aug 2023 11:30:49 +0200 Subject: [PATCH] auth-backend: move gcp-iap provider test Signed-off-by: Patrik Oldsberg --- .../package.json | 1 + .../src/authenticator.test.ts | 91 +++++++++++++++++++ .../src/providers/gcp-iap/provider.test.ts | 75 --------------- yarn.lock | 3 +- 4 files changed, 94 insertions(+), 76 deletions(-) create mode 100644 plugins/auth-backend-module-gcp-iap-provider/src/authenticator.test.ts delete mode 100644 plugins/auth-backend/src/providers/gcp-iap/provider.test.ts diff --git a/plugins/auth-backend-module-gcp-iap-provider/package.json b/plugins/auth-backend-module-gcp-iap-provider/package.json index 93c47f2706..9c073a6cb8 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -41,6 +41,7 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "express": "^4.18.2", "msw": "^1.0.0", "supertest": "^6.1.3" }, diff --git a/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.test.ts b/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.test.ts new file mode 100644 index 0000000000..51efbe1a04 --- /dev/null +++ b/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.test.ts @@ -0,0 +1,91 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mockServices } from '@backstage/backend-test-utils'; +import { Request } from 'express'; +import { gcpIapAuthenticator } from './authenticator'; + +beforeEach(() => { + jest.clearAllMocks(); +}); +jest.mock('./helpers', () => ({ + createTokenValidator() { + return async () => ({ sub: 's', email: 'e' }); + }, +})); + +describe('GcpIapProvider', () => { + it('should find default JWT header', async () => { + const ctx = await gcpIapAuthenticator.initialize({ + config: mockServices.rootConfig({ data: { audience: 'my-audience' } }), + }); + await expect( + gcpIapAuthenticator.authenticate( + { + req: { + header(name: string) { + return name === 'x-goog-iap-jwt-assertion' + ? 'my-token' + : undefined; + }, + } as Request, + }, + ctx, + ), + ).resolves.toEqual({ result: { iapToken: { sub: 's', email: 'e' } } }); + }); + + it('should find custom JWT header', async () => { + const jwtHeader = 'x-custom-header'; + const ctx = await gcpIapAuthenticator.initialize({ + config: mockServices.rootConfig({ + data: { audience: 'my-audience', jwtHeader }, + }), + }); + await expect( + gcpIapAuthenticator.authenticate( + { + req: { + header(name: string) { + return name === jwtHeader ? 'my-token' : undefined; + }, + } as Request, + }, + ctx, + ), + ).resolves.toEqual({ result: { iapToken: { sub: 's', email: 'e' } } }); + }); + + it('should throw if header is missing', async () => { + const ctx = await gcpIapAuthenticator.initialize({ + config: mockServices.rootConfig({ + data: { audience: 'my-audience' }, + }), + }); + await expect( + gcpIapAuthenticator.authenticate( + { + req: { + header(_name: string) { + return undefined; + }, + } as Request, + }, + ctx, + ), + ).rejects.toThrow('Missing Google IAP header'); + }); +}); diff --git a/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts b/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts deleted file mode 100644 index c01db3a853..0000000000 --- a/plugins/auth-backend/src/providers/gcp-iap/provider.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import express from 'express'; -import request from 'supertest'; -import { AuthResolverContext } from '../types'; -import { GcpIapProvider } from './provider'; -import { DEFAULT_IAP_JWT_HEADER } from './types'; - -beforeEach(() => { - jest.clearAllMocks(); -}); - -describe('GcpIapProvider', () => { - const authHandler = jest.fn(); - const signInResolver = jest.fn(); - const tokenValidator = jest.fn(); - - it.each([undefined, 'x-custom-header'])( - 'runs the happy path', - async jwtHeader => { - const provider = new GcpIapProvider({ - authHandler, - signInResolver, - tokenValidator, - resolverContext: {} as AuthResolverContext, - jwtHeader: jwtHeader, - }); - - // { "sub": "user:default/me", "ent": ["group:default/home"] } - const backstageToken = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvbWUiLCJlbnQiOlsiZ3JvdXA6ZGVmYXVsdC9ob21lIl19.CbmAKzFErGmtsnpRxyPc7dHv7WEjb5lY6206YCzR_Rc'; - const iapToken = { sub: 's', email: 'e@mail.com' }; - - authHandler.mockResolvedValueOnce({ email: 'e@mail.com' }); - signInResolver.mockResolvedValueOnce({ token: backstageToken }); - tokenValidator.mockResolvedValueOnce(iapToken); - - const app = express(); - app.use('/refresh', provider.refresh.bind(provider)); - - const header = jwtHeader || DEFAULT_IAP_JWT_HEADER; - const response = await request(app).get('/refresh').set(header, 'token'); - - expect(response.status).toBe(200); - expect(response.get('content-type')).toBe( - 'application/json; charset=utf-8', - ); - expect(response.body).toEqual({ - backstageIdentity: { - token: backstageToken, - identity: { - type: 'user', - userEntityRef: 'user:default/me', - ownershipEntityRefs: ['group:default/home'], - }, - }, - providerInfo: { iapToken }, - }); - }, - ); -}); diff --git a/yarn.lock b/yarn.lock index 986fcb0c09..2a561a603f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4586,6 +4586,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" "@backstage/types": "workspace:^" + express: ^4.18.2 google-auth-library: ^8.0.0 msw: ^1.0.0 supertest: ^6.1.3 @@ -25460,7 +25461,7 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1": +"express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1, express@npm:^4.18.2": version: 4.18.2 resolution: "express@npm:4.18.2" dependencies: