Merge pull request #1500 from timurista/timurista

Add gitlab sign in method #343
This commit is contained in:
Patrik Oldsberg
2020-07-06 19:21:44 +02:00
committed by GitHub
5 changed files with 117 additions and 2 deletions
+4 -1
View File
@@ -31,7 +31,10 @@ const app = createApp({
plugins: Object.values(plugins),
components: {
SignInPage: props => (
<SignInPage {...props} providers={['guest', 'google', 'custom', 'okta']} />
<SignInPage
{...props}
providers={['guest', 'google', 'custom', 'okta', 'gitlab']}
/>
),
},
});
@@ -0,0 +1,88 @@
/*
* Copyright 2020 Spotify AB
*
* 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 React from 'react';
import { Grid, Typography, Button } from '@material-ui/core';
import { InfoCard } from '../InfoCard/InfoCard';
import { ProviderComponent, ProviderLoader, SignInProvider } from './types';
import { useApi, gitlabAuthApiRef, errorApiRef } from '@backstage/core-api';
const Component: ProviderComponent = ({ onResult }) => {
const gitlabAuthApi = useApi(gitlabAuthApiRef);
const errorApi = useApi(errorApiRef);
const handleLogin = async () => {
try {
const identity = await gitlabAuthApi.getBackstageIdentity({
instantPopup: true,
});
const profile = await gitlabAuthApi.getProfile();
onResult({
userId: identity!.id,
profile: profile!,
getIdToken: () =>
gitlabAuthApi.getBackstageIdentity().then(i => i!.idToken),
logout: async () => {
await gitlabAuthApi.logout();
},
});
} catch (error) {
errorApi.post(error);
}
};
return (
<Grid item>
<InfoCard
title="Gitlab"
actions={
<Button color="primary" variant="outlined" onClick={handleLogin}>
Sign In
</Button>
}
>
<Typography variant="body1">Sign In using Gitlab</Typography>
</InfoCard>
</Grid>
);
};
const loader: ProviderLoader = async apis => {
const gitlabAuthApi = apis.get(gitlabAuthApiRef)!;
const identity = await gitlabAuthApi.getBackstageIdentity({
optional: true,
});
if (!identity) {
return undefined;
}
const profile = await gitlabAuthApi.getProfile();
return {
userId: identity.id,
profile: profile!,
getIdToken: () =>
gitlabAuthApi.getBackstageIdentity().then(i => i!.idToken),
logout: async () => {
await gitlabAuthApi.logout();
},
};
};
export const gitlabProvider: SignInProvider = { Component, loader };
@@ -18,6 +18,7 @@ import React, { useLayoutEffect, useState, useMemo, useCallback } from 'react';
import { guestProvider } from './guestProvider';
import { googleProvider } from './googleProvider';
import { customProvider } from './customProvider';
import { gitlabProvider } from './gitlabProvider';
import { oktaProvider } from './oktaProvider';
import {
SignInPageProps,
@@ -31,11 +32,17 @@ import { SignInProvider } from './types';
const PROVIDER_STORAGE_KEY = '@backstage/core:SignInPage:provider';
// Separate list here to avoid exporting internal types
export type SignInProviderId = 'guest' | 'google' | 'custom' | 'okta';
export type SignInProviderId =
| 'guest'
| 'google'
| 'gitlab'
| 'custom'
| 'okta';
const signInProviders: { [id in SignInProviderId]: SignInProvider } = {
guest: guestProvider,
google: googleProvider,
gitlab: gitlabProvider,
custom: customProvider,
okta: oktaProvider,
};
@@ -41,6 +41,9 @@ describe('GitlabAuthProvider', () => {
},
},
expect: {
backstageIdentity: {
id: 'jimmymarkum',
},
providerInfo: {
accessToken: '19xasczxcm9n7gacn9jdgm19me',
expiresInSeconds: 100,
@@ -74,6 +77,9 @@ describe('GitlabAuthProvider', () => {
},
},
expect: {
backstageIdentity: {
id: 'daveboyle',
},
providerInfo: {
accessToken:
'ajakljsdoiahoawxbrouawucmbawe.awkxjemaneasdxwe.sodijxqeqwexeqwxe',
@@ -78,6 +78,14 @@ export class GitlabAuthProvider implements OAuthProviderHandlers {
idToken: params.id_token,
};
// gitlab provides an id numeric value (123)
// as a fallback
let id = passportProfile!.id;
if (profile.email) {
id = profile.email.split('@')[0];
}
if (params.expires_in) {
providerInfo.expiresInSeconds = params.expires_in;
}
@@ -87,6 +95,9 @@ export class GitlabAuthProvider implements OAuthProviderHandlers {
return {
providerInfo,
profile,
backstageIdentity: {
id,
},
};
}