Commit d7f5502a authored by Lauri Himanen's avatar Lauri Himanen
Browse files

Added KeyCloak authentication mechanism.

parent 2693066b
Pipeline #79117 skipped with stage
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -9,5 +9,8 @@ window.nomadEnv = {
//path: "",
//userCookieDomain: ".localhost",
guestUserToken: 'eyJhbGciOiJIUzI1NiIsImlhdCI6MTUyMzg4MDE1OSwiZXhwIjoxNjgxNTYwMTU5fQ.ey'+
'JpZCI6ImVuY2d1aSJ9.MsMWQa3IklH7cQTxRaIRSF9q8D_2LD5Fs2-irpWPTp4'
'JpZCI6ImVuY2d1aSJ9.MsMWQa3IklH7cQTxRaIRSF9q8D_2LD5Fs2-irpWPTp4',
keycloakBase: 'https://nomad-lab.eu/fairdi/keycloak/auth/',
keycloakRealm: 'fairdi_nomad_test',
keycloakClientId: 'nomad_gui_dev'
};
......@@ -187,8 +187,27 @@ body { font-family: 'Arimo', sans-serif;
header{ background-color: #23356d; }
#logo-header {
display: flex;
}
#auth-panel {
width: 25%;
text-align: right;
padding-top:5px;
}
#logo-panel {
width: 25%;
text-align: right;
padding-top:5px;
}
#spacer {
flex-grow: 1;
}
div#logo-header{
div#logo-header {
width: 1200px; margin: 0 auto;
/* padding-top: 10px;padding-bottom: 56px;*/
padding: 3px 0;
......
......@@ -11,6 +11,8 @@
<link rel="stylesheet" href="css/styles.css"/>
<script defer src="conf.js"></script>
<script defer src="keycloak.min.js"></script>
<script defer src="loadkeycloak.js"></script>
<script defer src="lib/3d-viewers/three.min.js"></script>
<script defer src="lib/3d-viewers/orthographiccontrols.js"></script>
<script defer src="lib/3d-viewers/matviewer.min.js"></script>
......@@ -49,50 +51,29 @@
<header>
<div id="logo-header" >
<div style="float: left; width: 20%;padding-top:9px">
<!--<a href="#/search/new"> NOMAD Encyclopedia</a>-->
<a href="https://nomad-coe.eu/index.php?page=materials-encyclopedia" target="_blank">
Introduction to NOMAD Encyclopedia
<div "logo-panel">
<a href="https://nomad-lab.eu/" target="_blank">
The NOMAD Laboratory
<img src="img/nomad-logo.png" /> <!--style="padding-top:10px"-->
</a>
</div>
<div style="float: right; width: 16%;text-align: right; padding-top:5px; ">
<div id="spacer"></div>
<div id="auth-panel">
<span style="vertical-align: middle;">
<span id="guest-user">Guest
<a style="text-decoration: underline">(LOGIN)</a>
</span>
<span id="auth-user" style="display: none">
<span id="auth-user">
<span id="user-name"></span>
<a id="logout-button" style="text-decoration: underline; cursor: pointer" >
(logout)</a>
<span id="login-button" style="display: none; text-decoration: underline; cursor: pointer">(LOGIN)</span>
<span id="logout-button" style="display: none; text-decoration: underline; cursor: pointer">(LOGOUT)</span>
</span>
&nbsp;&nbsp;
</span>
<img src="img/user.png" />
</div>
<div style="float: right; text-align: right; width: 40%;" >
<a href="https://nomad-coe.eu/" target="_blank">
The NOMAD Laboratory
<img src="img/nomad-logo.png" /> <!--style="padding-top:10px"-->
</a>
</div>
<div style="clear: both;"></div>
</div>
<!--</div>-->
</header>
<div id="second-header">
<div style="float: left; width: 60%;">
<a href=""> <img src="img/NOMADEncyclopedia.png" /></a>
</div>
<div style="float: right; width: 30%;text-align: right">
......@@ -109,6 +90,5 @@
<div id="content">
</div>
<!-- <script type='text/javascript' src='http://www.x3dom.org/download/x3dom.js'> </script>-->
</body>
</html>
This diff is collapsed.
// This separate script is used to handle the login procedure before loading
// the application. As of 0.8.3 nomad-FAIR is using KeyCloak 7.0.0, which does
// not support the "silentCheckSsoRedirectUri" option. This option enables a
// silent login check that does not enforce reloads. In order to do such silent
// login, the Javascript adapter for KeyCloak 8.0.0 is used instead. This is
// against the best practice of directly downloading the Javascript adapter
// from the authentication server (window.nomadEnv.keycloakBase +
// "js/keycloak.min.js"), but is in this case acceptable as it result is a much
// smoother user experience.
var keycloak = new Keycloak({
url: window.nomadEnv.keycloakBase,
realm: window.nomadEnv.keycloakRealm,
clientId: window.nomadEnv.keycloakClientId
});
keycloak.init({
onLoad: "check-sso",
silentCheckSsoRedirectUri: "http://localhost:3000/gui/silent-check-sso.html",
promiseType: "native",
}).then((authenticated) => {
let loginButton = document.querySelector('#login-button');
let logoutButton = document.querySelector('#logout-button');
let userName = document.querySelector('#user-name');
if (authenticated) {
keycloak.loadUserProfile()
.then(function(profile) {
userName.textContent = `${profile.firstName} ${profile.lastName}`;
}).catch(function() {
console.log('Failed to load user profile.');
});
loginButton.style.display = 'none';
logoutButton.style.display = 'inline';
} else {
loginButton.style.display = 'inline';
logoutButton.style.display = 'none';
userName.textContent = "Guest";
}
});
let loginButton = document.querySelector('#login-button');
let logoutButton = document.querySelector('#logout-button');
loginButton.onclick = () => {
keycloak.login({redirectUri: "http://" + window.location.host + "/gui/#/search"})
.catch(() => {console.log("Authentication error.")})
};
logoutButton.onclick = () => {
keycloak.logout()
};
<!doctype html>
<html>
<body>
<script>
parent.postMessage(location.href, location.origin)
</script>
</body>
</html>
......@@ -35,23 +35,27 @@ function add(route, func){
window.addEventListener("hashchange", route);
function route(){
let hashPath= document.location.hash.substring(2);
function route() {
let hashPath = document.location.hash.substring(2);
let command, param, subparam;
// remove the ending /
// Remove the ending /
if (hashPath.lastIndexOf('/') === (hashPath.length-1))
hashPath = hashPath.substring(0,hashPath.length-1);
if (hashPath.indexOf('/') >0){
// Remove state parameters from authentication
let stateIndex = hashPath.indexOf('&state');
if (stateIndex != -1) {
hashPath = hashPath.substring(0, stateIndex);
}
if (hashPath.indexOf('/') > 0){
let a= hashPath.split('/');
command= a[0];
param= a[1];
subparam= a[2];
}
else command= hashPath;
//console.log("hashPath: " + hashPath+' command: '+command+' param: '+param+' subparam: '+subparam);
else command = hashPath;
if (routes.has(command)) {
routes.get(command)(param, subparam);
......
......@@ -66,8 +66,6 @@ let ELEMENTS = [
// API URL and user cookie domain configuration
const API_BASE_URL = window.nomadEnv.host + window.nomadEnv.path;
document.querySelector('#guest-user a').href = API_BASE_URL+'saml/?sso2';
// Mockup URLs
//const FERMI_SURFACE_URL= HOST+'files/fermi/'+
//'fed3fa9fbc68aa6c5e51845396889666ca37bb2e626e1da53.x3d';
......
......@@ -225,28 +225,25 @@ Router.route();
/********* User authentication ***********/
let userNameElement = document.querySelector('#user-name');
let logoutButton = document.querySelector('#logout-button');
function setAppAuthenticated(data){
if (data.status === 'Authenticated'){
userNameElement.innerHTML = data.user.username;
document.querySelector('#guest-user').style.display = 'none';
document.querySelector('#auth-user').style.display = 'inline';
util.setAuthRequestHeader(data.user, data.token.data);
if (currentModule === materialModDOM) flaggingTab.style.visibility = 'visible';
}
}
//function setAppAuthenticated(data){
//if (data.status === 'Authenticated'){
//userNameElement.innerHTML = data.user.username;
//document.querySelector('#guest-user').style.display = 'none';
//document.querySelector('#auth-user').style.display = 'inline';
//util.setAuthRequestHeader(data.user, data.token.data);
//if (currentModule === materialModDOM) flaggingTab.style.visibility = 'visible';
//}
//}
function setAppLoggedOut(){
userNameElement.innerHTML = '';
document.querySelector('#guest-user').style.display = 'inline';
document.querySelector('#auth-user').style.display = 'none';
util.setAuthRequestHeader();
if (flaggingTab.style.visibility !== 'hidden')
flaggingTab.style.visibility = 'hidden';
}
//function logout(){
//userNameElement.innerHTML = '';
//util.setAuthRequestHeader();
//if (flaggingTab.style.visibility !== 'hidden')
//flaggingTab.style.visibility = 'hidden';
//}
function getCookie(name) {
......@@ -262,22 +259,9 @@ function parseCookie(userData) {
let userInfoCookie = getCookie('user_info');
//console.log('Cookies: ', document.cookie, userInfoCookie);
if (userInfoCookie !== undefined){
let userInfoData = JSON.parse(parseCookie(userInfoCookie));
//console.log('userInfoData: ', userInfoData);
setAppAuthenticated(userInfoData);
}
// Logout
logoutButton.addEventListener( "click", e => {
document.cookie='user_info=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain='+
window.nomadEnv.userCookieDomain+'; path=/';
//console.log('Logging out document.cookie ',document.cookie);
setAppLoggedOut();
//console.log('Logging out ',userNameElement.innerHTML);
});
......@@ -864,7 +864,7 @@ class SummaryByFunctionalsComponent {
// Create tabs for each functional
this.functionalTabs.innerHTML = "";
this.calcMapByFunctional.forEach( (calcs, functionalName) =>{
this.calcMapByFunctional.forEach( (calcs, functionalName) => {
this.functionalTabs.innerHTML +=
'<span class="tab" data-tab="'+functionalName+'">'+functionalName+'</span>';
});
......
......@@ -229,7 +229,7 @@ class PropertiesBox {
</div>
<div style="clear: both;"></div>
`
`;
this.tabsElement = this.element.querySelector('.properties-box-tabs');
this.tabSelected = this.element.querySelector('[data-tab="structure"]');
this.tabPanelSelected = this.element.querySelector('.structure-panel');
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment