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