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

Apply GitHub authentication plugin #604

Merged
merged 6 commits into from
Jan 29, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions che-theia-init-sources.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ sources:
- plugins/welcome-plugin
- plugins/ssh-plugin
- plugins/telemetry-plugin
- plugins/github-auth-plugin
checkoutTo: master
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

import { CheGithubMain } from '../common/che-protocol';
import { CheApiService, CheGithubMain } from '../common/che-protocol';
import { interfaces } from 'inversify';
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
import axios, { AxiosInstance } from 'axios';
Expand All @@ -18,9 +18,11 @@ export class CheGithubMainImpl implements CheGithubMain {
private axiosInstance: AxiosInstance = axios;
private apiUrl: string;
private token: string | undefined;
private readonly cheApiService: CheApiService;

constructor(container: interfaces.Container) {
this.envVariableServer = container.get(EnvVariablesServer);
this.cheApiService = container.get(CheApiService);
this.envVariableServer.getValue('CHE_API').then(variable => {
if (variable && variable.value) {
this.apiUrl = variable.value;
Expand All @@ -36,6 +38,15 @@ export class CheGithubMainImpl implements CheGithubMain {
});
}

async $getToken(): Promise<string> {
await this.fetchToken();
if (this.token) {
return this.token;
} else {
throw new Error('Failed to get GitHub authentication token');
}
}

private async fetchToken(): Promise<void> {
if (!this.token) {
await this.updateToken();
Expand All @@ -49,17 +60,17 @@ export class CheGithubMainImpl implements CheGithubMain {
}

private async updateToken(): Promise<void> {
this.token = await this.getToken();
this.token = await this.cheApiService.getOAuthToken('github');
if (!this.token) {
await this.authenticate();
this.token = await this.getToken();
this.token = await this.cheApiService.getOAuthToken('github');
}
}

private authenticate(): Promise<void> {
return new Promise(async (resolve, reject) => {
const redirectUrl = window.location.href;
const url = `${this.apiUrl}/oauth/authenticate?oauth_provider=github&userId=${await this.getUserId()}` +
const url = `${this.apiUrl}/oauth/authenticate?oauth_provider=github&userId=${await this.cheApiService.getUserId()}` +
`&scope=write:public_key&redirect_after_login=${redirectUrl}`;
const popupWindow = window.open(url, 'popup');
const popup_close_handler = async () => {
Expand All @@ -85,18 +96,4 @@ export class CheGithubMainImpl implements CheGithubMain {
const popupCloseHandlerIntervalId = window.setInterval(popup_close_handler, 80);
});
}

private async getToken(): Promise<string | undefined> {
try {
const result = await this.axiosInstance.get<{ token: string }>(`${this.apiUrl}/oauth/token?oauth_provider=github`);
return result.data.token;
} catch (e) {
return undefined;
}
}

private async getUserId(): Promise<string | undefined> {
const result = await this.axiosInstance.get<{ id: string }>(`${this.apiUrl}/user`);
return result.data.id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ export interface CheFactoryMain {
export interface CheDevfile {
}

export interface CheGithub {
uploadPublicSshKey(publicKey: string): Promise<void>;
}

export interface CheDevfileMain {
$createWorkspace(devfilePath: string): Promise<void>;
}
Expand All @@ -65,8 +61,14 @@ export interface CheSshMain {
$deleteKey(service: string, name: string): Promise<void>;
}

export interface CheGithub {
uploadPublicSshKey(publicKey: string): Promise<void>;
getToken(): Promise<string>;
}

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

/**
Expand Down Expand Up @@ -429,6 +431,7 @@ export interface CheApiService {

getFactoryById(factoryId: string): Promise<cheApi.factory.Factory>;

getUserId(): Promise<string>;
getUserPreferences(): Promise<Preferences>;
getUserPreferences(filter: string | undefined): Promise<Preferences>;
updateUserPreferences(update: Preferences): Promise<Preferences>;
Expand All @@ -444,6 +447,7 @@ export interface CheApiService {
getAllSshKey(service: string): Promise<cheApi.ssh.SshPair[]>;
submitTelemetryEvent(id: string, ownerId: string, ip: string, agent: string, resolution: string, properties: [string, string][]): Promise<void>;
submitTelemetryActivity(): Promise<void>;
getOAuthToken(oAuthProvider: string): Promise<string | undefined>;
}

export const CHE_TASK_SERVICE_PATH = '/che-task-service';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ export class CheApiServiceImpl implements CheApiService {
return process.env.CHE_API_INTERNAL;
}

async getUserId(): Promise<string> {
const cheApiClient = await this.getCheApiClient();
const user = await cheApiClient.getCurrentUser();
return user.id;
}

async getUserPreferences(filter?: string): Promise<Preferences> {
const cheApiClient = await this.getCheApiClient();
return cheApiClient.getUserPreferences(filter);
Expand Down Expand Up @@ -282,6 +288,15 @@ export class CheApiServiceImpl implements CheApiService {
}
}

async getOAuthToken(oAuthProvider: string): Promise<string | undefined> {
const cheApiClient = await this.getCheApiClient();
try {
return await cheApiClient.getOAuthToken(oAuthProvider);
} catch (e) {
return undefined;
}
}

private getWorkspaceTelemetryClient(): TelemetryClient | undefined {

if (!this.telemetryClient) {
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 @@ -116,6 +116,9 @@ export function createAPIFactory(rpc: RPCProtocol): CheApiFactory {
const github: typeof che.github = {
uploadPublicSshKey(publicKey: string): Promise<void> {
return cheGithubImpl.uploadPublicSshKey(publicKey);
},
getToken(): Promise<string> {
return cheGithubImpl.getToken();
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ export class CheGithubImpl implements CheGithub {
uploadPublicSshKey(publicKey: string): Promise<void> {
return this.githubMain.$uploadPublicSshKey(publicKey);
}

getToken(): Promise<string> {
return this.githubMain.$getToken();
}
}
1 change: 1 addition & 0 deletions extensions/eclipse-che-theia-plugin/src/che-proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ declare module '@eclipse-che/plugin' {

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

export namespace ssh {
Expand Down
3 changes: 3 additions & 0 deletions plugins/github-auth-plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
lib/
node_modules/
*.theia
5 changes: 5 additions & 0 deletions plugins/github-auth-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Theia - Telemetry Plug-in
vinokurig marked this conversation as resolved.
Show resolved Hide resolved

## License

[EPL-2.0](http://www.eclipse.org/legal/epl-2.0)
42 changes: 42 additions & 0 deletions plugins/github-auth-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "@eclipse-che/github-auth-plugin",
"version": "0.0.1",
"publisher": "Eclipse Che",
"keywords": [
"theia-plugin"
],
"description": "Manage Eclipse Che Telemetry Plugin",
vinokurig marked this conversation as resolved.
Show resolved Hide resolved
"license": "EPL-2.0",

"files": [
"src"
],
"activationEvents": [
"*"
],
"devDependencies": {
"@theia/plugin": "next",
"@theia/plugin-packager": "latest",
"@eclipse-che/plugin": "0.0.1",
"rimraf": "2.6.2",
"typescript-formatter": "7.2.2",
"typescript": "2.9.2",
"ts-loader": "^4.1.0"
},
"scripts": {
"prepare": "yarn run clean && yarn run build",
"clean": "rimraf lib",
"format": "tsfmt -r --useTsfmt ../../configs/tsfmt.json",
"lint": "tslint -c ../../configs/tslint.json --project tsconfig.json",
"lint:fix": "tslint -c ../../configs/tslint.json --fix --project .",
"compile": "tsc",
"build": "yarn lint:fix && concurrently -n \"format,lint,compile\" -c \"red,green,blue\" \"yarn format\" \"yarn lint\" \"yarn compile\" && theia-plugin pack",
"watch": "tsc -w"
},
"engines": {
"theiaPlugin": "next"
},
"theiaPlugin": {
"backend": "lib/github-auth-plugin.js"
}
}
35 changes: 35 additions & 0 deletions plugins/github-auth-plugin/src/github-auth-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*********************************************************************
* Copyright (c) 2019 Red Hat, Inc.
vinokurig marked this conversation as resolved.
Show resolved Hide resolved
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

import * as theia from '@theia/plugin';
import * as che from '@eclipse-che/plugin';

export function start(context: theia.PluginContext) {
if (theia.plugins.getPlugin('github.vscode-pull-request-github')) {
const informationMessageTestCommand = {
vinokurig marked this conversation as resolved.
Show resolved Hide resolved
id: 'github-plugin-authenticate',
label: 'GitHub authenticate'
};
context.subscriptions.push(theia.commands.registerCommand(informationMessageTestCommand, async () => {
const token = await che.github.getToken();
const conf = await 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');
}));
}
}

export function stop() {

}
15 changes: 15 additions & 0 deletions plugins/github-auth-plugin/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "../../configs/base.tsconfig",
"compilerOptions": {
"skipLibCheck": true,
"lib": [
"es6",
"webworker"
],
"rootDir": "src",
"outDir": "lib"
},
"include": [
"src"
]
}
18 changes: 18 additions & 0 deletions plugins/github-auth-plugin/tsfmt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"baseIndentSize": 0,
"newLineCharacter": "\n",
"indentSize": 4,
"tabSize": 4,
"indentStyle": 4,
"convertTabsToSpaces": true,
"insertSpaceAfterCommaDelimiter": true,
"insertSpaceAfterSemicolonInForStatements": true,
"insertSpaceBeforeAndAfterBinaryOperators": true,
"insertSpaceAfterKeywordsInControlFlowStatements": true,
"insertSpaceAfterFunctionKeywordForAnonymousFunctions": false,
"insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false,
"insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false,
"insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false,
"placeOpenBraceOnNewLineForFunctions": false,
"placeOpenBraceOnNewLineForControlBlocks": false
}
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
"@eclipse-che/api" latest

"@eclipse-che/workspace-client@latest":
version "0.0.1-1574171760"
resolved "https://registry.yarnpkg.com/@eclipse-che/workspace-client/-/workspace-client-0.0.1-1574171760.tgz#e4066030fe4cb35f21a82e173e37633d37c76520"
integrity sha512-lCnrrb9jKkxbO9QSmFERHvDxrN+8j1X/3RypESu7n7nrG53ubEqnnquTbU+vEgrMHyg1x0ctLRiUBQarM8dslg==
version "0.0.1-1579077578"
resolved "https://registry.yarnpkg.com/@eclipse-che/workspace-client/-/workspace-client-0.0.1-1579077578.tgz#0fc322b536eb46bf271effc3f00a0435038b5966"
integrity sha512-j3hPUaMcld6cw0wuqQd/EjjUAkkq7J5iri8MCJYJf2eSylLnjYRabNfnfVS4REgj3b02VXLx3kuDGmNPLacSEw==
dependencies:
"@eclipse-che/api" "^7.0.0-beta-4.0"
axios "0.19.0"
Expand Down