CHE-9024: fix ability to start a workspace from Dashboard (#9034)

* CHE-9024: fix ability to start a workspace from Dashboard

Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>

* fixup! CHE-9024: fix ability to start a workspace from Dashboard
6.19.x
Oleksii Kurinnyi 2018-03-07 11:01:34 +02:00 committed by GitHub
parent b47e5841e6
commit 16a8419a90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 144 additions and 32 deletions

View File

@ -18,13 +18,95 @@ import { Loader } from './loader/loader'
const WEBSOCKET_CONTEXT = '/api/websocket';
declare const Keycloak: Function;
export class KeycloakLoader {
/**
* Load keycloak settings
*/
public loadKeycloakSettings(): Promise<any> {
const msg = "Cannot load keycloak settings. This is normal for single-user mode.";
return new Promise((resolve, reject) => {
try {
const request = new XMLHttpRequest();
request.onerror = request.onabort = function () {
reject(msg);
};
request.onload = () => {
if (request.status == 200) {
resolve(this.injectKeycloakScript(JSON.parse(request.responseText)));
} else {
reject(msg);
}
};
const url = "/api/keycloak/settings";
request.open("GET", url, true);
request.send();
} catch (e) {
reject(msg + e.message);
}
});
}
/**
* Injects keycloak javascript
*/
private injectKeycloakScript(keycloakSettings: any): Promise<any> {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.type = 'text/javascript';
(script as any).language = 'javascript';
script.async = true;
script.src = keycloakSettings['che.keycloak.auth_server_url'] + '/js/keycloak.js';
script.onload = () => {
resolve(this.initKeycloak(keycloakSettings));
};
script.onerror = script.onabort = () => {
reject('Cannot load ' + script.src);
};
document.head.appendChild(script);
});
}
/**
* Initialize keycloak and load the IDE
*/
private initKeycloak(keycloakSettings: any): Promise<any> {
return new Promise((resolve, reject) => {
const keycloak = Keycloak({
url: keycloakSettings['che.keycloak.auth_server_url'],
realm: keycloakSettings['che.keycloak.realm'],
clientId: keycloakSettings['che.keycloak.client_id']
});
window['_keycloak'] = keycloak;
keycloak
.init({onLoad: 'login-required', checkLoginIframe: false})
.success(() => {
resolve(keycloak);
})
.error(() => {
reject('[Keycloak] Failed to initialize Keycloak');
});
});
}
}
export class WorkspaceLoader {
loader: Loader;
workspace: che.IWorkspace;
startAfterStopping = false;
constructor(loader: Loader) {
constructor(private readonly loader: Loader,
private readonly keycloak: any) {
this.loader = loader;
/** Ask dashboard to show the IDE. */
@ -112,38 +194,42 @@ export class WorkspaceLoader {
* @param workspaceId workspace id
*/
getWorkspace(workspaceId: string): Promise<che.IWorkspace> {
return new Promise((resolve, reject) => {
let request = new XMLHttpRequest();
request.open("GET", '/api/workspace/' + workspaceId);
request.send();
request.onreadystatechange = function () {
if (this.readyState !== 4) { return; }
if (this.status !== 200) {
reject(this.status ? this.statusText : "Unknown error");
return;
}
resolve(JSON.parse(this.responseText));
};
});
const request = new XMLHttpRequest();
request.open("GET", '/api/workspace/' + workspaceId);
return this.setAuthorizationHeader(request).then((xhr: XMLHttpRequest) => {
return new Promise<che.IWorkspace>((resolve, reject) => {
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) { return; }
if (xhr.status !== 200) {
reject(xhr.status ? xhr.statusText : "Unknown error");
return;
}
resolve(JSON.parse(xhr.responseText));
};
});
});
}
/**
* Start current workspace.
*/
startWorkspace(): Promise<che.IWorkspace> {
return new Promise((resolve, reject) => {
let request = new XMLHttpRequest();
request.open("POST", `/api/workspace/${this.workspace.id}/runtime`);
request.send();
request.onreadystatechange = function () {
if (this.readyState !== 4) { return; }
if (this.status !== 200) {
reject(this.status ? this.statusText : "Unknown error");
return;
}
resolve(JSON.parse(this.responseText));
};
});
const request = new XMLHttpRequest();
request.open("POST", `/api/workspace/${this.workspace.id}/runtime`);
return this.setAuthorizationHeader(request).then((xhr: XMLHttpRequest) => {
return new Promise<che.IWorkspace>((resolve, reject) => {
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) { return; }
if (xhr.status !== 200) {
reject(xhr.status ? xhr.statusText : "Unknown error");
return;
}
resolve(JSON.parse(xhr.responseText));
};
});
});
}
/**
@ -192,7 +278,8 @@ export class WorkspaceLoader {
subscribeWorkspaceEvents() : Promise<void> {
let master = new CheJsonRpcMasterApi(new WebsocketClient());
return new Promise((resolve) => {
master.connect(this.websocketBaseURL() + WEBSOCKET_CONTEXT).then(() => {
const entryPoint = this.websocketBaseURL() + WEBSOCKET_CONTEXT + this.getAuthenticationToken();
master.connect(entryPoint).then(() => {
master.subscribeEnvironmentOutput(this.workspace.id,
(message: any) => this.onEnvironmentOutput(message.text));
@ -239,9 +326,34 @@ export class WorkspaceLoader {
}, 1000);
}
};
setAuthorizationHeader(xhr: XMLHttpRequest): Promise<XMLHttpRequest> {
return new Promise((resolve, reject) => {
if (this.keycloak && this.keycloak.token) {
this.keycloak.updateToken(5).success(() => {
xhr.setRequestHeader('Authorization', 'Bearer ' + this.keycloak.token);
resolve(xhr);
}).error(() => {
console.log('Failed to refresh token');
this.keycloak.login();
reject();
});
}
resolve(xhr);
});
}
getAuthenticationToken(): string {
return this.keycloak && this.keycloak.token ? '?token=' + this.keycloak.token : '';
}
}
/** Initialize */
if (document.getElementById('workspace-console')) {
new WorkspaceLoader(new Loader()).load();
new KeycloakLoader().loadKeycloakSettings().catch((error: any) => {
console.log(error);
}).then((keycloak: any) => {
new WorkspaceLoader(new Loader(), keycloak).load();
});
}

View File

@ -37,7 +37,7 @@ module.exports = merge(common, {
target: 'http://localhost:8080',
ws: true,
},
'/api/workspace': "http://localhost:8080",
'/api': "http://localhost:8080",
}
},
plugins:[