Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHE-7581 Improved keycloak initialization #8425

Merged
merged 4 commits into from
Jan 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,58 +20,75 @@ protected Keycloak() {
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;
}-*/;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
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;
Expand All @@ -32,20 +31,22 @@
/** 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;
}

Expand Down Expand Up @@ -82,19 +83,15 @@ public void onFailure(Exception reason) {
}

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(
Expand Down Expand Up @@ -129,6 +126,6 @@ public String apply(Boolean refreshed) {
}

public boolean isKeycloakDisabled() {
return keycloakDisabled;
return keycloak == null;
}
}