From a61d88b146dbdd9603930d0d30eb375d2a0f42c7 Mon Sep 17 00:00:00 2001 From: Patrick Knight Date: Tue, 7 Nov 2023 17:21:53 -0500 Subject: [PATCH] feat(backend): add the remaining auth providers (#720) * feat(backend): add the remaining auth providers * add auth providers from second list * add OIDC and SAML providers --------- Co-authored-by: Tomas Kral --- .changeset/swift-peas-act.md | 17 ++++ packages/backend/src/plugins/auth.ts | 124 +++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 .changeset/swift-peas-act.md diff --git a/.changeset/swift-peas-act.md b/.changeset/swift-peas-act.md new file mode 100644 index 000000000..2739e679f --- /dev/null +++ b/.changeset/swift-peas-act.md @@ -0,0 +1,17 @@ +--- +'backend': minor +--- + +Add the remaining Auth Providers to the showcase + +- Atlassian +- Azure Easy Auth +- Bitbucket +- Bitbucket Server +- Cloudflare Access +- GitLab +- Google IAP +- OIDC +- Okta +- OneLogin +- SAML diff --git a/packages/backend/src/plugins/auth.ts b/packages/backend/src/plugins/auth.ts index 8a7d1e006..6abbb0b67 100644 --- a/packages/backend/src/plugins/auth.ts +++ b/packages/backend/src/plugins/auth.ts @@ -53,6 +53,20 @@ async function signInWithCatalogUserOptional( function getAuthProviderFactory(providerId: string): AuthProviderFactory { switch (providerId) { + case 'atlassian': + return providers.atlassian.create({ + signIn: { + async resolver({ result: { fullProfile } }, ctx) { + const userId = fullProfile.username; + if (!userId) { + throw new Error( + 'Atlassian user profile does not contain a username', + ); + } + return await signInWithCatalogUserOptional(userId, ctx); + }, + }, + }); case `auth0`: return providers.auth0.create({ signIn: { @@ -65,6 +79,48 @@ function getAuthProviderFactory(providerId: string): AuthProviderFactory { }, }, }); + case 'azure-easyauth': + return providers.easyAuth.create({ + signIn: { + async resolver({ result: { fullProfile } }, ctx) { + const userId = fullProfile.id; + if (!userId) { + throw new Error( + 'Azure Easy Auth user profile does not contain an id', + ); + } + return await ctx.signInWithCatalogUser({ + annotations: { + 'graph.microsoft.com/user-id': userId, + }, + }); + }, + }, + }); + case 'bitbucket': + return providers.bitbucket.create({ + signIn: { + resolver: + providers.bitbucket.resolvers.usernameMatchingUserEntityAnnotation(), + }, + }); + case 'bitbucketServer': + return providers.bitbucketServer.create({ + signIn: { + resolver: + providers.bitbucketServer.resolvers.emailMatchingUserEntityProfileEmail(), + }, + }); + case 'cfaccess': + return providers.cfAccess.create({ + async authHandler({ claims }) { + return { profile: { email: claims.email } }; + }, + signIn: { + resolver: + providers.cfAccess.resolvers.emailMatchingUserEntityProfileEmail(), + }, + }); case 'github': return providers.github.create({ signIn: { @@ -79,6 +135,18 @@ function getAuthProviderFactory(providerId: string): AuthProviderFactory { }, }, }); + case 'gitlab': + return providers.gitlab.create({ + signIn: { + async resolver({ result: { fullProfile } }, ctx) { + const userId = fullProfile.id; + if (!userId) { + throw new Error(`GitLab user profile does not contain an id`); + } + return await signInWithCatalogUserOptional(userId, ctx); + }, + }, + }); case 'google': return providers.google.create({ signIn: { @@ -86,6 +154,23 @@ function getAuthProviderFactory(providerId: string): AuthProviderFactory { providers.google.resolvers.emailLocalPartMatchingUserEntityName(), }, }); + case 'gcp-iap': + return providers.gcpIap.create({ + async authHandler({ iapToken }) { + return { profile: { email: iapToken.email } }; + }, + signIn: { + async resolver({ result: { iapToken } }, ctx) { + const userId = iapToken.email.split('@')[0]; + if (!userId) { + throw new Error( + 'Google IAP user profile does not contain an email', + ); + } + return await signInWithCatalogUserOptional(userId, ctx); + }, + }, + }); case `oauth2Proxy`: return providers.oauth2Proxy.create({ signIn: { @@ -98,6 +183,39 @@ function getAuthProviderFactory(providerId: string): AuthProviderFactory { }, }, }); + case 'oidc': + return providers.oidc.create({ + signIn: { + async resolver({ result: { userinfo } }, ctx) { + const userId = userinfo.sub; + if (!userId) { + throw new Error('OIDC user does not contain a subject'); + } + return await signInWithCatalogUserOptional(userId, ctx); + }, + }, + }); + case 'okta': + return providers.okta.create({ + signIn: { + resolver: + providers.okta.resolvers.emailMatchingUserEntityAnnotation(), + }, + }); + case 'onelogin': + return providers.onelogin.create({ + signIn: { + async resolver({ result: { fullProfile } }, ctx) { + const userId = fullProfile.id; + if (!userId) { + throw new Error( + `OneLogin user profile does not contain a user id`, + ); + } + return await signInWithCatalogUserOptional(userId, ctx); + }, + }, + }); case `microsoft`: return providers.microsoft.create({ signIn: { @@ -110,6 +228,12 @@ function getAuthProviderFactory(providerId: string): AuthProviderFactory { }, }, }); + case 'saml': + return providers.saml.create({ + signIn: { + resolver: providers.saml.resolvers.nameIdMatchingUserEntityName(), + }, + }); default: throw new Error(`No auth provider found for ${providerId}`); }