fix(auth-backend): update gitlab refresh token on refresh

Signed-off-by: Guilherme Vierno <guilhermevierno@gmail.com>
This commit is contained in:
Guilherme Vierno
2021-09-08 16:41:53 -03:00
parent 36e26fb959
commit 560d6810f0
3 changed files with 86 additions and 26 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Fix a bug preventing an access token to be refreshed a second time with the GitLab provider.
@@ -16,6 +16,7 @@
import { GitlabAuthProvider, gitlabDefaultSignInResolver } from './provider';
import * as helpers from '../../lib/passport/PassportStrategyHelper';
import { PassportProfile } from '../../lib/passport/types';
import { OAuthResult } from '../../lib/oauth';
import { getVoidLogger } from '@backstage/backend-common';
import { TokenIssuer } from '../../identity';
@@ -27,6 +28,33 @@ const mockFrameHandler = jest.spyOn(
) as unknown as jest.MockedFunction<() => Promise<{ result: OAuthResult }>>;
describe('GitlabAuthProvider', () => {
const tokenIssuer = {
issueToken: jest.fn(),
listPublicKeys: jest.fn(),
};
const catalogIdentityClient = {
findUser: jest.fn(),
};
const provider = new GitlabAuthProvider({
clientId: 'mock',
clientSecret: 'mock',
callbackUrl: 'mock',
baseUrl: 'mock',
catalogIdentityClient:
catalogIdentityClient as unknown as CatalogIdentityClient,
tokenIssuer: tokenIssuer as unknown as TokenIssuer,
authHandler: async ({ fullProfile }) => ({
profile: {
email: fullProfile.emails![0]!.value,
displayName: fullProfile.displayName,
picture: 'http://gitlab.com/lols',
},
}),
signInResolver: gitlabDefaultSignInResolver,
logger: getVoidLogger(),
});
it('should transform to type OAuthResponse', async () => {
const tests = [
{
@@ -117,36 +145,62 @@ describe('GitlabAuthProvider', () => {
},
];
const tokenIssuer = {
issueToken: jest.fn(),
listPublicKeys: jest.fn(),
};
const catalogIdentityClient = {
findUser: jest.fn(),
};
const provider = new GitlabAuthProvider({
clientId: 'mock',
clientSecret: 'mock',
callbackUrl: 'mock',
baseUrl: 'mock',
catalogIdentityClient:
catalogIdentityClient as unknown as CatalogIdentityClient,
tokenIssuer: tokenIssuer as unknown as TokenIssuer,
authHandler: async ({ fullProfile }) => ({
profile: {
email: fullProfile.emails![0]!.value,
displayName: fullProfile.displayName,
picture: 'http://gitlab.com/lols',
},
}),
signInResolver: gitlabDefaultSignInResolver,
logger: getVoidLogger(),
});
for (const test of tests) {
mockFrameHandler.mockResolvedValueOnce(test.input);
const { response } = await provider.handler({} as any);
expect(response).toEqual(test.expect);
}
});
it('should forward a new refresh token on refresh', async () => {
const mockRefreshToken = jest.spyOn(
helpers,
'executeRefreshTokenStrategy',
) as unknown as jest.MockedFunction<() => Promise<{}>>;
mockRefreshToken.mockResolvedValueOnce({
accessToken: 'a.b.c',
refreshToken: 'dont-forget-to-send-refresh',
params: {
id_token: 'my-id',
scope: 'read_user',
},
});
const mockUserProfile = jest.spyOn(
helpers,
'executeFetchUserProfileStrategy',
) as unknown as jest.MockedFunction<() => Promise<PassportProfile>>;
mockUserProfile.mockResolvedValueOnce({
id: 'uid-my-id',
username: 'mockuser',
provider: 'gitlab',
displayName: 'Mocked User',
emails: [
{
value: 'mockuser@gmail.com',
},
],
});
const response = await provider.refresh({} as any);
expect(response).toEqual({
backstageIdentity: {
id: 'mockuser',
},
profile: {
displayName: 'Mocked User',
email: 'mockuser@gmail.com',
picture: 'http://gitlab.com/lols',
},
providerInfo: {
accessToken: 'a.b.c',
idToken: 'my-id',
refreshToken: 'dont-forget-to-send-refresh',
scope: 'read_user',
},
});
});
});
@@ -177,6 +177,7 @@ export class GitlabAuthProvider implements OAuthHandlers {
providerInfo: {
idToken: result.params.id_token,
accessToken: result.accessToken,
refreshToken: result.refreshToken, // GitLab expires the old refresh token when used
scope: result.params.scope,
expiresInSeconds: result.params.expires_in,
},