From 3493c914cf96725ce0991273b5ea25827d8cde1c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 2 Apr 2024 16:05:33 +0200 Subject: [PATCH] backend-app-api: initial test for issuing limited tokens Co-authored-by: Camila Belo Signed-off-by: Patrik Oldsberg --- .../auth/authServiceFactory.test.ts | 59 ++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts index 64266db857..f987f3dea5 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts @@ -22,7 +22,7 @@ import { InternalBackstageCredentials, authServiceFactory, } from './authServiceFactory'; -import { decodeJwt } from 'jose'; +import { base64url, decodeJwt } from 'jose'; import { discoveryServiceFactory } from '../discovery'; import { BackstageServicePrincipal, @@ -129,6 +129,61 @@ describe('authServiceFactory', () => { }); it('should issue limited user tokens', async () => { - // TODO + const publicKey = [ + { + kty: 'EC', + x: 'Xd7ATJLz0085GTqYTKdl3oSZqHwcs-l1bMxrG7iFMOw', + y: 'EvFsODRaJsNWKLgknbHeCE1KxAPZL2WiSNkXB5gO1WM', + crv: 'P-256', + kid: 'b49bc495-e926-4ff9-b44f-4100e2dc069d', + alg: 'ES256', + }, + ]; + + const tester = ServiceFactoryTester.from(authServiceFactory, { + dependencies: mockDeps, + }); + + const catalogAuth = await tester.get('catalog'); + + const fullToken = + 'eyJhbGciOiJFUzI1NiIsImtpZCI6ImI0OWJjNDk1LWU5MjYtNGZmOS1iNDRmLTQxMDBlMmRjMDY5ZCJ9.eyJ0eXAiOiJ2bmQuYmFja3N0YWdlLnVzZXIiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjcwMDcvYXBpL2F1dGgiLCJzdWIiOiJ1c2VyOmRldmVsb3BtZW50L2d1ZXN0IiwiZW50IjpbInVzZXI6ZGV2ZWxvcG1lbnQvZ3Vlc3QiLCJncm91cDpkZWZhdWx0L3RlYW0tYSJdLCJhdWQiOiJiYWNrc3RhZ2UiLCJpYXQiOjE3MTIwNjQ0NzksImV4cCI6MTcxMjA2ODA3OSwidWlwIjoiMVQxR1JIcGpsdF9oRl8zM2trUFZ2QjdqM1dkWlJqcFowVHVnLXJTaXQwRHNQclJLY1V4eGU3VGVpZDhCbDhCTDE2QnRtTTRWTzJzQ0ExcjVkWUdLS2ZnIn0.5fFibx-RJVPHOvJNSCLGbUg3_sJVUMnyfN6QAq5abyKi8wtbDCCUAI9_x0Rb22KYCmBolV_cdjut-V6wQ3YmBg'; + + const credentials = await catalogAuth.authenticate(fullToken); + if (!catalogAuth.isPrincipal(credentials, 'user')) { + throw new Error('no a user principal'); + } + + const { token: limitedToken, expiresAt } = + await catalogAuth.getLimitedUserToken(credentials); + + expect(expiresAt).toEqual(new Date(1712068079 * 1000)); + + const expectedTokenHeader = base64url.encode( + JSON.stringify({ + alg: 'ES256', + kid: 'b49bc495-e926-4ff9-b44f-4100e2dc069d', + }), + ); + const expectedTokenPayload = base64url.encode( + JSON.stringify({ + typ: 'vnd.backstage.limited-user', + sub: 'user:development/guest', + ent: ['user:development/guest', 'group:default/team-a'], + iat: 1712064479, + exp: 1712068079, + }), + ); + const expectedTokenSignature = JSON.parse( + atob(fullToken.split('.')[1]), + ).uip; + + const expectedToken = `${expectedTokenHeader}.${expectedTokenPayload}.${expectedTokenSignature}`; + + expect(limitedToken).toBe(expectedToken); + + const limitedCredentials = await catalogAuth.authenticate(limitedToken, { + allowLimitedAccess: true, + }); }); });