blob: 11ba13d3390c1207dd8291478708773349eabd77 [file] [log] [blame]
Iftekharul Islamcd789502017-04-19 14:37:55 -05001/**
2 * Controller for user Accounts
3 *
4 * @module app/users
5 * @exports userAccountsController
6 * @name userAccountsController
Iftekharul Islamcd789502017-04-19 14:37:55 -05007 */
8
Andrew Geisslerba5e3f32018-05-24 10:58:00 -07009window.angular && (function(angular) {
10 'use strict';
Iftekharul Islamcd789502017-04-19 14:37:55 -050011
Andrew Geisslerd27bb132018-05-24 11:07:27 -070012 angular.module('app.users').controller('userAccountsController', [
Yoshie Muranakafa562732019-07-17 11:23:15 -050013 '$scope', 'APIUtils', 'toastService', '$uibModal',
14 function($scope, APIUtils, toastService, $uibModal) {
15 $scope.loading;
16 $scope.accountSettings;
17 $scope.userRoles;
18 $scope.localUsers;
Gunnar Mills08744f82018-03-19 16:24:41 -050019
Yoshie Muranakafa562732019-07-17 11:23:15 -050020 $scope.tableModel = {};
21 $scope.tableModel.data = [];
22 $scope.tableModel.header = ['Username', 'Privilege', 'Account status']
23 $scope.tableModel.actions = ['Edit', 'Delete'];
24
25 /**
26 * Data table mapper
27 * @param {*} user
28 */
29 function mapTableData(user) {
30 let accountStatus =
31 user.Locked ? 'Locked' : user.Enabled ? 'Enabled' : 'Disabled';
32 user.uiData = [user.UserName, user.RoleId, accountStatus];
33 return user;
34 }
35
36 /**
37 * API call to get all user accounts
38 */
39 function getLocalUsers() {
AppaRao Puli28711a62018-10-17 16:07:55 +053040 $scope.loading = true;
Yoshie Muranakafa562732019-07-17 11:23:15 -050041 APIUtils.getAllUserAccounts()
42 .then((users) => {
43 $scope.localUsers = users;
44 $scope.tableModel.data = users.map(mapTableData);
45 })
46 .catch((error) => {
47 console.log(JSON.stringify(error));
48 toastService.error('Failed to load users.');
49 })
50 .finally(() => {
51 $scope.loading = false;
52 })
53 }
AppaRao Pulia83cd052019-01-07 23:25:43 +053054
Yoshie Muranakafa562732019-07-17 11:23:15 -050055 /**
56 * API call to get current Account settings
57 */
58 function getAccountSettings() {
59 APIUtils.getAllUserAccountProperties()
60 .then((settings) => {
61 $scope.accountSettings = settings;
62 })
63 .catch((error) => {
64 console.log(JSON.stringify(error));
65 $scope.accountSettings = null;
66 })
67 }
AppaRao Pulib1e7c862019-03-12 14:56:40 +053068
Yoshie Muranakafa562732019-07-17 11:23:15 -050069 /**
70 * API call to get local user roles
71 */
72 function getUserRoles() {
73 APIUtils.getAccountServiceRoles()
74 .then((roles) => {
75 $scope.userRoles = roles;
76 })
77 .catch((error) => {
78 console.log(JSON.stringify(error));
79 $scope.userRoles = null;
80 })
81 }
AppaRao Pulib1e7c862019-03-12 14:56:40 +053082
Yoshie Muranakafa562732019-07-17 11:23:15 -050083 /**
84 * API call to create new user
85 * @param {*} user
86 */
87 function createUser(username, password, role, enabled) {
AppaRao Pulib1e7c862019-03-12 14:56:40 +053088 $scope.loading = true;
Yoshie Muranakafa562732019-07-17 11:23:15 -050089 APIUtils.createUser(username, password, role, enabled)
90 .then(() => {
91 getLocalUsers();
92 toastService.success(`User '${username}' has been created.`);
93 })
94 .catch((error) => {
95 console.log(JSON.stringify(error));
96 toastService.error(`Failed to create new user '${username}'.`);
97 })
98 .finally(() => {
AppaRao Pulib1e7c862019-03-12 14:56:40 +053099 $scope.loading = false;
100 });
Yoshie Muranakafa562732019-07-17 11:23:15 -0500101 }
AppaRao Pulib1e7c862019-03-12 14:56:40 +0530102
Yoshie Muranakafa562732019-07-17 11:23:15 -0500103 /**
104 * API call to update existing user
105 */
106 function updateUser(originalUsername, username, password, role, enabled) {
AppaRao Puli28711a62018-10-17 16:07:55 +0530107 $scope.loading = true;
Yoshie Muranakafa562732019-07-17 11:23:15 -0500108 APIUtils.updateUser(originalUsername, username, password, role, enabled)
109 .then(() => {
110 getLocalUsers();
111 toastService.success('User has been updated successfully.')
112 })
113 .catch((error) => {
114 console.log(JSON.stringify(error));
115 toastService.error(`Unable to update user '${originalUsername}'.`)
116 })
117 .finally(() => {
118 $scope.loading = false;
119 })
120 }
121
122 /**
123 * API call to delete user
124 * @param {*} username
125 */
126 function deleteUser(username) {
127 $scope.loading = true;
128 APIUtils.deleteUser(username)
129 .then(() => {
130 getLocalUsers();
131 toastService.success(`User '${username}' has been deleted.`);
132 })
133 .catch((error) => {
134 console.log(JSON.stringify(error));
135 toastService.error(`Failed to delete user '${username}'.`);
136 })
137 .finally(() => {
AppaRao Puli28711a62018-10-17 16:07:55 +0530138 $scope.loading = false;
Gunnar Millsb3d48d42018-05-25 08:34:35 -0500139 });
Yoshie Muranakafa562732019-07-17 11:23:15 -0500140 }
AppaRao Puli28711a62018-10-17 16:07:55 +0530141
Yoshie Muranakafa562732019-07-17 11:23:15 -0500142 /**
143 * API call to save account policy settings
144 * @param {number} lockoutDuration
145 * @param {number} lockoutThreshold
146 */
147 function updateAccountSettings(lockoutDuration, lockoutThreshold) {
AppaRao Puli28711a62018-10-17 16:07:55 +0530148 $scope.loading = true;
Yoshie Muranakafa562732019-07-17 11:23:15 -0500149 APIUtils.saveUserAccountProperties(lockoutDuration, lockoutThreshold)
150 .then(() => {
151 $scope.accountSettings['AccountLockoutDuration'] =
152 lockoutDuration;
153 $scope.accountSettings['AccountLockoutThreshold'] =
154 lockoutThreshold;
155 toastService.success(
156 'Account policy settings have been updated.');
157 })
158 .catch((error) => {
159 console.log(JSON.stringify(error));
160 toastService.error('Failed to update account policy settings.');
161 })
162 .finally(() => {
AppaRao Puli28711a62018-10-17 16:07:55 +0530163 $scope.loading = false;
164 });
Yoshie Muranakafa562732019-07-17 11:23:15 -0500165 }
AppaRao Pulicf7219c2018-12-27 16:17:46 +0530166
Yoshie Muranakafa562732019-07-17 11:23:15 -0500167 /**
168 * Initiate account settings modal
169 */
170 function initAccountSettingsModal() {
171 const template = require('./user-accounts-modal-settings.html');
172 $uibModal
173 .open({
174 template,
175 windowTopClass: 'uib-modal',
176 ariaLabelledBy: 'dialog_label',
177 controllerAs: 'modalCtrl',
178 controller: function() {
179 // If AccountLockoutDuration is not 0 the lockout
180 // method is automatic. If AccountLockoutDuration is 0 the
181 // lockout method is manual
182 const lockoutMethod =
183 $scope.accountSettings.AccountLockoutDuration ? 1 : 0;
184 this.settings = {};
185 this.settings.maxLogin =
186 $scope.accountSettings.AccountLockoutThreshold;
187 this.settings.lockoutMethod = lockoutMethod;
188 this.settings.timeoutDuration = !lockoutMethod ?
189 null :
190 $scope.accountSettings.AccountLockoutDuration;
191 }
192 })
193 .result
194 .then((form) => {
195 if (form.$valid) {
196 const lockoutDuration = form.lockoutMethod.$modelValue ?
197 form.timeoutDuration.$modelValue :
198 0;
199 const lockoutThreshold = form.maxLogin.$modelValue;
200 updateAccountSettings(lockoutDuration, lockoutThreshold);
201 }
202 })
203 .catch(
204 () => {
205 // do nothing
206 })
207 }
208
209 /**
210 * Initiate user modal
211 * Can be triggered by clicking edit in table or 'Add user' button
212 * If triggered from the table, user parameter will be provided
213 * If triggered by add user button, user parameter will be undefined
214 * @optional @param {*} user
215 */
216 function initUserModal(user) {
217 if ($scope.userRoles === null || $scope.userRoles === undefined) {
218 // If userRoles failed to load, do not allow add/edit
219 // functionality
220 return;
221 }
222 const newUser = user ? false : true;
223 const originalUsername = user ? angular.copy(user.UserName) : null;
224 const template = require('./user-accounts-modal-user.html');
225 $uibModal
226 .open({
227 template,
228 windowTopClass: 'uib-modal',
229 ariaLabelledBy: 'dialog_label',
230 controllerAs: 'modalCtrl',
231 controller: function() {
232 // Set default status to Enabled
233 const status = newUser ? true : user.Enabled;
234 // Check if UserName is root
235 // Some form controls will be disabled for root users:
236 // edit enabled status, edit username, edit role
237 const isRoot =
238 newUser ? false : user.UserName === 'root' ? true : false;
239 // Array of existing usernames (excluding current user instance)
240 const existingUsernames =
241 $scope.localUsers.reduce((acc, val) => {
242 if (user && (val.UserName === user.UserName)) {
243 return acc;
244 }
245 acc.push(val.UserName);
246 return acc;
247 }, []);
248
249 this.user = {};
250 this.user.isRoot = isRoot;
251 this.user.new = newUser;
252 this.user.accountStatus = status;
253 this.user.username = newUser ? '' : user.UserName;
254 this.user.privilege = newUser ? '' : user.RoleId;
255
256 this.privilegeRoles = $scope.userRoles;
257 this.existingUsernames = existingUsernames;
258 this.minPasswordLength = $scope.accountSettings ?
259 $scope.accountSettings.MinPasswordLength :
260 null;
261 this.maxPasswordLength = $scope.accountSettings ?
262 $scope.accountSettings.MaxPasswordLength :
263 null;
264 }
265 })
266 .result
267 .then((form) => {
268 if (form.$valid) {
269 // If form control is pristine set property to null
270 // this will make sure only changed values are updated when
271 // modifying existing users
272 // API utils checks for null values
273 const username =
274 form.username.$pristine ? null : form.username.$modelValue;
275 const password =
276 form.password.$pristine ? null : form.password.$modelValue;
277 const role = form.privilege.$pristine ?
278 null :
279 form.privilege.$modelValue;
280 const enabled = (form.accountStatus.$pristine &&
281 form.accountStatus1.$pristine) ?
282 null :
283 form.accountStatus.$modelValue;
284
285 if (!newUser) {
286 updateUser(
287 originalUsername, username, password, role, enabled);
288 } else {
289 createUser(
290 username, password, role, form.accountStatus.$modelValue);
291 }
292 }
293 })
294 .catch(
295 () => {
296 // do nothing
297 })
298 }
299
300 /**
301 * Intiate remove user modal
302 * @param {*} user
303 */
304 function initRemoveModal(user) {
305 const template = require('./user-accounts-modal-remove.html');
306 $uibModal
307 .open({
308 template,
309 windowTopClass: 'uib-modal',
310 ariaLabelledBy: 'dialog_label',
311 controllerAs: 'modalCtrl',
312 controller: function() {
313 this.user = user.UserName;
314 }
315 })
316 .result
317 .then(() => {
318 const isRoot = user.UserName === 'root' ? true : false;
319 if (isRoot) {
320 toastService.error(`Cannot delete 'root' user.`)
321 return;
322 }
323 deleteUser(user.UserName);
324 })
325 .catch(
326 () => {
327 // do nothing
328 })
329 }
330
331 /**
332 * Callback when action emitted from table
333 * @param {*} value
334 */
335 $scope.onEmitAction = (value) => {
336 switch (value.action) {
337 case 'Edit':
338 initUserModal(value.row);
339 break;
340 case 'Delete':
341 initRemoveModal(value.row);
342 break;
343 default:
beccabroeka5deeea2019-03-22 15:38:49 -0500344 }
345 };
Yoshie Muranakafa562732019-07-17 11:23:15 -0500346
347 /**
348 * Callback when 'Account settings policy' button clicked
349 */
350 $scope.onClickAccountSettingsPolicy = () => {
351 initAccountSettingsModal();
352 };
353
354 /**
355 * Callback when 'Add user' button clicked
356 */
357 $scope.onClickAddUser = () => {
358 initUserModal();
359 };
360
361 /**
362 * Callback when controller view initially loaded
363 */
364 $scope.$on('$viewContentLoaded', () => {
365 getLocalUsers();
366 getUserRoles();
367 getAccountSettings();
368 })
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700369 }
370 ]);
Iftekharul Islamcd789502017-04-19 14:37:55 -0500371})(angular);