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,
};