diff --git a/extensions/eclipse-che-theia-plugin-ext/src/browser/che-github-main.ts b/extensions/eclipse-che-theia-plugin-ext/src/browser/che-github-main.ts index 383497122..1d8e1693b 100644 --- a/extensions/eclipse-che-theia-plugin-ext/src/browser/che-github-main.ts +++ b/extensions/eclipse-che-theia-plugin-ext/src/browser/che-github-main.ts @@ -72,15 +72,21 @@ export class CheGithubMainImpl implements CheGithubMain { private async updateToken(): Promise { const oAuthProvider = 'github'; - try { + const authenticateAndUpdateToken: () => Promise = async () => { + await this.oAuthUtils.authenticate(oAuthProvider, ['repo', 'user', 'write:public_key']); this.token = await this.oAuthUtils.getToken(oAuthProvider); - // Validate the GitHub token. - await this.getUser(); - } catch (e) { - if (e.message.indexOf('Request failed with status code 401') !== -1) { - await this.oAuthUtils.authenticate(oAuthProvider, ['write:public_key']); - this.token = await this.oAuthUtils.getToken(oAuthProvider); + }; + if (await this.oAuthUtils.isAuthenticated(oAuthProvider)) { + try { + // Validate the GitHub token. + await this.getUser(); + } catch (e) { + if (/Request failed with status code 401/g.test(e.message)) { + await authenticateAndUpdateToken(); + } } + } else { + await authenticateAndUpdateToken(); } } } diff --git a/extensions/eclipse-che-theia-remote-api/src/browser/oauth-utils.ts b/extensions/eclipse-che-theia-remote-api/src/browser/oauth-utils.ts index dd81b182e..d6cc1ed4e 100644 --- a/extensions/eclipse-che-theia-remote-api/src/browser/oauth-utils.ts +++ b/extensions/eclipse-che-theia-remote-api/src/browser/oauth-utils.ts @@ -13,6 +13,7 @@ import { inject, injectable } from 'inversify'; import { EnvVariablesServer } from '@theia/core/lib/common/env-variables'; import { OAuthService } from '../common/oauth-service'; +import { UserService } from '../common/user-service'; @injectable() export class OauthUtils { @@ -27,7 +28,8 @@ export class OauthUtils { constructor( @inject(EnvVariablesServer) private readonly envVariableServer: EnvVariablesServer, - @inject(OAuthService) private readonly oAuthService: OAuthService + @inject(OAuthService) private readonly oAuthService: OAuthService, + @inject(UserService) private readonly userService: UserService ) { const onDidReceiveTokenEmitter = new Emitter(); this.onDidReceiveToken = onDidReceiveTokenEmitter.event; @@ -57,29 +59,41 @@ export class OauthUtils { } async getUserToken(): Promise { - if (this.userToken) { - return this.userToken; - } else if (this.machineToken && this.machineToken.length > 0) { - const timer = setTimeout(() => { - this.messageService.warn( - 'Authentication is taking too long, the oauth pop-up may be blocked by your browser, ' + - 'if so, allow popup windows for the current url and restart the workspace' + const updateToken: () => Promise = async () => { + if (this.machineToken && this.machineToken.length > 0) { + const timer = setTimeout(() => { + this.messageService.warn( + 'Authentication is taking too long, the OAuth pop-up may be blocked by your browser, ' + + 'if so, allow pop-up windows for the current url and restart the workspace' + ); + }, 10000); + const popup = window.open( + `${this.apiUrl.substring(0, this.apiUrl.indexOf('/api'))}/_app/oauth.html`, + 'popup', + 'toolbar=no, status=no, menubar=no, scrollbars=no, width=10, height=10, visible=none' ); - }, 10000); - const popup = window.open( - `${this.apiUrl.substring(0, this.apiUrl.indexOf('/api'))}/_app/oauth.html`, - 'popup', - 'toolbar=no, status=no, menubar=no, scrollbars=no, width=10, height=10, visible=none' - ); - if (popup) { - this.oAuthPopup = popup; - } - return new Promise(async resolve => { - this.onDidReceiveToken(() => { - clearTimeout(timer); - resolve(this.userToken); + if (popup) { + this.oAuthPopup = popup; + } + return new Promise(async resolve => { + this.onDidReceiveToken(() => { + clearTimeout(timer); + resolve(this.userToken); + }); }); - }); + } + }; + if (this.userToken) { + try { + await this.userService.getCurrentUser(this.userToken); + } catch (e) { + if (/Request getCurrentUser failed with message: "401"/g.test(e.message)) { + return updateToken(); + } + } + return this.userToken; + } else { + return updateToken(); } } @@ -105,7 +119,7 @@ export class OauthUtils { await this.oAuthService.getOAuthToken(provider, await this.getUserToken()); return true; } catch (e) { - return e.message.indexOf('Request failed with status code 401') > 0; + return new RegExp(`User \\[.*] is not associated with identity provider \\[${provider}]\\.`).test(e.message); } } diff --git a/plugins/github-auth-plugin/src/github-auth-plugin.ts b/plugins/github-auth-plugin/src/github-auth-plugin.ts index 6dfa42804..90f4fa4b0 100644 --- a/plugins/github-auth-plugin/src/github-auth-plugin.ts +++ b/plugins/github-auth-plugin/src/github-auth-plugin.ts @@ -23,6 +23,20 @@ export async function start(context: theia.PluginContext): Promise { onDidChangeSessions: onDidChangeSessions.event, getSessions: async () => sessions, login: async (scopes: string[]) => { + if (!(await che.oAuth.isRegistered('github'))) { + if ( + await theia.window.showWarningMessage( + 'Che could not authenticate to your Github account. The setup for Github OAuth provider is not complete.', + 'Setup instructions' + ) + ) { + theia.commands.executeCommand( + 'theia.open', + 'https://www.eclipse.org/che/docs/che-7/administration-guide/configuring-authorization/#configuring-github-oauth_che' + ); + } + return; + } const githubUser = await che.github.getUser(); const session = { id: v4(), @@ -49,22 +63,6 @@ export async function start(context: theia.PluginContext): Promise { } }, }); - if (theia.plugins.getPlugin('github.vscode-pull-request-github')) { - if (sessions.length > 0) { - onDidChangeSessions.fire({ added: sessions.map(s => s.id), removed: [], changed: [] }); - // TODO Remove the notification when https://github.com/eclipse-theia/theia/issues/7178 is fixed. - } else { - const signIn = 'Sign in'; - const result = await theia.window.showInformationMessage( - 'In order to use the Pull Requests functionality, you must sign in to GitHub', - signIn - ); - - if (result === signIn) { - theia.authentication.getSession('github', ['read:user', 'user:email', 'repo'], { createIfNone: true }); - } - } - } } export function stop(): void {}