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