From 44bdcbdb66a83cae987f1d7d5fc6a48a97a65de2 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Thu, 21 Apr 2022 16:30:46 +0200 Subject: [PATCH 1/2] feat: add common sign-in resolver for simple email-to-email matching - `providers.google.resolvers.emailMatchingUserEntityEmail()` - `providers.microsoft.resolvers.emailMatchingUserEntityEmail()` - `providers.okta.resolvers.emailMatchingUserEntityEmail()` Signed-off-by: Patrick Jungermann --- .changeset/strong-mangos-sell.md | 10 ++++++++- plugins/auth-backend/api-report.md | 3 +++ .../src/providers/google/provider.ts | 9 +++++++- .../src/providers/microsoft/provider.ts | 9 +++++++- .../src/providers/okta/provider.ts | 9 +++++++- .../auth-backend/src/providers/resolvers.ts | 21 +++++++++++++++++++ 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/.changeset/strong-mangos-sell.md b/.changeset/strong-mangos-sell.md index c70a917a4d..aca074c7f3 100644 --- a/.changeset/strong-mangos-sell.md +++ b/.changeset/strong-mangos-sell.md @@ -2,7 +2,15 @@ '@backstage/plugin-auth-backend': patch --- -Add common signIn resolver to more providers. +Add more common predefined sign-in resolvers to auth providers. + +Add the existing resolver to more providers (already available at `google`): - `providers.microsoft.resolvers.emailLocalPartMatchingUserEntityName()` - `providers.okta.resolvers.emailLocalPartMatchingUserEntityName()` + +Add a new resolver for simple email-to-email matching: + +- `providers.google.resolvers.emailMatchingUserEntityEmail()` +- `providers.microsoft.resolvers.emailMatchingUserEntityEmail()` +- `providers.okta.resolvers.emailMatchingUserEntityEmail()` diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index ae02e859a1..80866bb959 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -872,6 +872,7 @@ export const providers: Readonly<{ ) => AuthProviderFactory; resolvers: Readonly<{ emailLocalPartMatchingUserEntityName: () => SignInResolver; + emailMatchingUserEntityEmail: () => SignInResolver; emailMatchingUserEntityAnnotation(): SignInResolver; }>; }>; @@ -890,6 +891,7 @@ export const providers: Readonly<{ ) => AuthProviderFactory; resolvers: Readonly<{ emailLocalPartMatchingUserEntityName: () => SignInResolver; + emailMatchingUserEntityEmail: () => SignInResolver; emailMatchingUserEntityAnnotation(): SignInResolver; }>; }>; @@ -947,6 +949,7 @@ export const providers: Readonly<{ ) => AuthProviderFactory; resolvers: Readonly<{ emailLocalPartMatchingUserEntityName: () => SignInResolver; + emailMatchingUserEntityEmail: () => SignInResolver; emailMatchingUserEntityAnnotation(): SignInResolver; }>; }>; diff --git a/plugins/auth-backend/src/providers/google/provider.ts b/plugins/auth-backend/src/providers/google/provider.ts index 68925e7817..f468a6415a 100644 --- a/plugins/auth-backend/src/providers/google/provider.ts +++ b/plugins/auth-backend/src/providers/google/provider.ts @@ -43,7 +43,10 @@ import { SignInResolver, } from '../types'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; -import { commonByEmailLocalPartResolver } from '../resolvers'; +import { + commonByEmailLocalPartResolver, + commonByEmailResolver, +} from '../resolvers'; type PrivateInfo = { refreshToken: string; @@ -248,6 +251,10 @@ export const google = createAuthProviderIntegration({ * Looks up the user by matching their email local part to the entity name. */ emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver, + /** + * Looks up the user by matching their email to the entity email. + */ + emailMatchingUserEntityEmail: () => commonByEmailResolver, /** * Looks up the user by matching their email to the `google.com/email` annotation. */ diff --git a/plugins/auth-backend/src/providers/microsoft/provider.ts b/plugins/auth-backend/src/providers/microsoft/provider.ts index cc722ad4e5..05db76fb15 100644 --- a/plugins/auth-backend/src/providers/microsoft/provider.ts +++ b/plugins/auth-backend/src/providers/microsoft/provider.ts @@ -43,7 +43,10 @@ import { AuthResolverContext, } from '../types'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; -import { commonByEmailLocalPartResolver } from '../resolvers'; +import { + commonByEmailLocalPartResolver, + commonByEmailResolver, +} from '../resolvers'; import { Logger } from 'winston'; import fetch from 'node-fetch'; @@ -275,6 +278,10 @@ export const microsoft = createAuthProviderIntegration({ * Looks up the user by matching their email local part to the entity name. */ emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver, + /** + * Looks up the user by matching their email to the entity email. + */ + emailMatchingUserEntityEmail: () => commonByEmailResolver, /** * Looks up the user by matching their email to the `microsoft.com/email` annotation. */ diff --git a/plugins/auth-backend/src/providers/okta/provider.ts b/plugins/auth-backend/src/providers/okta/provider.ts index 0516b4415d..a28be51586 100644 --- a/plugins/auth-backend/src/providers/okta/provider.ts +++ b/plugins/auth-backend/src/providers/okta/provider.ts @@ -43,7 +43,10 @@ import { AuthResolverContext, } from '../types'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; -import { commonByEmailLocalPartResolver } from '../resolvers'; +import { + commonByEmailLocalPartResolver, + commonByEmailResolver, +} from '../resolvers'; import { StateStore } from 'passport-oauth2'; type PrivateInfo = { @@ -279,6 +282,10 @@ export const okta = createAuthProviderIntegration({ * Looks up the user by matching their email local part to the entity name. */ emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver, + /** + * Looks up the user by matching their email to the entity email. + */ + emailMatchingUserEntityEmail: () => commonByEmailResolver, /** * Looks up the user by matching their email to the `okta.com/email` annotation. */ diff --git a/plugins/auth-backend/src/providers/resolvers.ts b/plugins/auth-backend/src/providers/resolvers.ts index 8a2785099f..129c29c5e4 100644 --- a/plugins/auth-backend/src/providers/resolvers.ts +++ b/plugins/auth-backend/src/providers/resolvers.ts @@ -35,3 +35,24 @@ export const commonByEmailLocalPartResolver: SignInResolver = async ( entityRef: { name: localPart }, }); }; + +/** + * A common sign-in resolver that looks up the user using their email address + * as email of the entity. + */ +export const commonByEmailResolver: SignInResolver = async ( + info, + ctx, +) => { + const { profile } = info; + + if (!profile.email) { + throw new Error('Login failed, user profile does not contain an email'); + } + + return ctx.signInWithCatalogUser({ + filter: { + 'spec.profile.email': profile.email, + }, + }); +}; From d047f48ae618e4df10ca5e51460f22ce753f7651 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 26 Apr 2022 13:41:29 +0200 Subject: [PATCH 2/2] chore: rename to emailMatchingUserEntityProfileEmail Signed-off-by: Johan Haals --- .changeset/strong-mangos-sell.md | 6 +++--- plugins/auth-backend/api-report.md | 6 +++--- plugins/auth-backend/src/providers/google/provider.ts | 2 +- plugins/auth-backend/src/providers/microsoft/provider.ts | 2 +- plugins/auth-backend/src/providers/okta/provider.ts | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.changeset/strong-mangos-sell.md b/.changeset/strong-mangos-sell.md index aca074c7f3..614d36cf52 100644 --- a/.changeset/strong-mangos-sell.md +++ b/.changeset/strong-mangos-sell.md @@ -11,6 +11,6 @@ Add the existing resolver to more providers (already available at `google`): Add a new resolver for simple email-to-email matching: -- `providers.google.resolvers.emailMatchingUserEntityEmail()` -- `providers.microsoft.resolvers.emailMatchingUserEntityEmail()` -- `providers.okta.resolvers.emailMatchingUserEntityEmail()` +- `providers.google.resolvers.emailMatchingUserEntityProfileEmail()` +- `providers.microsoft.resolvers.emailMatchingUserEntityProfileEmail()` +- `providers.okta.resolvers.emailMatchingUserEntityProfileEmail()` diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index 80866bb959..18924f7c23 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -872,7 +872,7 @@ export const providers: Readonly<{ ) => AuthProviderFactory; resolvers: Readonly<{ emailLocalPartMatchingUserEntityName: () => SignInResolver; - emailMatchingUserEntityEmail: () => SignInResolver; + emailMatchingUserEntityProfileEmail: () => SignInResolver; emailMatchingUserEntityAnnotation(): SignInResolver; }>; }>; @@ -891,7 +891,7 @@ export const providers: Readonly<{ ) => AuthProviderFactory; resolvers: Readonly<{ emailLocalPartMatchingUserEntityName: () => SignInResolver; - emailMatchingUserEntityEmail: () => SignInResolver; + emailMatchingUserEntityProfileEmail: () => SignInResolver; emailMatchingUserEntityAnnotation(): SignInResolver; }>; }>; @@ -949,7 +949,7 @@ export const providers: Readonly<{ ) => AuthProviderFactory; resolvers: Readonly<{ emailLocalPartMatchingUserEntityName: () => SignInResolver; - emailMatchingUserEntityEmail: () => SignInResolver; + emailMatchingUserEntityProfileEmail: () => SignInResolver; emailMatchingUserEntityAnnotation(): SignInResolver; }>; }>; diff --git a/plugins/auth-backend/src/providers/google/provider.ts b/plugins/auth-backend/src/providers/google/provider.ts index f468a6415a..66749c1177 100644 --- a/plugins/auth-backend/src/providers/google/provider.ts +++ b/plugins/auth-backend/src/providers/google/provider.ts @@ -254,7 +254,7 @@ export const google = createAuthProviderIntegration({ /** * Looks up the user by matching their email to the entity email. */ - emailMatchingUserEntityEmail: () => commonByEmailResolver, + emailMatchingUserEntityProfileEmail: () => commonByEmailResolver, /** * Looks up the user by matching their email to the `google.com/email` annotation. */ diff --git a/plugins/auth-backend/src/providers/microsoft/provider.ts b/plugins/auth-backend/src/providers/microsoft/provider.ts index 05db76fb15..3c1110ab5e 100644 --- a/plugins/auth-backend/src/providers/microsoft/provider.ts +++ b/plugins/auth-backend/src/providers/microsoft/provider.ts @@ -281,7 +281,7 @@ export const microsoft = createAuthProviderIntegration({ /** * Looks up the user by matching their email to the entity email. */ - emailMatchingUserEntityEmail: () => commonByEmailResolver, + emailMatchingUserEntityProfileEmail: () => commonByEmailResolver, /** * Looks up the user by matching their email to the `microsoft.com/email` annotation. */ diff --git a/plugins/auth-backend/src/providers/okta/provider.ts b/plugins/auth-backend/src/providers/okta/provider.ts index a28be51586..f208564cb6 100644 --- a/plugins/auth-backend/src/providers/okta/provider.ts +++ b/plugins/auth-backend/src/providers/okta/provider.ts @@ -285,7 +285,7 @@ export const okta = createAuthProviderIntegration({ /** * Looks up the user by matching their email to the entity email. */ - emailMatchingUserEntityEmail: () => commonByEmailResolver, + emailMatchingUserEntityProfileEmail: () => commonByEmailResolver, /** * Looks up the user by matching their email to the `okta.com/email` annotation. */