CHE-7581 Improved keycloak initialization (#8425)

* Initialize keycloak before loading the IDE javascript

* Fix formatting

* Add explanation in error message
6.19.x
Vitaliy Guliy 2018-01-26 12:35:42 +02:00 committed by GitHub
parent 0c7db1480d
commit 9abfec7c5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 156 additions and 67 deletions

View File

@ -56,6 +56,81 @@
var Loader = new function() {
/*
* Load keycloak settings
*/
this.loadKeycloakSettings = function() {
var msg = "Cannot load keycloak settings. This is normal for single-user mode.";
try {
var request = new XMLHttpRequest();
request.onerror = request.onabort = function() {
console.error(msg);
Loader.startLoading();
};
request.onload = function() {
if (request.status == 200) {
Loader.injectKeycloakScript(JSON.parse(this.responseText));
} else {
console.error(msg);
Loader.startLoading();
}
};
var url = "/api/keycloak/settings";
request.open("GET", url, true);
request.send();
} catch (e) {
console.error(msg, e);
Loader.startLoading();
}
};
/*
* Injects keycloak javascript
*/
this.injectKeycloakScript = function(keycloakSettings) {
var script = document.createElement("script");
script.type = "text/javascript";
script.language = "javascript";
script.async = true;
script.src = keycloakSettings['che.keycloak.auth_server_url'] + '/js/keycloak.js';
script.onload = function() {
Loader.initKeycloak(keycloakSettings);
};
script.onerror = script.onabort = function() {
console.error("Cannot load " + script.src);
};
document.head.appendChild(script);
};
/*
* Initialize keycloak and load the IDE
*/
this.initKeycloak = function(keycloakSettings) {
var 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(function(authenticated) {
Loader.startLoading();
})
.error(function () {
console.log('[Keycloak] Failed to initialize Keycloak');
});
};
/*
* Show loader and load compilation-mapping.txt file to determine which IDE JavaScript file will be loaded
*/
@ -107,7 +182,7 @@
} else if (userAgent.includes('webkit')) {
return 'safari';
} else if (userAgent.includes('msie')) {
if ($doc.documentMode >= 8) {
if (document.documentMode >= 8) {
return 'ie8';
} else {
var result = /msie ([0-9]+)\\.([0-9]+)/.exec(userAgent);
@ -283,12 +358,12 @@
script.language = "javascript";
script.async = true;
script.src = "/_app/_app.nocache.js";
document.getElementsByTagName("head")[0].appendChild(script);
document.head.appendChild(script);
};
};
setTimeout(function() {
Loader.startLoading();
Loader.loadKeycloakSettings();
window.parent.postMessage("show-ide", "*");
}, 1);

View File

@ -20,58 +20,75 @@ public final class Keycloak extends JavaScriptObject {
super();
}
public static native boolean isConfigured() /*-{
if ($wnd['_keycloak']) {
return true;
}
return false;
}-*/;
public static native Promise<Keycloak> get() /*-{
return new Promise(function (resolve, reject) {
if ($wnd['_keycloak']) {
resolve($wnd['_keycloak']);
} else {
reject();
}
});
}-*/;
public static native Promise<Keycloak> init(
String theUrl, String theRealm, String theClientId) /*-{
return new Promise(function (resolve, reject) {
try {
console.log('[Keycloak] Initializing');
var keycloak = $wnd.Keycloak({
url: theUrl,
realm: theRealm,
clientId: theClientId
});
$wnd['_keycloak'] = keycloak;
keycloak.init({onLoad: 'login-required', checkLoginIframe: false})
.success(function (authenticated) {
resolve(keycloak);
})
.error(function () {
console.log('[Keycloak] Failed to initialize Keycloak');
reject();
});
console.log('[Keycloak] Initializing complete');
} catch (ex) {
console.log('[Keycloak] Failed to initialize Keycloak with exception: ', ex);
reject();
}
return new Promise(function (resolve, reject) {
try {
console.log('[Keycloak] Initializing');
var keycloak = $wnd.Keycloak({
url: theUrl,
realm: theRealm,
clientId: theClientId
});
}-*/;
$wnd['_keycloak'] = keycloak;
keycloak.init({onLoad: 'login-required', checkLoginIframe: false})
.success(function (authenticated) {
resolve(keycloak);
})
.error(function () {
console.log('[Keycloak] Failed to initialize Keycloak');
reject();
});
console.log('[Keycloak] Initializing complete');
} catch (ex) {
console.log('[Keycloak] Failed to initialize Keycloak with exception: ', ex);
reject();
}
});
}-*/;
public native Promise<Boolean> updateToken(int minValidity) /*-{
var theKeycloak = this;
return new Promise(function (resolve, reject) {
try {
theKeycloak.updateToken(minValidity)
.success(function (refreshed) {
resolve(refreshed);
})
.error(function () {
console.log('[Keycloak] Failed updating Keycloak token');
reject();
theKeycloak.login();
});
} catch (ex) {
console.log('[Keycloak] Failed updating Keycloak token with exception: ', ex);
reject();
theKeycloak.login();
}
});
var theKeycloak = this;
return new Promise(function (resolve, reject) {
try {
theKeycloak.updateToken(minValidity)
.success(function (refreshed) {
resolve(refreshed);
})
.error(function () {
console.log('[Keycloak] Failed updating Keycloak token');
reject();
theKeycloak.login();
});
} catch (ex) {
console.log('[Keycloak] Failed updating Keycloak token with exception: ', ex);
reject();
theKeycloak.login();
}
});
return updatePromise;
}-*/;
return updatePromise;
}-*/;
public native String getToken() /*-{
return this.token;
}-*/;
return this.token;
}-*/;
}

View File

@ -22,7 +22,6 @@ import com.google.inject.Singleton;
import java.util.Map;
import org.eclipse.che.api.promises.client.Function;
import org.eclipse.che.api.promises.client.Promise;
import org.eclipse.che.api.promises.client.PromiseProvider;
import org.eclipse.che.api.promises.client.callback.CallbackPromiseHelper;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.json.JsonHelper;
@ -32,20 +31,22 @@ import org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants;
/** KeycloakProvider */
@Singleton
public class KeycloakProvider {
private AppContext appContext;
private boolean keycloakDisabled = false;
private Promise<Keycloak> keycloak;
@Inject
public KeycloakProvider(AppContext appContext, PromiseProvider promiseProvider) {
this.appContext = appContext;
public KeycloakProvider(AppContext appContext) {
if (Keycloak.isConfigured()) {
keycloak = Keycloak.get();
return;
}
String keycloakSettings =
getKeycloakSettings(KeycloakConstants.getEndpoint(appContext.getMasterApiEndpoint()));
Map<String, String> settings;
try {
settings = JsonHelper.toMap(keycloakSettings);
} catch (Exception e) {
keycloakDisabled = true;
return;
}
@ -82,19 +83,15 @@ public class KeycloakProvider {
}
public static native String getKeycloakSettings(String keycloakSettingsEndpoint) /*-{
var myReq = new XMLHttpRequest();
myReq.open('GET', '' + keycloakSettingsEndpoint, false);
myReq.send(null);
return myReq.responseText;
}-*/;
var myReq = new XMLHttpRequest();
myReq.open('GET', '' + keycloakSettingsEndpoint, false);
myReq.send(null);
return myReq.responseText;
}-*/;
public static native JavaScriptObject getWindow() /*-{
return $wnd;
}-*/;
public Promise<Keycloak> getKeycloak() {
return keycloak;
}
return $wnd;
}-*/;
public Promise<String> getUpdatedToken(int minValidity) {
return keycloak.thenPromise(
@ -129,6 +126,6 @@ public class KeycloakProvider {
}
public boolean isKeycloakDisabled() {
return keycloakDisabled;
return keycloak == null;
}
}