diff --git a/ide/che-ide-gwt-app/src/main/resources/org/eclipse/che/ide/public/IDE.html b/ide/che-ide-gwt-app/src/main/resources/org/eclipse/che/ide/public/IDE.html index 5e68604d23..7a09f0237e 100644 --- a/ide/che-ide-gwt-app/src/main/resources/org/eclipse/che/ide/public/IDE.html +++ b/ide/che-ide-gwt-app/src/main/resources/org/eclipse/che/ide/public/IDE.html @@ -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); diff --git a/multiuser/keycloak/che-multiuser-keycloak-ide/src/main/java/org/eclipse/che/multiuser/keycloak/ide/Keycloak.java b/multiuser/keycloak/che-multiuser-keycloak-ide/src/main/java/org/eclipse/che/multiuser/keycloak/ide/Keycloak.java index 7eba3a0c10..89670a922e 100644 --- a/multiuser/keycloak/che-multiuser-keycloak-ide/src/main/java/org/eclipse/che/multiuser/keycloak/ide/Keycloak.java +++ b/multiuser/keycloak/che-multiuser-keycloak-ide/src/main/java/org/eclipse/che/multiuser/keycloak/ide/Keycloak.java @@ -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 get() /*-{ + return new Promise(function (resolve, reject) { + if ($wnd['_keycloak']) { + resolve($wnd['_keycloak']); + } else { + reject(); + } + }); + }-*/; + public static native Promise 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 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; + }-*/; } diff --git a/multiuser/keycloak/che-multiuser-keycloak-ide/src/main/java/org/eclipse/che/multiuser/keycloak/ide/KeycloakProvider.java b/multiuser/keycloak/che-multiuser-keycloak-ide/src/main/java/org/eclipse/che/multiuser/keycloak/ide/KeycloakProvider.java index c6065f57f6..00baec05bc 100644 --- a/multiuser/keycloak/che-multiuser-keycloak-ide/src/main/java/org/eclipse/che/multiuser/keycloak/ide/KeycloakProvider.java +++ b/multiuser/keycloak/che-multiuser-keycloak-ide/src/main/java/org/eclipse/che/multiuser/keycloak/ide/KeycloakProvider.java @@ -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; @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 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 getKeycloak() { - return keycloak; - } + return $wnd; + }-*/; public Promise getUpdatedToken(int minValidity) { return keycloak.thenPromise( @@ -129,6 +126,6 @@ public class KeycloakProvider { } public boolean isKeycloakDisabled() { - return keycloakDisabled; + return keycloak == null; } }