1afc8a799Smiramurali23/** 2afc8a799Smiramurali23 * Controller for Certificate Management 3afc8a799Smiramurali23 * 4afc8a799Smiramurali23 * @module app/access-control 5afc8a799Smiramurali23 * @exports certificateController 6afc8a799Smiramurali23 * @name certificateController 7afc8a799Smiramurali23 */ 8afc8a799Smiramurali23 9afc8a799Smiramurali23window.angular && (function(angular) { 10afc8a799Smiramurali23 'use strict'; 11afc8a799Smiramurali23 12c15f66b0SDixsie Wolmers angular.module('app.configuration').controller('certificateController', [ 13c15f66b0SDixsie Wolmers '$scope', 'APIUtils', '$q', 'Constants', 'toastService', '$timeout', 14c15f66b0SDixsie Wolmers '$uibModal', 15c15f66b0SDixsie Wolmers function( 16c15f66b0SDixsie Wolmers $scope, APIUtils, $q, Constants, toastService, $timeout, $uibModal) { 17afc8a799Smiramurali23 $scope.loading = false; 18afc8a799Smiramurali23 $scope.certificates = []; 19afc8a799Smiramurali23 $scope.availableCertificateTypes = []; 20afc8a799Smiramurali23 $scope.allCertificateTypes = Constants.CERTIFICATE_TYPES; 21afc8a799Smiramurali23 $scope.newCertificate = {}; 22afc8a799Smiramurali23 $scope.newCSR = {}; 23afc8a799Smiramurali23 $scope.keyBitLength = Constants.CERTIFICATE.KEY_BIT_LENGTH; 24afc8a799Smiramurali23 $scope.keyPairAlgorithm = Constants.CERTIFICATE.KEY_PAIR_ALGORITHM; 25afc8a799Smiramurali23 $scope.keyCurveId = Constants.CERTIFICATE.KEY_CURVE_ID; 26afc8a799Smiramurali23 $scope.countryList = Constants.COUNTRIES; 27afc8a799Smiramurali23 28afc8a799Smiramurali23 $scope.$on('$viewContentLoaded', () => { 29afc8a799Smiramurali23 getBmcTime(); 30afc8a799Smiramurali23 }) 31afc8a799Smiramurali23 32afc8a799Smiramurali23 $scope.loadCertificates = function() { 33afc8a799Smiramurali23 $scope.certificates = []; 34afc8a799Smiramurali23 $scope.availableCertificateTypes = Constants.CERTIFICATE_TYPES; 35afc8a799Smiramurali23 $scope.loading = true; 36afc8a799Smiramurali23 // Use Certificate Service to get the locations of all the certificates, 37afc8a799Smiramurali23 // then add a promise for fetching each certificate 38afc8a799Smiramurali23 APIUtils.getCertificateLocations().then( 39afc8a799Smiramurali23 function(data) { 40afc8a799Smiramurali23 var promises = []; 41afc8a799Smiramurali23 var locations = data.Links.Certificates; 42afc8a799Smiramurali23 for (var i in locations) { 43afc8a799Smiramurali23 var location = locations[i]; 44afc8a799Smiramurali23 promises.push(getCertificatePromise(location['@odata.id'])); 45afc8a799Smiramurali23 } 46afc8a799Smiramurali23 $q.all(promises) 47afc8a799Smiramurali23 .catch(function(error) { 48afc8a799Smiramurali23 toastService.error('Failed to load certificates.'); 49afc8a799Smiramurali23 console.log(JSON.stringify(error)); 50afc8a799Smiramurali23 }) 51afc8a799Smiramurali23 .finally(function() { 52afc8a799Smiramurali23 $scope.loading = false; 53*ca7e093bSZbigniew Kurzynski $scope.certificates.sort(function(a, b) { 54*ca7e093bSZbigniew Kurzynski if (a.Name > b.Name) { 55*ca7e093bSZbigniew Kurzynski return 1; 56*ca7e093bSZbigniew Kurzynski } 57*ca7e093bSZbigniew Kurzynski if (a.Name < b.Name) { 58*ca7e093bSZbigniew Kurzynski return -1; 59*ca7e093bSZbigniew Kurzynski } 60*ca7e093bSZbigniew Kurzynski if (a.Issuer.CommonName > b.Issuer.CommonName) { 61*ca7e093bSZbigniew Kurzynski return 1; 62*ca7e093bSZbigniew Kurzynski } 63*ca7e093bSZbigniew Kurzynski if (a.Issuer.CommonName < b.Issuer.CommonName) { 64*ca7e093bSZbigniew Kurzynski return -1; 65*ca7e093bSZbigniew Kurzynski } 66*ca7e093bSZbigniew Kurzynski return (Date.parse(a.ValidNotBefore) > 67*ca7e093bSZbigniew Kurzynski Date.parse(b.ValidNotBefore)) ? 68*ca7e093bSZbigniew Kurzynski 1 : 69*ca7e093bSZbigniew Kurzynski -1; 70*ca7e093bSZbigniew Kurzynski }); 71afc8a799Smiramurali23 }); 72afc8a799Smiramurali23 }, 73afc8a799Smiramurali23 function(error) { 74afc8a799Smiramurali23 $scope.loading = false; 75afc8a799Smiramurali23 $scope.availableCertificateTypes = []; 76afc8a799Smiramurali23 toastService.error('Failed to load certificates.'); 77afc8a799Smiramurali23 console.log(JSON.stringify(error)); 78afc8a799Smiramurali23 }); 79afc8a799Smiramurali23 }; 80afc8a799Smiramurali23 81afc8a799Smiramurali23 $scope.uploadCertificate = function() { 82afc8a799Smiramurali23 if ($scope.newCertificate.file.name.split('.').pop() !== 'pem') { 83afc8a799Smiramurali23 toastService.error('Certificate must be a .pem file.'); 84afc8a799Smiramurali23 return; 85afc8a799Smiramurali23 } 86afc8a799Smiramurali23 APIUtils 87afc8a799Smiramurali23 .addNewCertificate( 88afc8a799Smiramurali23 $scope.newCertificate.file, $scope.newCertificate.selectedType) 89afc8a799Smiramurali23 .then( 90afc8a799Smiramurali23 function(data) { 91afc8a799Smiramurali23 toastService.success( 92afc8a799Smiramurali23 $scope.newCertificate.selectedType.name + 93afc8a799Smiramurali23 ' was uploaded.'); 94afc8a799Smiramurali23 $scope.newCertificate = {}; 95afc8a799Smiramurali23 $scope.loadCertificates(); 96afc8a799Smiramurali23 }, 97afc8a799Smiramurali23 function(error) { 98afc8a799Smiramurali23 toastService.error( 99afc8a799Smiramurali23 $scope.newCertificate.selectedType.name + 100afc8a799Smiramurali23 ' failed upload.'); 101afc8a799Smiramurali23 console.log(JSON.stringify(error)); 102afc8a799Smiramurali23 }); 103afc8a799Smiramurali23 }; 104afc8a799Smiramurali23 105afc8a799Smiramurali23 var getCertificatePromise = function(url) { 106afc8a799Smiramurali23 var promise = APIUtils.getCertificate(url).then(function(data) { 107afc8a799Smiramurali23 var certificate = data; 108afc8a799Smiramurali23 isExpiring(certificate); 109afc8a799Smiramurali23 updateAvailableTypes(certificate); 110afc8a799Smiramurali23 $scope.certificates.push(certificate); 111afc8a799Smiramurali23 }); 112afc8a799Smiramurali23 return promise; 113afc8a799Smiramurali23 }; 114afc8a799Smiramurali23 115afc8a799Smiramurali23 var isExpiring = function(certificate) { 116afc8a799Smiramurali23 // convert certificate time to epoch time 117afc8a799Smiramurali23 // if ValidNotAfter is less than or equal to 30 days from bmc time 118afc8a799Smiramurali23 // (2592000000), isExpiring. If less than or equal to 0, is expired. 119afc8a799Smiramurali23 // dividing bmc time by 1000 converts epoch milliseconds to seconds 120afc8a799Smiramurali23 var difference = (new Date(certificate.ValidNotAfter).getTime()) - 121afc8a799Smiramurali23 ($scope.bmcTime) / 1000; 122afc8a799Smiramurali23 if (difference <= 0) { 123afc8a799Smiramurali23 certificate.isExpired = true; 124afc8a799Smiramurali23 } else if (difference <= 2592000000) { 125afc8a799Smiramurali23 certificate.isExpiring = true; 126afc8a799Smiramurali23 } else { 127afc8a799Smiramurali23 certificate.isExpired = false; 128afc8a799Smiramurali23 certificate.isExpiring = false; 129afc8a799Smiramurali23 } 130afc8a799Smiramurali23 }; 131afc8a799Smiramurali23 132afc8a799Smiramurali23 // add optional name 133afc8a799Smiramurali23 $scope.names = []; 134afc8a799Smiramurali23 $scope.addOptionalRow = function() { 135afc8a799Smiramurali23 $scope.names.push({Value: ''}) 136afc8a799Smiramurali23 }; 137afc8a799Smiramurali23 138afc8a799Smiramurali23 // remove optional name row 139afc8a799Smiramurali23 $scope.deleteOptionalRow = function(index) { 140afc8a799Smiramurali23 $scope.names.splice(index, 1); 141afc8a799Smiramurali23 if ($scope.names.length == 0) { 142afc8a799Smiramurali23 $scope.names = []; 143afc8a799Smiramurali23 } 144afc8a799Smiramurali23 }; 145afc8a799Smiramurali23 146afc8a799Smiramurali23 // create a CSR object to send to the backend 147afc8a799Smiramurali23 $scope.getCSRCode = function() { 148afc8a799Smiramurali23 var addCSR = {}; 149afc8a799Smiramurali23 let alternativeNames = $scope.names.map(name => name.Value); 150afc8a799Smiramurali23 151afc8a799Smiramurali23 // if user provided a first alternative name then push to alternative 152afc8a799Smiramurali23 // names array 153afc8a799Smiramurali23 $scope.newCSR.firstAlternativeName ? 154afc8a799Smiramurali23 alternativeNames.push($scope.newCSR.firstAlternativeName) : 155afc8a799Smiramurali23 $scope.newCSR.firstAlternativeName = ''; 156afc8a799Smiramurali23 157afc8a799Smiramurali23 addCSR.CertificateCollection = { 158afc8a799Smiramurali23 '@odata.id': $scope.newCSR.certificateCollection.location 159afc8a799Smiramurali23 }; 160afc8a799Smiramurali23 addCSR.CommonName = $scope.newCSR.commonName; 161afc8a799Smiramurali23 addCSR.ContactPerson = $scope.newCSR.contactPerson || ''; 162afc8a799Smiramurali23 addCSR.City = $scope.newCSR.city; 163afc8a799Smiramurali23 addCSR.AlternativeNames = alternativeNames || []; 164afc8a799Smiramurali23 addCSR.ChallengePassword = $scope.newCSR.challengePassword || ''; 165afc8a799Smiramurali23 addCSR.Email = $scope.newCSR.emailAddress || ''; 166afc8a799Smiramurali23 addCSR.Country = $scope.newCSR.countryCode.code; 167afc8a799Smiramurali23 addCSR.Organization = $scope.newCSR.organization; 168afc8a799Smiramurali23 addCSR.OrganizationalUnit = $scope.newCSR.companyUnit; 169afc8a799Smiramurali23 addCSR.KeyCurveId = $scope.newCSR.keyCurveId || ''; 170afc8a799Smiramurali23 addCSR.KeyBitLength = $scope.newCSR.keyBitLength 171afc8a799Smiramurali23 addCSR.KeyPairAlgorithm = $scope.newCSR.keyPairAlgorithm || ''; 172afc8a799Smiramurali23 addCSR.State = $scope.newCSR.state; 173afc8a799Smiramurali23 174afc8a799Smiramurali23 APIUtils.createCSRCertificate(addCSR).then( 175afc8a799Smiramurali23 function(data) { 176afc8a799Smiramurali23 $scope.csrCode = data; 177c15f66b0SDixsie Wolmers openDownloadCsrModal(); 178afc8a799Smiramurali23 }, 179afc8a799Smiramurali23 function(error) { 180afc8a799Smiramurali23 toastService.error('Unable to generate CSR. Try again.'); 181afc8a799Smiramurali23 console.log(JSON.stringify(error)); 182afc8a799Smiramurali23 }) 183afc8a799Smiramurali23 }; 184afc8a799Smiramurali23 185c15f66b0SDixsie Wolmers function openDownloadCsrModal() { 186c15f66b0SDixsie Wolmers const modalTemplateCsrDownload = 187c15f66b0SDixsie Wolmers require('./certificate-modal-csr-download.html'); 188c15f66b0SDixsie Wolmers $uibModal 189c15f66b0SDixsie Wolmers .open({ 190c15f66b0SDixsie Wolmers template: modalTemplateCsrDownload, 191c15f66b0SDixsie Wolmers windowTopClass: 'uib-modal', 192c15f66b0SDixsie Wolmers scope: $scope, 193c15f66b0SDixsie Wolmers ariaLabelledBy: 'modal_label', 194c15f66b0SDixsie Wolmers size: 'lg', 195c15f66b0SDixsie Wolmers }) 196c15f66b0SDixsie Wolmers .result.catch(function() { 197c15f66b0SDixsie Wolmers resetCSRModal(); 198c15f66b0SDixsie Wolmers }); 199c15f66b0SDixsie Wolmers }; 200c15f66b0SDixsie Wolmers 201c15f66b0SDixsie Wolmers $scope.addCertModal = function() { 202c15f66b0SDixsie Wolmers openAddCertModal(); 203c15f66b0SDixsie Wolmers }; 204c15f66b0SDixsie Wolmers 205c15f66b0SDixsie Wolmers function openAddCertModal() { 206c15f66b0SDixsie Wolmers const modalTemplateAddCert = 207c15f66b0SDixsie Wolmers require('./certificate-modal-add-cert.html'); 208c15f66b0SDixsie Wolmers $uibModal 209c15f66b0SDixsie Wolmers .open({ 210c15f66b0SDixsie Wolmers template: modalTemplateAddCert, 211c15f66b0SDixsie Wolmers windowTopClass: 'uib-modal', 212c15f66b0SDixsie Wolmers scope: $scope, 213c15f66b0SDixsie Wolmers ariaLabelledBy: 'modal_label', 214c15f66b0SDixsie Wolmers }) 215c15f66b0SDixsie Wolmers .result.catch(function() { 216c15f66b0SDixsie Wolmers // do nothing 217c15f66b0SDixsie Wolmers }); 218c15f66b0SDixsie Wolmers }; 219c15f66b0SDixsie Wolmers 220c15f66b0SDixsie Wolmers $scope.addCsrModal = function() { 221c15f66b0SDixsie Wolmers openCsrModal(); 222c15f66b0SDixsie Wolmers }; 223c15f66b0SDixsie Wolmers 224c15f66b0SDixsie Wolmers function openCsrModal() { 225c15f66b0SDixsie Wolmers const modalTemplateCsrGen = require('./certificate-modal-csr-gen.html'); 226c15f66b0SDixsie Wolmers $uibModal 227c15f66b0SDixsie Wolmers .open({ 228c15f66b0SDixsie Wolmers template: modalTemplateCsrGen, 229c15f66b0SDixsie Wolmers windowTopClass: 'uib-modal', 230c15f66b0SDixsie Wolmers scope: $scope, 231c15f66b0SDixsie Wolmers ariaLabelledBy: 'modal_label', 232c15f66b0SDixsie Wolmers size: 'lg', 233c15f66b0SDixsie Wolmers }) 234c15f66b0SDixsie Wolmers .result.catch(function() { 235c15f66b0SDixsie Wolmers resetCSRModal(); 236c15f66b0SDixsie Wolmers }); 237c15f66b0SDixsie Wolmers }; 238c15f66b0SDixsie Wolmers 239afc8a799Smiramurali23 // resetting the modal when user clicks cancel/closes the 240afc8a799Smiramurali23 // modal 241c15f66b0SDixsie Wolmers const resetCSRModal = function() { 242afc8a799Smiramurali23 $scope.newCSR.certificateCollection = $scope.selectOption; 243afc8a799Smiramurali23 $scope.newCSR.commonName = ''; 244afc8a799Smiramurali23 $scope.newCSR.contactPerson = ''; 245afc8a799Smiramurali23 $scope.newCSR.city = ''; 246afc8a799Smiramurali23 $scope.names = []; 247afc8a799Smiramurali23 $scope.newCSR.challengePassword = ''; 248afc8a799Smiramurali23 $scope.newCSR.emailAddress = ''; 249afc8a799Smiramurali23 $scope.newCSR.countryCode = ''; 250afc8a799Smiramurali23 $scope.newCSR.keyCurveId = ''; 251afc8a799Smiramurali23 $scope.newCSR.firstAlternativeName = ''; 252afc8a799Smiramurali23 $scope.newCSR.keyBitLength = $scope.selectOption; 253afc8a799Smiramurali23 $scope.newCSR.keyPairAlgorithm = $scope.selectOption; 254afc8a799Smiramurali23 $scope.newCSR.organization = ''; 255afc8a799Smiramurali23 $scope.newCSR.companyUnit = ''; 256afc8a799Smiramurali23 $scope.newCSR.state = ''; 257afc8a799Smiramurali23 }; 258afc8a799Smiramurali23 259afc8a799Smiramurali23 // copies the CSR code 260afc8a799Smiramurali23 $scope.copySuccess = function(event) { 261afc8a799Smiramurali23 $scope.copied = true; 262afc8a799Smiramurali23 $timeout(function() { 263afc8a799Smiramurali23 $scope.copied = false; 264afc8a799Smiramurali23 }, 5000); 265afc8a799Smiramurali23 }; 266afc8a799Smiramurali23 $scope.copyFailed = function(err) { 267afc8a799Smiramurali23 console.log(JSON.stringify(err)); 268afc8a799Smiramurali23 }; 269afc8a799Smiramurali23 270afc8a799Smiramurali23 271afc8a799Smiramurali23 var getBmcTime = function() { 272afc8a799Smiramurali23 APIUtils.getBMCTime().then(function(data) { 273afc8a799Smiramurali23 $scope.bmcTime = data.data.Elapsed; 274afc8a799Smiramurali23 }); 275afc8a799Smiramurali23 276afc8a799Smiramurali23 return $scope.bmcTime; 277afc8a799Smiramurali23 }; 278afc8a799Smiramurali23 279afc8a799Smiramurali23 var updateAvailableTypes = function(certificate) { 280afc8a799Smiramurali23 $scope.availableCertificateTypes = 281afc8a799Smiramurali23 $scope.availableCertificateTypes.filter(function(type) { 282bb3714efSZbigniew Kurzynski if (type.Description == 'TrustStore Certificate') { 283bb3714efSZbigniew Kurzynski return true; 284bb3714efSZbigniew Kurzynski } 285afc8a799Smiramurali23 return type.Description !== certificate.Description; 286afc8a799Smiramurali23 }); 287afc8a799Smiramurali23 }; 288afc8a799Smiramurali23 289afc8a799Smiramurali23 $scope.getDays = function(endDate) { 290afc8a799Smiramurali23 // finds number of days until certificate expiration 291afc8a799Smiramurali23 // dividing bmc time by 1000 converts milliseconds to seconds 292afc8a799Smiramurali23 var ms = (new Date(endDate).getTime()) - ($scope.bmcTime) / 1000; 293afc8a799Smiramurali23 return Math.floor(ms / (24 * 60 * 60 * 1000)); 294afc8a799Smiramurali23 }; 295afc8a799Smiramurali23 296afc8a799Smiramurali23 $scope.loadCertificates(); 297afc8a799Smiramurali23 } 298afc8a799Smiramurali23 ]); 299afc8a799Smiramurali23})(angular); 300