-
-
-
+
+
{user !== null ? user.profile.name : ""}
+
+ {user && (
+
+
+
+
+
+ )}
)
diff --git a/src/redux/actions.js b/src/redux/actions.js
index ba114b3d80..14c43843a4 100644
--- a/src/redux/actions.js
+++ b/src/redux/actions.js
@@ -78,3 +78,9 @@ export const USE_NAME = 'USE_NAME';
export function toggleUseNameState() {
return { type: USE_NAME };
}
+
+export const USER = 'USER';
+
+export function setLoggedUser(user) {
+ return { type: USER, user : user};
+}
diff --git a/src/redux/reducer.js b/src/redux/reducer.js
index f9f50eb46b..86ea34c586 100644
--- a/src/redux/reducer.js
+++ b/src/redux/reducer.js
@@ -26,7 +26,8 @@ import {
SELECT_CASE,
SELECT_FILE,
SELECT_THEME,
- USE_NAME
+ USE_NAME,
+ USER
} from "./actions";
const initialState = {
@@ -38,7 +39,8 @@ const initialState = {
cases : [],
selectedCase : null,
selectedFile : null,
- useName : getLocalStorageUseName()
+ useName : getLocalStorageUseName(),
+ user : null,
};
export const reducer = createReducer(initialState, {
@@ -94,4 +96,8 @@ export const reducer = createReducer(initialState, {
state.useName = !state.useName;
saveLocalStorageUseName(state.useName);
},
+
+ [USER]: (state, action) => {
+ state.user = action.user;
+ },
});
diff --git a/src/translations/en.json b/src/translations/en.json
index 328e38f742..01c6e4b1a7 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -15,6 +15,12 @@
"delete" : "Delete",
"filter" : "Filter",
+
+ "settings" : "Settings",
+ "logout" : "Logout",
+ "login" : "Login",
+ "connection": "Connection",
+
"deleteStudy" : "Delete Study",
"deleteStudyMsg" : "Are you sure you want to delete the study?",
"studyNameDidNotMatchMsg" : "The given study name did not match with ",
diff --git a/src/translations/fr.json b/src/translations/fr.json
index 80169beca0..02811781ca 100644
--- a/src/translations/fr.json
+++ b/src/translations/fr.json
@@ -15,6 +15,11 @@
"delete" : "Supprimer",
"filter" : "Filtre",
+ "settings" : "Paramètres",
+ "logout" : "Se déconnecter",
+ "login" : "Se connecter",
+ "connection": "Connexion",
+
"deleteStudy" : "Supprimer l'étude",
"deleteStudyMsg" : "Etes vous sur de vouloir supprimer l'étude?",
"studyNameDidNotMatchMsg" : "Le nom d'étude donné ne correspond pas à ",
diff --git a/src/utils/authentication/AuthService.js b/src/utils/authentication/AuthService.js
new file mode 100644
index 0000000000..c0b8dcea70
--- /dev/null
+++ b/src/utils/authentication/AuthService.js
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2020, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+import {UserManager} from 'oidc-client';
+import {UserManagerMock} from "./UserManagerMock";
+import {setLoggedUser} from "../../redux/actions";
+let userManagerPromise;
+if (process.env.REACT_APP_USE_AUTHENTICATION === "true") {
+ userManagerPromise = fetch('idpSettings.json')
+ .then(r => r.json())
+ .then(idpSettings => {
+ let settings = {
+ authority: idpSettings.authority,
+ client_id: idpSettings.client_id,
+ redirect_uri: idpSettings.redirect_uri,
+ post_logout_redirect_uri: idpSettings.post_logout_redirect_uri,
+ response_mode: 'fragment',
+ response_type: 'id_token token',
+ scope: idpSettings.scope,
+ };
+ return new UserManager(settings);
+ });
+} else {
+ userManagerPromise = Promise.resolve( new UserManagerMock({}));
+}
+
+const pathKey = "powsybl-study-app-current-path";
+
+function login(location, userManagerInstance) {
+ sessionStorage.setItem(pathKey, location.pathname + location.search);
+ return userManagerInstance.signinRedirect().then(() => console.debug("login"));
+}
+
+function logout(dispatch, userManagerInstance) {
+ dispatch(setLoggedUser(null));
+ return userManagerInstance.signoutRedirect().then(
+ () => console.debug("logged out"));
+}
+
+function dispatchUser(dispatch, userManagerInstance) {
+ return userManagerInstance.getUser().then(user => {
+ if (user) {
+ console.debug('User has been successfully loaded from store.');
+ return dispatch(setLoggedUser(user));
+ } else {
+ console.debug('You are not logged in.');
+ }
+ });
+}
+
+function handleSigninCallback(dispatch, history, userManagerInstance) {
+ userManagerInstance.signinRedirectCallback().then(function () {
+ dispatchUser(dispatch, userManagerInstance);
+ const previousPath = sessionStorage.getItem(pathKey);
+ history.push(previousPath);
+ }).catch(function (e) {
+ console.error(e);
+ });
+}
+
+export {userManagerPromise, login, logout, handleSigninCallback}
diff --git a/src/utils/authentication/UserManagerMock.js b/src/utils/authentication/UserManagerMock.js
new file mode 100644
index 0000000000..c6000e4175
--- /dev/null
+++ b/src/utils/authentication/UserManagerMock.js
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2020, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+export class UserManagerMock {
+ settings;
+
+ constructor(settings) {
+ this.settings = settings;
+ }
+
+ getUser() {
+ return Promise.resolve(JSON.parse(sessionStorage.getItem("powsybl-study-app-mock-user")));
+ }
+
+ signinRedirect() {
+ window.location = "./sign-in-callback";
+ return Promise.resolve(null);
+ }
+
+ signoutRedirect() {
+ sessionStorage.setItem("powsybl-study-app-mock-user", null);
+ window.location = ".";
+ return Promise.resolve(null);
+ }
+ signinRedirectCallback() {
+ sessionStorage.setItem("powsybl-study-app-mock-user", JSON.stringify(
+ {
+ profile:{ name:"John Doe"},
+ id_token : "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IllNRUxIVDBndmIwbXhvU0RvWWZvbWpxZmpZVSJ9.eyJhdWQiOiI5YzQwMjQ2MS1iMmFiLTQ3NjctOWRiMy02Njg1OWJiMGZjZDAiLCJpc3MiOiJodHRwczovL2" +
+ "xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vNzUwMmRhZDUtZDY0Yy00NmM3LTlkNDctYjE2ZjU4MGZjZmE5L3YyLjAiLCJpYXQiOjE1ODUzMzEyNDksIm5iZiI6MTU4NTMzMTI0OSwiZXhwIjoxNTg1MzM1MTQ5LCJhaW8iOiJBV1FB" +
+ "bS84UEFBQUF3Q0xyTDRIUEUvTnVjOU9OdHN0SUV4cVpyMUlqa1FGbXJvUW5EUzJBaksyWnpneUhQTldPdkE3bitveHkvRzgxWElsb1A0TitsQjZINFJteElwakhNYVArTjIyTzVnMUFaR04yc1d6VHA5T3JWMDIvOXhndXJBMjZrdU" +
+ "NXbGg2RSIsImF0X2hhc2giOiJJaWRYdGRHdzVkbjlOZDFQblVvbDh3IiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvOTE4ODA0MGQtNmM2Ny00YzViLWIxMTItMzZhMzA0YjY2ZGFkLyIsIm5vbmNlIjoiMjkzZTcxNzhm" +
+ "OWE5NGZlNjg1ZWY3MjdlZTg5MTYxYjEiLCJzdWIiOiJyTnZjWXJMSXJSN25iSDJPQlhoOFkzU05wZEtPc3dfTUNkX3F3NF9vNDRJIiwidGlkIjoiNzUwMmRhZDUtZDY0Yy00NmM3LTlkNDctYjE2ZjU4MGZjZmE5IiwidXRpIjoiUF" +
+ "BYdkw1UWxDMG1oMGp2N3NaNGJBQSIsInZlciI6IjIuMCJ9.dPAh24KTfsqmDaRoBtMLcayAWnDqVtydQ97P1a99dg93JsDu4Jhxju9vlzvjd6Ro5a1RZdrKFKB_pgC2DkQ3wSeYjpdSNyBAlW1_ryq65JkTJVMp33OsM_7SdjaRIiJ" +
+ "fPiJ3U9jRBSyj7ofoHCLUjD_Uu-XreKxpMGhFHOQIO72UfXg8TBpsapjkEv9Dyz2UqMa2BQvO5mxKw93LNg5BI6j2a5LhbMEmmRWqfxWGITJ9TWfHjYdFkrXKcmvWZ9D2b4tsw_5NorDxkuzVFhA89M_0ASzOXoj1Yb6LgdkzWXDim" +
+ "ssvyyz5Oe4V3gdkAe8Jj7Uwz-9AR-MO2kNkH7ytHA",
+ session_state : "session state",
+ access_token : "eyJ0eXAiOiJKV1QiLCJub25jZSI6InhKWHlQeXVrU1paQ3BOeEcxZUQway1lVDF0YzZtQ01ZVkZKcnBDOTJxc28iLCJhbGciOiJSUzI1NiIsIng1dCI6IllNRUxIVDBndmIwbXhvU0RvWWZvbWpxZmpZVSIsImtpZC" +
+ "I6IllNRUxIVDBndmIwbXhvU0RvWWZvbWpxZmpZVSJ9.eyJhdWQiOiIwMDAwMDAwMy0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDAiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83NTAyZGFkNS1kNjRjLTQ2YzctOWQ" +
+ "0Ny1iMTZmNTgwZmNmYTkvIiwiaWF0IjoxNTg1MzMxMjQ5LCJuYmYiOjE1ODUzMzEyNDksImV4cCI6MTU4NTMzNTE0OSwiYWNjdCI6MCwiYWNyIjoiMSIsImFpbyI6IkFVUUF1LzhQQUFBQXdwc3RYMlVkY2VDQWx4dU9tVHpIY0R3R" +
+ "lhTWUtYanIvZUNTSi9PdTRqbTJyUVBCUml0U1dWMThmNldCVEdNdnQ5ZGx0Ry9lTXB1VXZqaTN2NCtzanh3PT0iLCJhbHRzZWNpZCI6IjE6bGl2ZS5jb206MDAwMzQwMDExOUZEOTIxMiIsImFtciI6WyJwd2QiXSwiYXBwX2Rpc3B" +
+ "sYXluYW1lIjoic3BhIiwiYXBwaWQiOiI5YzQwMjQ2MS1iMmFiLTQ3NjctOWRiMy02Njg1OWJiMGZjZDAiLCJhcHBpZGFjciI6IjAiLCJlbWFpbCI6ImNoYW1zZWRkaW5lLmJlbmhhbWVkQGVuc2ktdW1hLnRuIiwiZmFtaWx5X25hb" +
+ "WUiOiJCRU5IQU1FRCIsImdpdmVuX25hbWUiOiJDaGFtc2VkZGluZSIsImlkcCI6ImxpdmUuY29tIiwiaXBhZGRyIjoiNzcuMjA0LjE0Ni4xNTkiLCJuYW1lIjoiQ2hhbXNlZGRpbmUgQkVOSEFNRUQiLCJvaWQiOiIzNTIzYmQ3OC0" +
+ "yZjIxLTQ3ZjYtODhlOC1hYWIzYjZmMjdmNjAiLCJwbGF0ZiI6IjE0IiwicHVpZCI6IjEwMDMyMDAwOURFMDg1NkEiLCJzY3AiOiJVc2VyLlJlYWQgcHJvZmlsZSBvcGVuaWQgZW1haWwiLCJzdWIiOiJjVEd5LVlfV3FLR2x1cmRUV" +
+ "DdSUVlfY3FjSDJoVHpEdllZTmotQ3hONXA4IiwidGlkIjoiNzUwMmRhZDUtZDY0Yy00NmM3LTlkNDctYjE2ZjU4MGZjZmE5IiwidW5pcXVlX25hbWUiOiJsaXZlLmNvbSNjaGFtc2VkZGluZS5iZW5oYW1lZEBlbnNpLXVtYS50biI" +
+ "sInV0aSI6IlBQWHZMNVFsQzBtaDBqdjdzWjRiQUEiLCJ2ZXIiOiIxLjAiLCJ4bXNfc3QiOnsic3ViIjoick52Y1lyTElyUjduYkgyT0JYaDhZM1NOcGRLT3N3X01DZF9xdzRfbzQ0SSJ9LCJ4bXNfdGNkdCI6MTU4MjgyMDM1Mn0.W_" +
+ "ccOGW_AGdg37KSMi7LWHtvm3Mw5p1dHjgDIrUaXduKF2iLS4dCaPw7yeo4VjAcOyV6C0h6ABLDCtkwVt8BSDTIIU7DaT8k2bRbMCCq69BmeiYPsbp-yX6ywGCx5DHsnOLqI2oHbBQktA2Nmv9Va651Pbm3OpSPuGPdVimkFCcnisiGl" +
+ "UOej1ZMNwyVT6386O2pERPtxmFUt_D1dKLxBXxBNxLVUG5BG3bI7wMpBOHEUA5CbaBzYXmGrLMXVVbrj9OsF-WQ6aNoqsm9cicX6pJB60lFz1dxLeSgcFO7Zh2K3PFe4FnXCqAvNPadQMz_kJEO9_phlDV85c2MPqeXbA",
+ token_type : "Bearer",
+ scope : "scopes"
+
+ }
+ ));
+ return Promise.resolve("");
+ }
+}