1/**
2 * Controller for LDAP
3 *
4 * @module app/access-control
5 * @exports ldapController
6 * @name ldapController
7 */
8
9window.angular && (function(angular) {
10  'use strict';
11
12  angular.module('app.accessControl').controller('ldapController', [
13    '$scope', 'APIUtils', '$q', 'toastService',
14    function($scope, APIUtils, $q, toastService) {
15      $scope.loading = false;
16      $scope.isSecure = false;
17      $scope.ldapProperties = {};
18      $scope.originalLdapProperties = {};
19      $scope.submitted = false;
20      $scope.roleGroups = [];
21      $scope.roleGroupType = '';
22      $scope.ldapCertExpiration = '';
23      $scope.caCertExpiration = '';
24
25      $scope.$on('$viewContentLoaded', function() {
26        $scope.loadLdap();
27      });
28
29      $scope.loadLdap = function() {
30        $scope.loading = true;
31        $scope.submitted = false;
32        const ldapAccountProperties =
33            APIUtils.getAllUserAccountProperties().then(
34                function(data) {
35                  const serviceEnabled = data.LDAP.ServiceEnabled ||
36                      data.ActiveDirectory.ServiceEnabled;
37                  const ldapServiceEnabled = data.LDAP.ServiceEnabled;
38                  const adServiceEnabled = data.ActiveDirectory.ServiceEnabled;
39                  const enabledServiceType = getEnabledServiceType(data);
40                  const serviceAddresses = getServiceAddresses(data);
41                  const useSSL = getUseSsl(data);
42                  const userName = getUsername(data);
43                  const baseDistinguishedNames =
44                      getBaseDistinguishedNames(data);
45                  const groupsAttribute = getGroupsAttribute(data);
46                  const usernameAttribute = getUsernameAttribute(data);
47                  const authenticationType = getAuthenticationType(data);
48                  const roleGroups = getRoleGroups(data);
49
50
51                  return {
52                    'ServiceEnabled': serviceEnabled,
53                    'LDAPServiceEnabled': ldapServiceEnabled,
54                    'ADServiceEnabled': adServiceEnabled,
55                    'EnabledServiceType': enabledServiceType,
56                    'ServiceAddresses': serviceAddresses,
57                    'useSSL': useSSL,
58                    'Username': userName,
59                    'BaseDistinguishedNames': baseDistinguishedNames,
60                    'GroupsAttribute': groupsAttribute,
61                    'UsernameAttribute': usernameAttribute,
62                    'AuthenticationType': authenticationType,
63                    'RoleGroups': roleGroups
64                  };
65                },
66                function(error) {
67                  console.log(JSON.stringify(error));
68                });
69
70        const ldapCertificate =
71            getCertificate('/redfish/v1/AccountService/LDAP/Certificates');
72
73        const caCertificate =
74            getCertificate('/redfish/v1/Managers/bmc/Truststore/Certificates/');
75
76        const promises =
77            [ldapAccountProperties, ldapCertificate, caCertificate];
78        $q.all(promises).then(function(results) {
79          $scope.ldapProperties = results[0];
80          $scope.originalLdapProperties = angular.copy(results[0]);
81          $scope.roleGroupType = results[0].EnabledServiceType;
82          $scope.roleGroups = results[0].RoleGroups;
83          $scope.ldapCertificate = results[1];
84          $scope.caCertificate = results[2];
85          $scope.loading = false;
86        });
87      };
88
89      /**
90       * Save LDAP settings
91       * Will be making two calls every time to accomodate the backend design
92       * LDAP and ActiveDirectory changes can not be sent together when changing
93       * from ActiveDirectory to LDAP
94       */
95      $scope.saveLdapSettings = function() {
96        const enabledServiceType = $scope.ldapProperties.EnabledServiceType;
97        const enabledServicePayload =
98            createLdapEnableRequest(enabledServiceType, $scope.ldapProperties);
99        const disabledServiceType =
100            enabledServiceType == 'LDAP' ? 'ActiveDirectory' : 'LDAP';
101        const disabledServicePayload =
102            createLdapDisableRequest(disabledServiceType);
103
104        APIUtils.saveLdapProperties(disabledServicePayload)
105            .then(function(response) {
106              return APIUtils.saveLdapProperties(enabledServicePayload);
107            })
108            .then(
109                function(response) {
110                  if (!response.data.hasOwnProperty('error')) {
111                    toastService.success('Successfully updated LDAP settings.');
112                    $scope.loadLdap();
113                  } else {
114                    // The response returned a 200 but there was an error
115                    // property sent in the response. It is unclear what
116                    // settings were saved. Reloading LDAP to make it clear
117                    // to the user.
118                    toastService.error('Unable to update all LDAP settings.');
119                    $scope.loadLdap();
120                    console.log(response.data.error.message);
121                  }
122                },
123                function(error) {
124                  toastService.error('Unable to update LDAP settings.');
125                  console.log(JSON.stringify(error));
126                });
127      };
128
129      /**
130       * Sends a request to disable the LDAP Service if the user
131       * toggled the service enabled checkbox in the UI and if
132       * there was a previously saved service type. This prevents
133       * unnecessary calls to the backend if the user toggled
134       * the service enabled, but never actually had saved settings.
135       */
136      $scope.updateServiceEnabled = () => {
137        const originalEnabledServiceType =
138            $scope.originalLdapProperties.EnabledServiceType;
139
140        if (!$scope.ldapProperties.ServiceEnabled &&
141            originalEnabledServiceType) {
142          $scope.ldapProperties.EnabledServiceType = '';
143
144          const disabledServicePayload =
145              createLdapDisableRequest(originalEnabledServiceType);
146          APIUtils.saveLdapProperties(disabledServicePayload)
147              .then(
148                  function(response) {
149                    toastService.success('Successfully disabled LDAP.');
150                    $scope.roleGroups = [];
151                    $scope.loadLdap();
152                  },
153                  function(error) {
154                    toastService.error('Unable to update LDAP settings.');
155                    console.log(JSON.stringify(error));
156                  });
157        }
158      };
159
160      /**
161       *
162       * @param {string} uri for certificate
163       * @returns {null | Object}
164       */
165      function getCertificate(location) {
166        return APIUtils.getCertificate(location).then(function(data) {
167          if (data.Members && data.Members.length) {
168            return APIUtils.getCertificate(data.Members[0]['@odata.id'])
169                .then(
170                    function(response) {
171                      return response;
172                    },
173                    function(error) {
174                      console.log(json.stringify(error));
175                    })
176          } else {
177            return null;
178          }
179        });
180      }
181
182      /**
183       *
184       * @param {Object} ldapProperties
185       * @returns {string}
186       */
187      function getEnabledServiceType(ldapProperties) {
188        let enabledServiceType = '';
189        if (ldapProperties.LDAP.ServiceEnabled) {
190          enabledServiceType = 'LDAP';
191        } else if (ldapProperties.ActiveDirectory.ServiceEnabled) {
192          enabledServiceType = 'ActiveDirectory';
193        }
194        return enabledServiceType;
195      }
196
197      /**
198       *
199       * @param {Object} ldapProperties
200       * @returns {Array}
201       */
202      function getServiceAddresses(ldapProperties) {
203        let serviceAddresses = [];
204        let serviceType = getEnabledServiceType(ldapProperties);
205        if (serviceType) {
206          serviceAddresses = ldapProperties[serviceType]['ServiceAddresses'];
207        }
208        return serviceAddresses;
209      }
210
211      /**
212       *
213       * @param {Object} ldapProperties
214       * @returns {boolean}
215       */
216      function getUseSsl(ldapProperties) {
217        let useSsl = false;
218        let serviceType = getEnabledServiceType(ldapProperties);
219        if (serviceType) {
220          const uri = ldapProperties[serviceType]['ServiceAddresses'][0];
221          useSsl = uri.startsWith('ldaps://');
222        }
223        return useSsl;
224      }
225
226      /**
227       *
228       * @param {Object} ldapProperties
229       * @returns {string}
230       */
231      function getUsername(ldapProperties) {
232        let username = '';
233        let serviceType = getEnabledServiceType(ldapProperties);
234        if (serviceType) {
235          username = ldapProperties[serviceType]['Authentication']['Username'];
236        }
237        return username;
238      }
239
240      /**
241       *
242       * @param {Object} ldapProperties
243       * @returns {Array}
244       */
245      function getBaseDistinguishedNames(ldapProperties) {
246        let basedDisguishedNames = [];
247        let serviceType = getEnabledServiceType(ldapProperties);
248        if (serviceType) {
249          basedDisguishedNames =
250              ldapProperties[serviceType]['LDAPService']['SearchSettings']['BaseDistinguishedNames'];
251        }
252        return basedDisguishedNames;
253      }
254
255      /**
256       *
257       * @param {Object} ldapProperties
258       * @returns {string}
259       */
260      function getGroupsAttribute(ldapProperties) {
261        let groupsAttribute = '';
262        let serviceType = getEnabledServiceType(ldapProperties);
263        if (serviceType) {
264          groupsAttribute =
265              ldapProperties[serviceType]['LDAPService']['SearchSettings']['GroupsAttribute'];
266        }
267        return groupsAttribute;
268      }
269
270
271      /**
272       *
273       * @param {Object} ldapProperties
274       * @returns {string}
275       */
276      function getUsernameAttribute(ldapProperties) {
277        let userNameAttribute = '';
278        let serviceType = getEnabledServiceType(ldapProperties);
279        if (serviceType) {
280          userNameAttribute =
281              ldapProperties[serviceType]['LDAPService']['SearchSettings']['UsernameAttribute'];
282        }
283        return userNameAttribute;
284      }
285
286      /**
287       *
288       * @param {Object} ldapProperties
289       * @returns {null | string}
290       */
291      function getAuthenticationType(ldapProperties) {
292        let authenticationType = null;
293        let serviceType = getEnabledServiceType(ldapProperties);
294        if (serviceType) {
295          authenticationType =
296              ldapProperties[serviceType]['Authentication']['AuthenticationType'];
297        }
298        return authenticationType;
299      }
300
301      /**
302       *
303       * @param {Object} ldapProperties
304       * @returns {Array} A list of role groups
305       */
306      function getRoleGroups(ldapProperties) {
307        let roleGroups = [];
308        let serviceType = getEnabledServiceType(ldapProperties);
309        if (serviceType) {
310          roleGroups = ldapProperties[serviceType]['RemoteRoleMapping'];
311        }
312
313        return roleGroups;
314      }
315
316      /**
317       * Returns the payload needed to enable an LDAP Service
318       * @param {string} serviceType - 'LDAP' or 'ActiveDirectory'
319       */
320      function createLdapEnableRequest(serviceType, ldapProperties) {
321        let ldapRequest = {};
322        const ServiceEnabled = true;
323        const Authentication = {
324          Username: ldapProperties.Username,
325          AuthenticationType: ldapProperties.AuthenticationType
326        };
327        const LDAPService = {
328          SearchSettings: {
329            BaseDistinguishedNames: ldapProperties.BaseDistinguishedNames,
330            GroupsAttribute: ldapProperties.GroupsAttribute,
331            UsernameAttribute: ldapProperties.UsernameAttribute
332          }
333        };
334        const ServiceAddresses = ldapProperties.ServiceAddresses;
335
336        if (serviceType == 'LDAP') {
337          ldapRequest = {
338            LDAP:
339                {ServiceEnabled, Authentication, LDAPService, ServiceAddresses}
340          };
341        } else {
342          ldapRequest = {
343            ActiveDirectory:
344                {ServiceEnabled, Authentication, LDAPService, ServiceAddresses}
345          };
346        }
347        return ldapRequest;
348      };
349
350      /**
351       * Returns the payload needed to disable an LDAP Service
352       * @param {string} serviceType - 'LDAP' or 'ActiveDirectory'
353       */
354      function createLdapDisableRequest(serviceType) {
355        let ldapRequest = {};
356        const ServiceEnabled = false;
357
358        if (serviceType == 'LDAP') {
359          ldapRequest = {LDAP: {ServiceEnabled}};
360        } else {
361          ldapRequest = {ActiveDirectory: {ServiceEnabled}};
362        }
363        return ldapRequest;
364      }
365    }
366  ]);
367})(angular);
368