1import api, { getResponseCount } from '@/store/api';
2import i18n from '@/i18n';
3
4const getServerErrorMessages = function (error) {
5  let errorData = error.response.data.error
6    ? error.response.data.error
7    : error.response.data;
8  if (typeof errorData == 'string') {
9    return [];
10  }
11  return Object.values(errorData)
12    .reduce((a, b) => a.concat(b))
13    .filter((info) => info.Message)
14    .map((info) => info.Message);
15};
16
17const UserManagementStore = {
18  namespaced: true,
19  state: {
20    allUsers: [],
21    accountRoles: [],
22    accountLockoutDuration: null,
23    accountLockoutThreshold: null,
24    accountMinPasswordLength: null,
25    accountMaxPasswordLength: null,
26  },
27  getters: {
28    allUsers(state) {
29      return state.allUsers;
30    },
31    accountRoles(state) {
32      return state.accountRoles;
33    },
34    accountSettings(state) {
35      return {
36        lockoutDuration: state.accountLockoutDuration,
37        lockoutThreshold: state.accountLockoutThreshold,
38      };
39    },
40    accountPasswordRequirements(state) {
41      return {
42        minLength: state.accountMinPasswordLength,
43        maxLength: state.accountMaxPasswordLength,
44      };
45    },
46  },
47  mutations: {
48    setUsers(state, allUsers) {
49      state.allUsers = allUsers;
50    },
51    setAccountRoles(state, accountRoles) {
52      state.accountRoles = accountRoles;
53    },
54    setLockoutDuration(state, lockoutDuration) {
55      state.accountLockoutDuration = lockoutDuration;
56    },
57    setLockoutThreshold(state, lockoutThreshold) {
58      state.accountLockoutThreshold = lockoutThreshold;
59    },
60    setAccountMinPasswordLength(state, minPasswordLength) {
61      state.accountMinPasswordLength = minPasswordLength;
62    },
63    setAccountMaxPasswordLength(state, maxPasswordLength) {
64      state.accountMaxPasswordLength = maxPasswordLength;
65    },
66  },
67  actions: {
68    async getUsers({ commit }) {
69      return await api
70        .get('/redfish/v1/AccountService/Accounts')
71        .then((response) =>
72          response.data.Members.map((user) => user['@odata.id']),
73        )
74        .then((userIds) => api.all(userIds.map((user) => api.get(user))))
75        .then((users) => {
76          const userData = users.map((user) => user.data);
77          commit('setUsers', userData);
78        })
79        .catch((error) => {
80          console.log(error);
81          const message = i18n.t('pageUserManagement.toast.errorLoadUsers');
82          throw new Error(message);
83        });
84    },
85    getAccountSettings({ commit }) {
86      api
87        .get('/redfish/v1/AccountService')
88        .then(({ data }) => {
89          commit('setLockoutDuration', data.AccountLockoutDuration);
90          commit('setLockoutThreshold', data.AccountLockoutThreshold);
91          commit('setAccountMinPasswordLength', data.MinPasswordLength);
92          commit('setAccountMaxPasswordLength', data.MaxPasswordLength);
93        })
94        .catch((error) => {
95          console.log(error);
96          const message = i18n.t(
97            'pageUserManagement.toast.errorLoadAccountSettings',
98          );
99          throw new Error(message);
100        });
101    },
102    getAccountRoles({ commit }) {
103      api
104        .get('/redfish/v1/AccountService/Roles')
105        .then(({ data: { Members = [] } = {} }) => {
106          const roles = Members.map((role) => {
107            return role['@odata.id'].split('/').pop();
108          });
109          commit('setAccountRoles', roles);
110        })
111        .catch((error) => console.log(error));
112    },
113    async createUser({ dispatch }, { username, password, privilege, status }) {
114      const data = {
115        UserName: username,
116        Password: password,
117        RoleId: privilege,
118        Enabled: status,
119      };
120      return await api
121        .post('/redfish/v1/AccountService/Accounts', data)
122        .then(() => dispatch('getUsers'))
123        .then(() =>
124          i18n.t('pageUserManagement.toast.successCreateUser', {
125            username,
126          }),
127        )
128        .catch((error) => {
129          let serverMessages = getServerErrorMessages(error);
130          let message =
131            serverMessages.length > 0
132              ? serverMessages.join(' ')
133              : i18n.t('pageUserManagement.toast.errorCreateUser', {
134                  username: username,
135                });
136          throw new Error(message);
137        });
138    },
139    async updateUser(
140      { dispatch },
141      { originalUsername, username, password, privilege, status, locked },
142    ) {
143      const data = {};
144      if (username) data.UserName = username;
145      if (password) data.Password = password;
146      if (privilege) data.RoleId = privilege;
147      if (status !== undefined) data.Enabled = status;
148      if (locked !== undefined) data.Locked = locked;
149      return await api
150        .patch(`/redfish/v1/AccountService/Accounts/${originalUsername}`, data)
151        .then(() => dispatch('getUsers'))
152        .then(() =>
153          i18n.t('pageUserManagement.toast.successUpdateUser', {
154            username: originalUsername,
155          }),
156        )
157        .catch((error) => {
158          console.log(error);
159          const serverMessages = getServerErrorMessages(error);
160          const message =
161            serverMessages.length > 0
162              ? serverMessages.join(' ')
163              : i18n.t('pageUserManagement.toast.errorUpdateUser', {
164                  username: originalUsername,
165                });
166          throw new Error(message);
167        });
168    },
169    async deleteUser({ dispatch }, username) {
170      return await api
171        .delete(`/redfish/v1/AccountService/Accounts/${username}`)
172        .then(() => dispatch('getUsers'))
173        .then(() =>
174          i18n.t('pageUserManagement.toast.successDeleteUser', {
175            username,
176          }),
177        )
178        .catch((error) => {
179          console.log(error);
180          const message = i18n.t('pageUserManagement.toast.errorDeleteUser', {
181            username,
182          });
183          throw new Error(message);
184        });
185    },
186    async deleteUsers({ dispatch }, users) {
187      const promises = users.map(({ username }) => {
188        return api
189          .delete(`/redfish/v1/AccountService/Accounts/${username}`)
190          .catch((error) => {
191            console.log(error);
192            return error;
193          });
194      });
195      return await api
196        .all(promises)
197        .then((response) => {
198          dispatch('getUsers');
199          return response;
200        })
201        .then(
202          api.spread((...responses) => {
203            const { successCount, errorCount } = getResponseCount(responses);
204            let toastMessages = [];
205
206            if (successCount) {
207              const message = i18n.tc(
208                'pageUserManagement.toast.successBatchDelete',
209                successCount,
210              );
211              toastMessages.push({ type: 'success', message });
212            }
213
214            if (errorCount) {
215              const message = i18n.tc(
216                'pageUserManagement.toast.errorBatchDelete',
217                errorCount,
218              );
219              toastMessages.push({ type: 'error', message });
220            }
221
222            return toastMessages;
223          }),
224        );
225    },
226    async enableUsers({ dispatch }, users) {
227      const data = {
228        Enabled: true,
229      };
230      const promises = users.map(({ username }) => {
231        return api
232          .patch(`/redfish/v1/AccountService/Accounts/${username}`, data)
233          .catch((error) => {
234            console.log(error);
235            return error;
236          });
237      });
238      return await api
239        .all(promises)
240        .then((response) => {
241          dispatch('getUsers');
242          return response;
243        })
244        .then(
245          api.spread((...responses) => {
246            const { successCount, errorCount } = getResponseCount(responses);
247            let toastMessages = [];
248
249            if (successCount) {
250              const message = i18n.tc(
251                'pageUserManagement.toast.successBatchEnable',
252                successCount,
253              );
254              toastMessages.push({ type: 'success', message });
255            }
256
257            if (errorCount) {
258              const message = i18n.tc(
259                'pageUserManagement.toast.errorBatchEnable',
260                errorCount,
261              );
262              toastMessages.push({ type: 'error', message });
263            }
264
265            return toastMessages;
266          }),
267        );
268    },
269    async disableUsers({ dispatch }, users) {
270      const data = {
271        Enabled: false,
272      };
273      const promises = users.map(({ username }) => {
274        return api
275          .patch(`/redfish/v1/AccountService/Accounts/${username}`, data)
276          .catch((error) => {
277            console.log(error);
278            return error;
279          });
280      });
281      return await api
282        .all(promises)
283        .then((response) => {
284          dispatch('getUsers');
285          return response;
286        })
287        .then(
288          api.spread((...responses) => {
289            const { successCount, errorCount } = getResponseCount(responses);
290            let toastMessages = [];
291
292            if (successCount) {
293              const message = i18n.tc(
294                'pageUserManagement.toast.successBatchDisable',
295                successCount,
296              );
297              toastMessages.push({ type: 'success', message });
298            }
299
300            if (errorCount) {
301              const message = i18n.tc(
302                'pageUserManagement.toast.errorBatchDisable',
303                errorCount,
304              );
305              toastMessages.push({ type: 'error', message });
306            }
307
308            return toastMessages;
309          }),
310        );
311    },
312    async saveAccountSettings(
313      { dispatch },
314      { lockoutThreshold, lockoutDuration },
315    ) {
316      const data = {};
317      if (lockoutThreshold !== undefined) {
318        data.AccountLockoutThreshold = lockoutThreshold;
319      }
320      if (lockoutDuration !== undefined) {
321        data.AccountLockoutDuration = lockoutDuration;
322      }
323
324      return await api
325        .patch('/redfish/v1/AccountService', data)
326        //GET new settings to update view
327        .then(() => dispatch('getAccountSettings'))
328        .then(() => i18n.t('pageUserManagement.toast.successSaveSettings'))
329        .catch((error) => {
330          console.log(error);
331          const message = i18n.t('pageUserManagement.toast.errorSaveSettings');
332          throw new Error(message);
333        });
334    },
335  },
336};
337
338export default UserManagementStore;
339