From 0fa06d9e6e79f02d63a1585f5f26df7f15146eaf Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 29 Sep 2020 11:10:37 +0200 Subject: [PATCH] auth-backend: switch client to look up single users --- .../src/lib/catalog/CatalogIdentityClient.ts | 25 +++++++++++-- .../src/providers/google/provider.ts | 35 ++++++++----------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts index b09dfaa268..2c1d66e1f8 100644 --- a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts +++ b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.ts @@ -16,7 +16,11 @@ import fetch from 'node-fetch'; import { UserEntity } from '@backstage/catalog-model'; -import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { + ConflictError, + NotFoundError, + PluginEndpointDiscovery, +} from '@backstage/backend-common'; type UserQuery = { annotations: Record; @@ -32,7 +36,12 @@ export class CatalogIdentityClient { this.discovery = options.discovery; } - async findUser(query: UserQuery): Promise { + /** + * Looks up a single user using a query. + * + * Throws a NotFoundError or ConflictError if 0 or multiple users are found. + */ + async findUser(query: UserQuery): Promise { const params = new URLSearchParams(); params.append('kind', 'User'); @@ -50,6 +59,16 @@ export class CatalogIdentityClient { ); } - return response.json(); + const users: UserEntity[] = await response.json(); + + if (users.length !== 1) { + if (users.length > 1) { + throw new ConflictError('User lookup resulted in multiple matches'); + } else { + throw new NotFoundError('User not found'); + } + } + + return users[0]; } } diff --git a/plugins/auth-backend/src/providers/google/provider.ts b/plugins/auth-backend/src/providers/google/provider.ts index a93c964dbc..80143ca201 100644 --- a/plugins/auth-backend/src/providers/google/provider.ts +++ b/plugins/auth-backend/src/providers/google/provider.ts @@ -149,35 +149,28 @@ export class GoogleAuthProvider implements OAuthHandlers { throw new Error('Google profile contained no email'); } - 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}`); - } + try { + const user = await this.identityClient.findUser({ + annotations: { + 'google.com/email': profile.email, + }, + }); + return { + ...response, + backstageIdentity: { + id: user.metadata.name, + }, + }; + } catch (error) { this.logger.warn( - `Falling back to allowing login based on email pattern, this will probably break in the future`, + `Failed to look up user, ${error}, 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, - }, - }; } }