Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Commit

Permalink
Register GitHub Authentication provider for the vscode GitHub PR plug…
Browse files Browse the repository at this point in the history
…in (#841)

1. Register authentication provider via the authentication plugin API based on the Che GitHub oAuth, so the native command Github sign in from the PR plugin calls the registered provider.
2. Remove the temporary command that injects the GitHub token to the vscode PR plugin settings and ask to reload the browser page.
3. Update the GitHub Plugin API with getUser() function which returns GitHub user info.
  • Loading branch information
vinokurig authored Oct 9, 2020
1 parent 8d39edf commit 010cef7
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CheGithubMain } from '../common/che-protocol';
import { interfaces } from 'inversify';
import axios, { AxiosInstance } from 'axios';
import { OauthUtils } from '@eclipse-che/theia-remote-api/lib/browser/oauth-utils';
import { GithubUser } from '@eclipse-che/plugin';

export class CheGithubMainImpl implements CheGithubMain {
private axiosInstance: AxiosInstance = axios;
Expand Down Expand Up @@ -39,12 +40,23 @@ export class CheGithubMainImpl implements CheGithubMain {
}
}

async $getUser(): Promise<GithubUser> {
await this.fetchToken();
return this.getUser();
}

private async getUser(): Promise<GithubUser> {
const result = await this.axiosInstance.get<GithubUser>('https://api.github.com/user?access_token=' + this.token);
return result.data;
}

private async fetchToken(): Promise<void> {
if (!this.token) {
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();
}
Expand All @@ -55,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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@ export interface CheOpenshiftMain {
export interface CheGithub {
uploadPublicSshKey(publicKey: string): Promise<void>;
getToken(): Promise<string>;
getUser(): Promise<che.GithubUser>;
}

export interface CheGithubMain {
$uploadPublicSshKey(publicKey: string): Promise<void>;
$getToken(): Promise<string>;
$getUser(): Promise<che.GithubUser>;
}

export interface CheOauth {
Expand Down
3 changes: 3 additions & 0 deletions extensions/eclipse-che-theia-plugin-ext/src/plugin/che-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ export function createAPIFactory(rpc: RPCProtocol): CheApiFactory {
},
getToken(): Promise<string> {
return cheGithubImpl.getToken();
},
getUser(): Promise<che.GithubUser> {
return cheGithubImpl.getUser();
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -26,4 +27,8 @@ export class CheGithubImpl implements CheGithub {
getToken(): Promise<string> {
return this.githubMain.$getToken();
}

getUser(): Promise<GithubUser> {
return this.githubMain.$getUser();
}
}
8 changes: 8 additions & 0 deletions extensions/eclipse-che-theia-plugin/src/che-proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,17 @@ declare module '@eclipse-che/plugin' {
export function createWorkspace(devfilePath: string): Promise<void>;
}

export interface GithubUser {
login: string,
id: number,
name: string,
email: string
}

export namespace github {
export function uploadPublicSshKey(publicKey: string): Promise<void>;
export function getToken(): Promise<string>;
export function getUser(): Promise<GithubUser>;
}

export namespace openshift {
Expand Down
62 changes: 47 additions & 15 deletions plugins/github-auth-plugin/src/github-auth-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> {
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.AuthenticationProviderAuthenticationSessionsChangeEvent>();
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 });
}
}
}
}

Expand Down

0 comments on commit 010cef7

Please sign in to comment.