From 5f26bb244e937eb6794ef4b9ccc9b9fa6007376d Mon Sep 17 00:00:00 2001 From: Alex Tugarev Date: Thu, 31 Mar 2022 11:57:34 +0000 Subject: [PATCH] [auth] fix missing updates to dynamic login providers this primarily affects self-hosted installation where the `ownerId` is about to change during the initial setup of the login/git provider. --- .../src/auth-provider-entry.spec.db.ts | 2 +- .../src/typeorm/auth-provider-entry-db-impl.ts | 8 +++++--- .../src/auth/host-context-provider-impl.ts | 17 ++++++++++------- .../server/src/auth/login-completion-handler.ts | 4 ++-- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/components/gitpod-db/src/auth-provider-entry.spec.db.ts b/components/gitpod-db/src/auth-provider-entry.spec.db.ts index 073995e218d166..c694c0368f2a7b 100644 --- a/components/gitpod-db/src/auth-provider-entry.spec.db.ts +++ b/components/gitpod-db/src/auth-provider-entry.spec.db.ts @@ -88,7 +88,7 @@ export class AuthProviderEntryDBSpec { const loadedAp = await this.db.findByHost(ap.host); expect(loadedAp, "findByHost()").to.deep.equal(ap); expect(loadedAp?.oauthRevision, "findByHost()").to.equal( - "e05ea6fab8efcaba4b3246c2b2d3931af897c3bc2c1cf075c31614f0954f9840", + "b05eb3256a101f6cbca1d8885c8ee241891582e78c567b7305f097ab3556d5f0", ); } } diff --git a/components/gitpod-db/src/typeorm/auth-provider-entry-db-impl.ts b/components/gitpod-db/src/typeorm/auth-provider-entry-db-impl.ts index e4edaa68cc55d2..7465ef651281bb 100644 --- a/components/gitpod-db/src/typeorm/auth-provider-entry-db-impl.ts +++ b/components/gitpod-db/src/typeorm/auth-provider-entry-db-impl.ts @@ -31,7 +31,7 @@ export class AuthProviderEntryDBImpl implements AuthProviderEntryDB { async storeAuthProvider(ap: AuthProviderEntry, updateOAuthRevision: boolean): Promise { const repo = await this.getAuthProviderRepo(); if (updateOAuthRevision) { - (ap.oauthRevision as any) = this.oauthContentHash(ap.oauth); + (ap.oauthRevision as any) = this.oauthContentHash(ap); } return repo.save(ap); } @@ -91,8 +91,10 @@ export class AuthProviderEntryDBImpl implements AuthProviderEntryDB { return query.getMany(); } - protected oauthContentHash(oauth: AuthProviderEntry["oauth"]): string { - const result = createHash("sha256").update(JSON.stringify(oauth)).digest("hex"); + protected oauthContentHash(entry: AuthProviderEntry): string { + const result = createHash("sha256") + .update(JSON.stringify({ oauth: entry.oauth, ownerId: entry.ownerId, status: entry.status })) + .digest("hex"); return result; } } diff --git a/components/server/src/auth/host-context-provider-impl.ts b/components/server/src/auth/host-context-provider-impl.ts index 902ad2036f950c..1d8a9202eb4850 100644 --- a/components/server/src/auth/host-context-provider-impl.ts +++ b/components/server/src/auth/host-context-provider-impl.ts @@ -82,16 +82,19 @@ export class HostContextProviderImpl implements HostContextProvider { const { host } = config; const existingContext = this.dynamicHosts.get(host); - const existingConfig = existingContext && existingContext.authProvider.params; - if (existingConfig && config.id === existingConfig.id) { - if (existingConfig.host !== config.host) { + if (existingContext) { + const existingConfig = existingContext.authProvider.params; + const sameId = config.id === existingConfig.id; + const sameHost = config.host === existingConfig.host; + if (!sameHost || !sameId) { log.warn("Ignoring host update for dynamic Auth Provider: " + host, { config, existingConfig }); continue; } - if (existingConfig.status === config.status) { - if (!!config.oauthRevision && existingConfig.oauthRevision === config.oauthRevision) { - continue; - } + const sameOwner = config.ownerId === existingConfig.ownerId; + const sameStatus = config.status === existingConfig.status; + const hasOAuthRevisionChanged = + !!config.oauthRevision && existingConfig.oauthRevision === config.oauthRevision; + if (sameOwner && sameStatus && hasOAuthRevisionChanged) { if (JSON.stringify(existingConfig.oauth) === JSON.stringify(config.oauth)) { continue; } diff --git a/components/server/src/auth/login-completion-handler.ts b/components/server/src/auth/login-completion-handler.ts index 44f375df9556ed..d3b064d8884b9f 100644 --- a/components/server/src/auth/login-completion-handler.ts +++ b/components/server/src/auth/login-completion-handler.ts @@ -105,10 +105,10 @@ export class LoginCompletionHandler { const hostCtx = this.hostContextProvider.get(hostname); if (hostCtx) { const { params: config } = hostCtx.authProvider; - const { id, verified, ownerId, builtin } = config; + const { id, verified, builtin } = config; if (!builtin && !verified) { try { - await this.authProviderService.markAsVerified({ id, ownerId }); + await this.authProviderService.markAsVerified({ id, ownerId: user.id }); } catch (error) { log.error(LogContext.from({ user }), `Failed to mark AuthProvider as verified!`, { error }); }