From 31d11082334e5a548b696707c294c2fcfa77d41c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 25 Sep 2020 15:44:48 +0200 Subject: [PATCH] auth-backend: look up google users in the catalog via email annotation --- .../src/providers/google/provider.ts | 48 +++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/plugins/auth-backend/src/providers/google/provider.ts b/plugins/auth-backend/src/providers/google/provider.ts index 3cc585605c..a93c964dbc 100644 --- a/plugins/auth-backend/src/providers/google/provider.ts +++ b/plugins/auth-backend/src/providers/google/provider.ts @@ -15,6 +15,7 @@ */ import express from 'express'; +import { Logger } from 'winston'; import { Strategy as GoogleStrategy } from 'passport-google-oauth20'; import { executeFrameHandlerStrategy, @@ -36,15 +37,25 @@ import { OAuthRefreshRequest, } from '../../lib/oauth'; import passport from 'passport'; +import { CatalogIdentityClient } from '../../lib/catalog'; type PrivateInfo = { refreshToken: string; }; +export type GoogleAuthProviderOptions = OAuthProviderOptions & { + logger: Logger; + identityClient: CatalogIdentityClient; +}; + export class GoogleAuthProvider implements OAuthHandlers { private readonly _strategy: GoogleStrategy; + private readonly logger: Logger; + private readonly identityClient: CatalogIdentityClient; - constructor(options: OAuthProviderOptions) { + constructor(options: GoogleAuthProviderOptions) { + this.logger = options.logger; + this.identityClient = options.identityClient; // TODO: throw error if env variables not set? this._strategy = new GoogleStrategy( { @@ -138,17 +149,44 @@ export class GoogleAuthProvider implements OAuthHandlers { throw new Error('Google profile contained no email'); } - // TODO(Rugvip): Hardcoded to the local part of the email for now - const id = profile.email.split('@')[0]; + const users = await this.identityClient.findUser({ + annotations: { + 'google.com/email': profile.email, + }, + }); + if (users.length !== 1) { + if (users.length > 1) { + this.logger.info( + `Multiple identities found for Google user ${profile.email}`, + ); + } else { + this.logger.info(`No identity found for Google user ${profile.email}`); + } - return { ...response, backstageIdentity: { id } }; + this.logger.warn( + `Falling back to allowing login based on email pattern, this will probably break in the future`, + ); + return { + ...response, + backstageIdentity: { id: profile.email.split('@')[0] }, + }; + } + + return { + ...response, + backstageIdentity: { + id: users[0].metadata.name, + }, + }; } } export const createGoogleProvider: AuthProviderFactory = ({ globalConfig, config, + logger, tokenIssuer, + discovery, }) => OAuthEnvironmentHandler.mapConfig(config, envConfig => { const providerId = 'google'; @@ -160,6 +198,8 @@ export const createGoogleProvider: AuthProviderFactory = ({ clientId, clientSecret, callbackUrl, + logger, + identityClient: new CatalogIdentityClient({ discovery }), }); return OAuthAdapter.fromConfig(globalConfig, provider, {