From 41c6c34e31c58da3a2e4715a0b3ffb3ce2b78339 Mon Sep 17 00:00:00 2001 From: Igor Vinokur Date: Wed, 7 Oct 2020 10:30:13 +0300 Subject: [PATCH 1/3] Register GitHub Authentication provider for the vscode Github PR plugin Signed-off-by: Igor Vinokur --- .../src/browser/che-github-main.ts | 7 +++ .../src/common/che-protocol.ts | 2 + .../src/plugin/che-api.ts | 3 + .../src/plugin/che-github.ts | 5 ++ .../src/che-proposed.d.ts | 8 +++ .../configs/root-compilation.tsconfig.json | 2 +- .../src/github-auth-plugin.ts | 62 ++++++++++++++----- 7 files changed, 73 insertions(+), 16 deletions(-) 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 1a76dbbcf..0c52c8afa 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 @@ -12,6 +12,7 @@ import { CheGithubMain } from '../common/che-protocol'; import { interfaces } from 'inversify'; import axios, { AxiosInstance } from 'axios'; import { OauthUtils } from './oauth-utils'; +import { GithubUser } from '@eclipse-che/plugin'; export class CheGithubMainImpl implements CheGithubMain { private axiosInstance: AxiosInstance = axios; @@ -39,6 +40,12 @@ export class CheGithubMainImpl implements CheGithubMain { } } + async $getUser(): Promise { + await this.fetchToken(); + const result = await this.axiosInstance.get('https://api.github.com/user?access_token=' + this.token); + return result.data; + } + private async fetchToken(): Promise { if (!this.token) { await this.updateToken(); diff --git a/extensions/eclipse-che-theia-plugin-ext/src/common/che-protocol.ts b/extensions/eclipse-che-theia-plugin-ext/src/common/che-protocol.ts index 797308167..6be942565 100644 --- a/extensions/eclipse-che-theia-plugin-ext/src/common/che-protocol.ts +++ b/extensions/eclipse-che-theia-plugin-ext/src/common/che-protocol.ts @@ -73,11 +73,13 @@ export interface CheOpenshiftMain { export interface CheGithub { uploadPublicSshKey(publicKey: string): Promise; getToken(): Promise; + getUser(): Promise; } export interface CheGithubMain { $uploadPublicSshKey(publicKey: string): Promise; $getToken(): Promise; + $getUser(): Promise; } export interface CheOauth { diff --git a/extensions/eclipse-che-theia-plugin-ext/src/plugin/che-api.ts b/extensions/eclipse-che-theia-plugin-ext/src/plugin/che-api.ts index d1b598825..dd5cfeeb9 100644 --- a/extensions/eclipse-che-theia-plugin-ext/src/plugin/che-api.ts +++ b/extensions/eclipse-che-theia-plugin-ext/src/plugin/che-api.ts @@ -134,6 +134,9 @@ export function createAPIFactory(rpc: RPCProtocol): CheApiFactory { }, getToken(): Promise { return cheGithubImpl.getToken(); + }, + getUser(): Promise { + return cheGithubImpl.getUser(); } }; diff --git a/extensions/eclipse-che-theia-plugin-ext/src/plugin/che-github.ts b/extensions/eclipse-che-theia-plugin-ext/src/plugin/che-github.ts index e5e872609..8d966a22d 100644 --- a/extensions/eclipse-che-theia-plugin-ext/src/plugin/che-github.ts +++ b/extensions/eclipse-che-theia-plugin-ext/src/plugin/che-github.ts @@ -10,6 +10,7 @@ import { RPCProtocol } from '@theia/plugin-ext/lib/common/rpc-protocol'; import { PLUGIN_RPC_CONTEXT, CheGithub, CheGithubMain } from '../common/che-protocol'; +import { GithubUser } from '@eclipse-che/plugin'; export class CheGithubImpl implements CheGithub { @@ -26,4 +27,8 @@ export class CheGithubImpl implements CheGithub { getToken(): Promise { return this.githubMain.$getToken(); } + + getUser(): Promise { + return this.githubMain.$getUser(); + } } diff --git a/extensions/eclipse-che-theia-plugin/src/che-proposed.d.ts b/extensions/eclipse-che-theia-plugin/src/che-proposed.d.ts index 9b2926c95..b21a41a3e 100644 --- a/extensions/eclipse-che-theia-plugin/src/che-proposed.d.ts +++ b/extensions/eclipse-che-theia-plugin/src/che-proposed.d.ts @@ -44,9 +44,17 @@ declare module '@eclipse-che/plugin' { export function createWorkspace(devfilePath: string): Promise; } + export interface GithubUser { + login: string, + id: number, + name: string, + email: string + } + export namespace github { export function uploadPublicSshKey(publicKey: string): Promise; export function getToken(): Promise; + export function getUser(): Promise; } export namespace openshift { diff --git a/generator/tests/init-sources/assembly-example/configs/root-compilation.tsconfig.json b/generator/tests/init-sources/assembly-example/configs/root-compilation.tsconfig.json index b433ca3d8..fafeee5db 100644 --- a/generator/tests/init-sources/assembly-example/configs/root-compilation.tsconfig.json +++ b/generator/tests/init-sources/assembly-example/configs/root-compilation.tsconfig.json @@ -164,4 +164,4 @@ "path": "../examples/assembly/compile.tsconfig.json" } ] -} +} \ No newline at end of file diff --git a/plugins/github-auth-plugin/src/github-auth-plugin.ts b/plugins/github-auth-plugin/src/github-auth-plugin.ts index 30e8d3e92..35e318f10 100644 --- a/plugins/github-auth-plugin/src/github-auth-plugin.ts +++ b/plugins/github-auth-plugin/src/github-auth-plugin.ts @@ -11,22 +11,54 @@ import * as theia from '@theia/plugin'; import * as che from '@eclipse-che/plugin'; -export function start(context: theia.PluginContext): void { +export async function start(context: theia.PluginContext): Promise { if (theia.plugins.getPlugin('github.vscode-pull-request-github')) { - const command = { - id: 'github-plugin-authenticate', - label: 'GitHub authenticate' - }; - context.subscriptions.push(theia.commands.registerCommand(command, async () => { - const token = await che.github.getToken(); - const conf = theia.workspace.getConfiguration(); - await conf.update('githubPullRequests.hosts', [{ - host: 'github.com', - token - }], theia.ConfigurationTarget.Global); - theia.window.showWarningMessage('GitHub token has been set to preferences. ' + - 'Refresh the page to reinitialise the vscode GitHub pull-request plugin with the token'); - })); + let session: theia.AuthenticationSession | undefined = context.workspaceState.get('session'); + const onDidChangeSessions = new theia.EventEmitter(); + theia.authentication.registerAuthenticationProvider({ + id: 'github', + label: 'GitHub', + supportsMultipleAccounts: false, + onDidChangeSessions: onDidChangeSessions.event, + getSessions: async () => { + if (session) { + return [session]; + } else { + return []; + } + }, + login: async (scopes: string[]) => { + const githubUser = await che.github.getUser(); + session = { + id: 'github-session', + accessToken: await che.github.getToken(), + account: {label: githubUser.login, id: githubUser.id.toString()}, + scopes + }; + context.workspaceState.update('session', session); + onDidChangeSessions.fire({ added: [session.id], removed: [], changed: [] }); + return session; + }, + logout: async (id: string) => { + session = undefined; + context.workspaceState.update('session', session); + onDidChangeSessions.fire({ added: [], removed: [id], changed: [] }); + } + } + ); + if (session) { + onDidChangeSessions.fire({ added: [session.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 }); + } + } } } From 987222e247e83482a4a6aa0292f581b2775621d2 Mon Sep 17 00:00:00 2001 From: Igor Vinokur Date: Wed, 7 Oct 2020 15:09:13 +0300 Subject: [PATCH 2/3] fixup! Register GitHub Authentication provider for the vscode Github PR plugin --- .../src/browser/che-github-main.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) 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 0c52c8afa..bf5036a0f 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 @@ -42,7 +42,11 @@ export class CheGithubMainImpl implements CheGithubMain { async $getUser(): Promise { await this.fetchToken(); - const result = await this.axiosInstance.get('https://api.github.com/user?access_token=' + this.token); + return this.getUser(); + } + + private async getUser(): Promise { + const result = await this.axiosInstance.get('https://api.github.com/user?access_token=' + this.token); return result.data; } @@ -51,7 +55,8 @@ export class CheGithubMainImpl implements CheGithubMain { await this.updateToken(); } else { try { - await this.axiosInstance.get('https://api.github.com/user?access_token=' + this.token); + // Validate the GitHub token. + await this.getUser(); } catch (e) { await this.updateToken(); } @@ -62,8 +67,10 @@ export class CheGithubMainImpl implements CheGithubMain { const oAuthProvider = 'github'; try { 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') > 0) { + 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); } From d001946044459b89a813d2de2a4d07f8734420f6 Mon Sep 17 00:00:00 2001 From: Igor Vinokur Date: Wed, 7 Oct 2020 18:01:15 +0300 Subject: [PATCH 3/3] fixup! Register GitHub Authentication provider for the vscode Github PR plugin --- .../assembly-example/configs/root-compilation.tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/tests/init-sources/assembly-example/configs/root-compilation.tsconfig.json b/generator/tests/init-sources/assembly-example/configs/root-compilation.tsconfig.json index fafeee5db..b433ca3d8 100644 --- a/generator/tests/init-sources/assembly-example/configs/root-compilation.tsconfig.json +++ b/generator/tests/init-sources/assembly-example/configs/root-compilation.tsconfig.json @@ -164,4 +164,4 @@ "path": "../examples/assembly/compile.tsconfig.json" } ] -} \ No newline at end of file +}