From e8a924a92317ce3b6cad8425a8e069d6fe52784d Mon Sep 17 00:00:00 2001 From: Tim Urista Date: Tue, 30 Jun 2020 16:12:48 -0700 Subject: [PATCH 1/3] add gitlab sign in method --- packages/app/src/App.tsx | 5 +- .../src/layout/SignInPage/gitlabProvider.tsx | 88 +++++++++++++++++++ .../core/src/layout/SignInPage/providers.tsx | 9 +- 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 packages/core/src/layout/SignInPage/gitlabProvider.tsx diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index ccaeb2828b..3c8054d995 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -31,7 +31,10 @@ const app = createApp({ plugins: Object.values(plugins), components: { SignInPage: props => ( - + ), }, }); diff --git a/packages/core/src/layout/SignInPage/gitlabProvider.tsx b/packages/core/src/layout/SignInPage/gitlabProvider.tsx new file mode 100644 index 0000000000..790e03c230 --- /dev/null +++ b/packages/core/src/layout/SignInPage/gitlabProvider.tsx @@ -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.email, + profile: profile!, + getIdToken: () => + gitlabAuthApi.getBackstageIdentity().then(i => i!.idToken), + logout: async () => { + await gitlabAuthApi.logout(); + }, + }); + } catch (error) { + errorApi.post(error); + } + }; + + return ( + + + Sign In + + } + > + Sign In using Gitlab + + + ); +}; + +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 }; diff --git a/packages/core/src/layout/SignInPage/providers.tsx b/packages/core/src/layout/SignInPage/providers.tsx index a195b2042a..53d6b75eac 100644 --- a/packages/core/src/layout/SignInPage/providers.tsx +++ b/packages/core/src/layout/SignInPage/providers.tsx @@ -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, }; From fe8aa1547387a64a2e13568a4bd8124df7759ee3 Mon Sep 17 00:00:00 2001 From: Tim Urista Date: Mon, 6 Jul 2020 09:47:19 -0700 Subject: [PATCH 2/3] add email for backstage profile --- .../core/src/layout/SignInPage/gitlabProvider.tsx | 2 +- plugins/auth-backend/src/providers/gitlab/provider.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/core/src/layout/SignInPage/gitlabProvider.tsx b/packages/core/src/layout/SignInPage/gitlabProvider.tsx index 790e03c230..5e417cb32d 100644 --- a/packages/core/src/layout/SignInPage/gitlabProvider.tsx +++ b/packages/core/src/layout/SignInPage/gitlabProvider.tsx @@ -32,7 +32,7 @@ const Component: ProviderComponent = ({ onResult }) => { const profile = await gitlabAuthApi.getProfile(); onResult({ - userId: identity?.id || profile.email, + userId: identity!.id, profile: profile!, getIdToken: () => gitlabAuthApi.getBackstageIdentity().then(i => i!.idToken), diff --git a/plugins/auth-backend/src/providers/gitlab/provider.ts b/plugins/auth-backend/src/providers/gitlab/provider.ts index 890fbb3531..950c414750 100644 --- a/plugins/auth-backend/src/providers/gitlab/provider.ts +++ b/plugins/auth-backend/src/providers/gitlab/provider.ts @@ -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, + }, }; } From 4f7e2de43cf2074c4fa0fe08d23179bb165224e2 Mon Sep 17 00:00:00 2001 From: Tim Urista Date: Mon, 6 Jul 2020 10:01:19 -0700 Subject: [PATCH 3/3] add backstage identity in test --- plugins/auth-backend/src/providers/gitlab/provider.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/auth-backend/src/providers/gitlab/provider.test.ts b/plugins/auth-backend/src/providers/gitlab/provider.test.ts index 5eec6c47f9..d4d1de17ec 100644 --- a/plugins/auth-backend/src/providers/gitlab/provider.test.ts +++ b/plugins/auth-backend/src/providers/gitlab/provider.test.ts @@ -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',