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.global.t(
82            'pageUserManagement.toast.errorLoadUsers',
83          );
84          throw new Error(message);
85        });
86    },
87    getAccountSettings({ commit }) {
88      api
89        .get('/redfish/v1/AccountService')
90        .then(({ data }) => {
91          commit('setLockoutDuration', data.AccountLockoutDuration);
92          commit('setLockoutThreshold', data.AccountLockoutThreshold);
93          commit('setAccountMinPasswordLength', data.MinPasswordLength);
94          commit('setAccountMaxPasswordLength', data.MaxPasswordLength);
95        })
96        .catch((error) => {
97          console.log(error);
98          const message = i18n.global.t(
99            'pageUserManagement.toast.errorLoadAccountSettings',
100          );
101          throw new Error(message);
102        });
103    },
104    getAccountRoles({ commit }) {
105      api
106        .get('/redfish/v1/AccountService/Roles')
107        .then(({ data: { Members = [] } = {} }) => {
108          const roles = Members.map((role) => {
109            return role['@odata.id'].split('/').pop();
110          });
111          commit('setAccountRoles', roles);
112        })
113        .catch((error) => console.log(error));
114    },
115    async createUser({ dispatch }, { username, password, privilege, status }) {
116      const data = {
117        UserName: username,
118        Password: password,
119        RoleId: privilege,
120        Enabled: status,
121      };
122      return await api
123        .post('/redfish/v1/AccountService/Accounts', data)
124        .then(() => dispatch('getUsers'))
125        .then(() =>
126          i18n.global.t('pageUserManagement.toast.successCreateUser', {
127            username,
128          }),
129        )
130        .catch((error) => {
131          let serverMessages = getServerErrorMessages(error);
132          let message =
133            serverMessages.length > 0
134              ? serverMessages.join(' ')
135              : i18n.global.t('pageUserManagement.toast.errorCreateUser', {
136                  username: username,
137                });
138          throw new Error(message);
139        });
140    },
141    async updateUser(
142      { dispatch },
143      { originalUsername, username, password, privilege, status, locked },
144    ) {
145      const data = {};
146      if (username) data.UserName = username;
147      if (password) data.Password = password;
148      if (privilege) data.RoleId = privilege;
149      if (status !== undefined) data.Enabled = status;
150      if (locked !== undefined) data.Locked = locked;
151      return await api
152        .patch(`/redfish/v1/AccountService/Accounts/${originalUsername}`, data)
153        .then(() => dispatch('getUsers'))
154        .then(() =>
155          i18n.global.t('pageUserManagement.toast.successUpdateUser', {
156            username: originalUsername,
157          }),
158        )
159        .catch((error) => {
160          console.log(error);
161          const serverMessages = getServerErrorMessages(error);
162          const message =
163            serverMessages.length > 0
164              ? serverMessages.join(' ')
165              : i18n.global.t('pageUserManagement.toast.errorUpdateUser', {
166                  username: originalUsername,
167                });
168          throw new Error(message);
169        });
170    },
171    async deleteUser({ dispatch }, username) {
172      return await api
173        .delete(`/redfish/v1/AccountService/Accounts/${username}`)
174        .then(() => dispatch('getUsers'))
175        .then(() =>
176          i18n.global.t('pageUserManagement.toast.successDeleteUser', {
177            username,
178          }),
179        )
180        .catch((error) => {
181          console.log(error);
182          const message = i18n.global.t(
183            'pageUserManagement.toast.errorDeleteUser',
184            {
185              username,
186            },
187          );
188          throw new Error(message);
189        });
190    },
191    async deleteUsers({ dispatch }, users) {
192      const promises = users.map(({ username }) => {
193        return api
194          .delete(`/redfish/v1/AccountService/Accounts/${username}`)
195          .catch((error) => {
196            console.log(error);
197            return error;
198          });
199      });
200      return await api
201        .all(promises)
202        .then((response) => {
203          dispatch('getUsers');
204          return response;
205        })
206        .then(
207          api.spread((...responses) => {
208            const { successCount, errorCount } = getResponseCount(responses);
209            let toastMessages = [];
210
211            if (successCount) {
212              const message = i18n.global.t(
213                'pageUserManagement.toast.successBatchDelete',
214                successCount,
215              );
216              toastMessages.push({ type: 'success', message });
217            }
218
219            if (errorCount) {
220              const message = i18n.global.t(
221                'pageUserManagement.toast.errorBatchDelete',
222                errorCount,
223              );
224              toastMessages.push({ type: 'error', message });
225            }
226
227            return toastMessages;
228          }),
229        );
230    },
231    async enableUsers({ dispatch }, users) {
232      const data = {
233        Enabled: true,
234      };
235      const promises = users.map(({ username }) => {
236        return api
237          .patch(`/redfish/v1/AccountService/Accounts/${username}`, data)
238          .catch((error) => {
239            console.log(error);
240            return error;
241          });
242      });
243      return await api
244        .all(promises)
245        .then((response) => {
246          dispatch('getUsers');
247          return response;
248        })
249        .then(
250          api.spread((...responses) => {
251            const { successCount, errorCount } = getResponseCount(responses);
252            let toastMessages = [];
253
254            if (successCount) {
255              const message = i18n.global.t(
256                'pageUserManagement.toast.successBatchEnable',
257                successCount,
258              );
259              toastMessages.push({ type: 'success', message });
260            }
261
262            if (errorCount) {
263              const message = i18n.global.t(
264                'pageUserManagement.toast.errorBatchEnable',
265                errorCount,
266              );
267              toastMessages.push({ type: 'error', message });
268            }
269
270            return toastMessages;
271          }),
272        );
273    },
274    async disableUsers({ dispatch }, users) {
275      const data = {
276        Enabled: false,
277      };
278      const promises = users.map(({ username }) => {
279        return api
280          .patch(`/redfish/v1/AccountService/Accounts/${username}`, data)
281          .catch((error) => {
282            console.log(error);
283            return error;
284          });
285      });
286      return await api
287        .all(promises)
288        .then((response) => {
289          dispatch('getUsers');
290          return response;
291        })
292        .then(
293          api.spread((...responses) => {
294            const { successCount, errorCount } = getResponseCount(responses);
295            let toastMessages = [];
296
297            if (successCount) {
298              const message = i18n.global.t(
299                'pageUserManagement.toast.successBatchDisable',
300                successCount,
301              );
302              toastMessages.push({ type: 'success', message });
303            }
304
305            if (errorCount) {
306              const message = i18n.global.t(
307                'pageUserManagement.toast.errorBatchDisable',
308                errorCount,
309              );
310              toastMessages.push({ type: 'error', message });
311            }
312
313            return toastMessages;
314          }),
315        );
316    },
317    async saveAccountSettings(
318      { dispatch },
319      { lockoutThreshold, lockoutDuration },
320    ) {
321      const data = {};
322      if (lockoutThreshold !== undefined) {
323        data.AccountLockoutThreshold = lockoutThreshold;
324      }
325      if (lockoutDuration !== undefined) {
326        data.AccountLockoutDuration = lockoutDuration;
327      }
328
329      return await api
330        .patch('/redfish/v1/AccountService', data)
331        //GET new settings to update view
332        .then(() => dispatch('getAccountSettings'))
333        .then(() =>
334          i18n.global.t('pageUserManagement.toast.successSaveSettings'),
335        )
336        .catch((error) => {
337          console.log(error);
338          const message = i18n.global.t(
339            'pageUserManagement.toast.errorSaveSettings',
340          );
341          throw new Error(message);
342        });
343    },
344  },
345};
346
347export default UserManagementStore;
348