xref: /openbmc/webui-vue/src/store/modules/Authentication/AuthenticanStore.js (revision ce7db82c9582c4dac04ac81d9af6b557ae7965e3)
16de03414SPaul Fertserimport api, { isPasswordExpired } from '@/store/api';
2fded0d11SDerick Montagueimport Cookies from 'js-cookie';
361859097SSurenNewareimport router from '@/router';
42b33526cSPaul Fertserimport { roles } from '@/router/routes';
5e080a1a7SDerick Montague
6e080a1a7SDerick Montagueconst AuthenticationStore = {
7e080a1a7SDerick Montague  namespaced: true,
8e080a1a7SDerick Montague  state: {
9b89eed27Skirankumarb07    consoleWindow: null,
104b0fc1dbSYoshie Muranaka    authError: false,
11d624dae9SYoshie Muranaka    xsrfCookie: Cookies.get('XSRF-TOKEN'),
12602e98aaSDerick Montague    isAuthenticatedCookie: Cookies.get('IsAuthenticated'),
131ff8e89fSPaul Fertser    sessionURI: localStorage.getItem('sessionURI'),
1409a3b9e0SPaul Fertser    xAuthToken: null,
15e080a1a7SDerick Montague  },
16e080a1a7SDerick Montague  getters: {
17b89eed27Skirankumarb07    consoleWindow: (state) => state.consoleWindow,
18602e98aaSDerick Montague    authError: (state) => state.authError,
19602e98aaSDerick Montague    isLoggedIn: (state) => {
201ff8e89fSPaul Fertser      // We might have gotten XSRF-TOKEN (and HttpOnly SESSION cookie) by Mutual TLS authentication,
211ff8e89fSPaul Fertser      // without going through explicit Session creation
22d624dae9SYoshie Muranaka      return (
2309a3b9e0SPaul Fertser        state.xsrfCookie !== undefined ||
2409a3b9e0SPaul Fertser        state.isAuthenticatedCookie == 'true' ||
2509a3b9e0SPaul Fertser        state.xAuthToken !== null
26d624dae9SYoshie Muranaka      );
27d624dae9SYoshie Muranaka    },
281ff8e89fSPaul Fertser    // Used to authenticate WebSocket connections via subprotocol value
29602e98aaSDerick Montague    token: (state) => state.xsrfCookie,
30e080a1a7SDerick Montague  },
31e080a1a7SDerick Montague  mutations: {
3209a3b9e0SPaul Fertser    authSuccess(state, { session, token }) {
334b0fc1dbSYoshie Muranaka      state.authError = false;
34d624dae9SYoshie Muranaka      state.xsrfCookie = Cookies.get('XSRF-TOKEN');
351ff8e89fSPaul Fertser      // Preserve session data across page reloads and browser restarts
361ff8e89fSPaul Fertser      localStorage.setItem('sessionURI', session);
371ff8e89fSPaul Fertser      state.sessionURI = session;
3809a3b9e0SPaul Fertser      // If we didn't get the XSRF cookie it means we are talking to a
3909a3b9e0SPaul Fertser      // Redfish implementation that is not bmcweb. In this case get the token
4009a3b9e0SPaul Fertser      // from headers and send it with the future requests, do not permanently
4109a3b9e0SPaul Fertser      // save anywhere.
4209a3b9e0SPaul Fertser      if (state.xsrfCookie === undefined) {
4309a3b9e0SPaul Fertser        api.set_auth_token(token);
4409a3b9e0SPaul Fertser        state.xAuthToken = token;
4509a3b9e0SPaul Fertser      }
46e080a1a7SDerick Montague    },
47a06fe469SDerick Montague    authError(state, authError = true) {
48a06fe469SDerick Montague      state.authError = authError;
49676f2fcaSDerick Montague    },
50d624dae9SYoshie Muranaka    logout(state) {
51fded0d11SDerick Montague      Cookies.remove('XSRF-TOKEN');
52d624dae9SYoshie Muranaka      Cookies.remove('IsAuthenticated');
5309a3b9e0SPaul Fertser      api.set_auth_token(undefined);
54b1f559f0SSukanya Pandey      localStorage.removeItem('storedUsername');
55d624dae9SYoshie Muranaka      state.xsrfCookie = undefined;
56d624dae9SYoshie Muranaka      state.isAuthenticatedCookie = undefined;
571ff8e89fSPaul Fertser      localStorage.removeItem('sessionURI');
581ff8e89fSPaul Fertser      state.sessionURI = null;
5909a3b9e0SPaul Fertser      state.xAuthToken = null;
601ff8e89fSPaul Fertser      state.consoleWindow = false;
61602e98aaSDerick Montague    },
62e080a1a7SDerick Montague  },
63e080a1a7SDerick Montague  actions: {
64d624dae9SYoshie Muranaka    login({ commit }, { username, password }) {
65a06fe469SDerick Montague      commit('authError', false);
66e080a1a7SDerick Montague      return api
671ff8e89fSPaul Fertser        .post('/redfish/v1/SessionService/Sessions', {
681ff8e89fSPaul Fertser          UserName: username,
691ff8e89fSPaul Fertser          Password: password,
70ebef6eeeSEd Tanous        })
71*ce7db82cSPaul Fertser        .then(({ headers, data }) => {
721ff8e89fSPaul Fertser          commit('authSuccess', {
73*ce7db82cSPaul Fertser            session: headers['location'],
74*ce7db82cSPaul Fertser            token: headers['x-auth-token'],
751ff8e89fSPaul Fertser          });
76*ce7db82cSPaul Fertser          setSessionPrivilege(commit, data);
77*ce7db82cSPaul Fertser          return isPasswordExpired(data);
781ff8e89fSPaul Fertser        })
79602e98aaSDerick Montague        .catch((error) => {
80fded0d11SDerick Montague          commit('authError');
81e080a1a7SDerick Montague          throw new Error(error);
82e080a1a7SDerick Montague        });
83e080a1a7SDerick Montague    },
841ff8e89fSPaul Fertser    logout({ commit, state }) {
856ce1a07cSYoshie Muranaka      api
861ff8e89fSPaul Fertser        .delete(state.sessionURI)
87*ce7db82cSPaul Fertser        .catch(() =>
88*ce7db82cSPaul Fertser          console.log(
89*ce7db82cSPaul Fertser            "Couldn't DELETE Session, proceeding with the logout anyway to get in sync with the backend.",
90*ce7db82cSPaul Fertser          ),
91*ce7db82cSPaul Fertser        )
921ff8e89fSPaul Fertser        .then(() => commit('logout'))
93780733a1SThang Q. Nguyen        .then(() => router.push('/login'))
94602e98aaSDerick Montague        .catch((error) => console.log(error));
952c98b095SYoshie Muranaka    },
96*ce7db82cSPaul Fertser    getSessionPrivilege({ commit, state }) {
97aeb19816SDamian Celico      return api
98*ce7db82cSPaul Fertser        .get(state.sessionURI)
99*ce7db82cSPaul Fertser        .then(({ data }) => setSessionPrivilege(commit, data));
100d624dae9SYoshie Muranaka    },
101d624dae9SYoshie Muranaka    resetStoreState({ state }) {
102d624dae9SYoshie Muranaka      state.authError = false;
103d624dae9SYoshie Muranaka      state.xsrfCookie = Cookies.get('XSRF-TOKEN');
104d624dae9SYoshie Muranaka      state.isAuthenticatedCookie = Cookies.get('IsAuthenticated');
105602e98aaSDerick Montague    },
106602e98aaSDerick Montague  },
107e080a1a7SDerick Montague};
108e080a1a7SDerick Montague
109*ce7db82cSPaul Fertserconst setSessionPrivilege = (commit, data) => {
110*ce7db82cSPaul Fertser  // If the backend didn't provide the role information in the Session object
111*ce7db82cSPaul Fertser  // our best bet is to assume the Administrator role to avoid hiding
112*ce7db82cSPaul Fertser  // potentially useful UI elements. Everything security-sensitive is validated
113*ce7db82cSPaul Fertser  // on the backend side anyway, so this is safe.
114*ce7db82cSPaul Fertser  commit('global/setPrivilege', data.Roles?.[0] ?? roles.administrator, {
115*ce7db82cSPaul Fertser    root: true,
116*ce7db82cSPaul Fertser  });
117*ce7db82cSPaul Fertser};
118*ce7db82cSPaul Fertser
119e080a1a7SDerick Montagueexport default AuthenticationStore;
120