Skip to content

Commit 5a69f7b

Browse files
authored
fix(api-gateway): Make securityContext available to extendContext, thanks @morford-brex (#10050)
1 parent ab0cdbe commit 5a69f7b

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

packages/cubejs-api-gateway/src/gateway.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,6 +2169,8 @@ class ApiGateway {
21692169
}
21702170

21712171
public async contextByReq(req: Request, securityContext, requestId: string): Promise<ExtendedRequestContext> {
2172+
req.securityContext = securityContext;
2173+
21722174
const extensions = typeof this.extendContext === 'function' ? await this.extendContext(req) : {};
21732175

21742176
return {

packages/cubejs-api-gateway/test/auth.test.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,4 +673,111 @@ describe('test authorization', () => {
673673
// no warnings, done on checkAuth/checkAuthMiddleware level
674674
expect(loggerMock.mock.calls.length).toEqual(0);
675675
});
676+
677+
test('extendContext receives securityContext from checkAuth', async () => {
678+
const loggerMock = jest.fn(() => {
679+
//
680+
});
681+
682+
const extendContextMock = jest.fn((req) => ({
683+
securityContext: {
684+
...req.securityContext,
685+
extendedField: 'added_by_extend_context',
686+
}
687+
}));
688+
689+
const expectSecurityContext = (securityContext) => {
690+
expect(securityContext.uid).toEqual(5);
691+
expect(securityContext.extendedField).toEqual('added_by_extend_context');
692+
expect(securityContext.iat).toBeDefined();
693+
expect(securityContext.exp).toBeDefined();
694+
};
695+
696+
const handlerMock = jest.fn((req, res) => {
697+
expectSecurityContext(req.context.securityContext);
698+
res.status(200).end();
699+
});
700+
701+
const { app } = createApiGateway(handlerMock, loggerMock, {
702+
extendContext: extendContextMock,
703+
});
704+
705+
const token = generateAuthToken({ uid: 5 });
706+
707+
await request(app)
708+
.get('/test-auth-fake')
709+
.set('Authorization', `Authorization: ${token}`)
710+
.expect(200);
711+
712+
expect(handlerMock.mock.calls.length).toEqual(1);
713+
expect(extendContextMock.mock.calls.length).toEqual(1);
714+
715+
// should receive securityContext from checkAuth
716+
expect(extendContextMock.mock.calls[0][0].securityContext).toMatchObject({
717+
uid: 5,
718+
iat: expect.any(Number),
719+
exp: expect.any(Number),
720+
});
721+
expectSecurityContext(handlerMock.mock.calls[0][0].context.securityContext);
722+
});
723+
724+
test('extendContext with custom checkAuth returning securityContext', async () => {
725+
const loggerMock = jest.fn(() => {
726+
//
727+
});
728+
729+
const checkAuthMock = jest.fn(async (req: Request, auth?: string) => {
730+
if (auth) {
731+
const decoded = jwt.verify(auth, 'secret') as any;
732+
return {
733+
security_context: {
734+
...decoded,
735+
tenantId: 'tenant_123',
736+
customField: 'from_check_auth',
737+
}
738+
};
739+
}
740+
return {};
741+
});
742+
743+
const extendContextMock = jest.fn((req) => {
744+
// should receive securityContext from checkAuth
745+
expect(req.securityContext).toBeDefined();
746+
expect(req.securityContext.customField).toEqual('from_check_auth');
747+
748+
return {
749+
securityContext: {
750+
...req.securityContext,
751+
extendedField: 'from_extend_context',
752+
}
753+
};
754+
});
755+
756+
const handlerMock = jest.fn((req, res) => {
757+
expect(req.context.securityContext.customField).toEqual('from_check_auth');
758+
expect(req.context.securityContext.extendedField).toEqual('from_extend_context');
759+
res.status(200).end();
760+
});
761+
762+
const { app } = createApiGateway(handlerMock, loggerMock, {
763+
checkAuth: checkAuthMock,
764+
extendContext: extendContextMock,
765+
});
766+
767+
const token = generateAuthToken({ uid: 5 });
768+
769+
await request(app)
770+
.get('/test-auth-fake')
771+
.set('Authorization', `Authorization: ${token}`)
772+
.expect(200);
773+
774+
expect(checkAuthMock.mock.calls.length).toEqual(1);
775+
expect(extendContextMock.mock.calls.length).toEqual(1);
776+
expect(handlerMock.mock.calls.length).toEqual(1);
777+
expect(extendContextMock.mock.calls[0][0].securityContext).toMatchObject({
778+
uid: 5,
779+
tenantId: 'tenant_123',
780+
customField: 'from_check_auth',
781+
});
782+
});
676783
});

0 commit comments

Comments
 (0)