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.accessControl').controller('certificateController', [ 13 '$scope', 'APIUtils', '$q', 'Constants', 'toastService', 14 function($scope, APIUtils, $q, Constants, toastService) { 15 $scope.loading = false; 16 $scope.certificates = []; 17 $scope.availableCertificateTypes = []; 18 $scope.allCertificateTypes = Constants.CERTIFICATE_TYPES; 19 $scope.addCertificateModal = false; 20 $scope.addCSRModal = false; 21 $scope.newCertificate = {}; 22 $scope.newCSR = {}; 23 $scope.submitted = false; 24 $scope.csrSubmitted = false; 25 $scope.csrCode = ''; 26 $scope.displayCSRCode = false; 27 $scope.keyBitLength = Constants.CERTIFICATE.KEY_BIT_LENGTH; 28 $scope.keyPairAlgorithm = Constants.CERTIFICATE.KEY_PAIR_ALGORITHM; 29 $scope.keyCurveId = Constants.CERTIFICATE.KEY_CURVE_ID; 30 $scope.countryList = Constants.COUNTRIES; 31 32 33 $scope.$on('$viewContentLoaded', () => { 34 getBmcTime(); 35 }) 36 37 $scope.loadCertificates = function() { 38 $scope.certificates = []; 39 $scope.availableCertificateTypes = Constants.CERTIFICATE_TYPES; 40 $scope.loading = true; 41 // Use Certificate Service to get the locations of all the certificates, 42 // then add a promise for fetching each certificate 43 APIUtils.getCertificateLocations().then( 44 function(data) { 45 var promises = []; 46 var locations = data.Links.Certificates; 47 for (var i in locations) { 48 var location = locations[i]; 49 promises.push(getCertificatePromise(location['@odata.id'])); 50 } 51 $q.all(promises) 52 .catch(function(error) { 53 toastService.error('Failed to load certificates.'); 54 console.log(JSON.stringify(error)); 55 }) 56 .finally(function() { 57 $scope.loading = false; 58 }); 59 }, 60 function(error) { 61 $scope.loading = false; 62 $scope.availableCertificateTypes = []; 63 toastService.error('Failed to load certificates.'); 64 console.log(JSON.stringify(error)); 65 }); 66 }; 67 68 $scope.uploadCertificate = function() { 69 if ($scope.newCertificate.file.name.split('.').pop() !== 'pem') { 70 toastService.error('Certificate must be a .pem file.'); 71 return; 72 } 73 $scope.addCertificateModal = false; 74 APIUtils 75 .addNewCertificate( 76 $scope.newCertificate.file, $scope.newCertificate.selectedType) 77 .then( 78 function(data) { 79 toastService.success( 80 $scope.newCertificate.selectedType.name + 81 ' was uploaded.'); 82 $scope.newCertificate = {}; 83 $scope.loadCertificates(); 84 }, 85 function(error) { 86 toastService.error( 87 $scope.newCertificate.selectedType.name + 88 ' failed upload.'); 89 console.log(JSON.stringify(error)); 90 }); 91 }; 92 93 var getCertificatePromise = function(url) { 94 var promise = APIUtils.getCertificate(url).then(function(data) { 95 var certificate = data; 96 isExpiring(certificate); 97 updateAvailableTypes(certificate); 98 $scope.certificates.push(certificate); 99 }); 100 return promise; 101 }; 102 103 var isExpiring = function(certificate) { 104 // convert certificate time to epoch time 105 // if ValidNotAfter is less than or equal to 30 days from bmc time 106 // (2592000000), isExpiring. If less than or equal to 0, is expired. 107 // dividing bmc time by 1000 converts epoch milliseconds to seconds 108 var difference = (new Date(certificate.ValidNotAfter).getTime()) - 109 ($scope.bmcTime) / 1000; 110 if (difference <= 0) { 111 certificate.isExpired = true; 112 } else if (difference <= 2592000000) { 113 certificate.isExpiring = true; 114 } else { 115 certificate.isExpired = false; 116 certificate.isExpiring = false; 117 } 118 }; 119 120 // add optional name 121 $scope.names = []; 122 $scope.addOptionalRow = function() { 123 $scope.names.push({Value: ''}) 124 }; 125 126 // remove optional name row 127 $scope.deleteOptionalRow = function(index) { 128 $scope.names.splice(index, 1); 129 if ($scope.names.length == 0) { 130 $scope.names = []; 131 } 132 }; 133 134 135 // create a CSR object to send to the backend 136 $scope.getCSRCode = function() { 137 var addCSR = {}; 138 let alternativeNames = $scope.names.map(name => name.Value); 139 140 // if user provided a first alternative name then push to alternative 141 // names array 142 $scope.newCSR.firstAlternativeName ? 143 alternativeNames.push($scope.newCSR.firstAlternativeName) : 144 $scope.newCSR.firstAlternativeName = ''; 145 146 147 addCSR.CertificateCollection = { 148 '@odata.id': $scope.newCSR.certificateCollection.location 149 }; 150 addCSR.CommonName = $scope.newCSR.commonName; 151 addCSR.ContactPerson = $scope.newCSR.contactPerson || ''; 152 addCSR.City = $scope.newCSR.city; 153 addCSR.AlternativeNames = alternativeNames || []; 154 addCSR.ChallengePassword = $scope.newCSR.challengePassword || ''; 155 addCSR.Email = $scope.newCSR.emailAddress || ''; 156 addCSR.Country = $scope.newCSR.countryCode.code; 157 addCSR.Organization = $scope.newCSR.organization; 158 addCSR.OrganizationalUnit = $scope.newCSR.companyUnit; 159 addCSR.KeyCurveId = $scope.newCSR.keyCurveId || ''; 160 addCSR.KeyBitLength = $scope.newCSR.keyBitLength 161 addCSR.KeyPairAlgorithm = $scope.newCSR.keyPairAlgorithm || ''; 162 addCSR.State = $scope.newCSR.state; 163 164 APIUtils.createCSRCertificate(addCSR).then( 165 function(data) { 166 $scope.displayCSRCode = true; 167 $scope.csrCode = data; 168 }, 169 function(error) { 170 $scope.addCSRModal = false; 171 toastService.error('Unable to generate CSR. Try again.'); 172 console.log(JSON.stringify(error)); 173 }) 174 }; 175 176 // resetting the modal when user clicks cancel/closes the 177 // modal 178 $scope.resetCSRModal = function() { 179 $scope.addCSRModal = false; 180 $scope.displayCSRCode = false; 181 $scope.newCSR.certificateCollection = $scope.selectOption; 182 $scope.newCSR.commonName = ''; 183 $scope.newCSR.contactPerson = ''; 184 $scope.newCSR.city = ''; 185 $scope.names = []; 186 $scope.newCSR.challengePassword = ''; 187 $scope.newCSR.emailAddress = ''; 188 $scope.newCSR.countryCode = ''; 189 $scope.newCSR.keyCurveId = ''; 190 $scope.newCSR.firstAlternativeName = ''; 191 $scope.newCSR.keyBitLength = $scope.selectOption; 192 $scope.newCSR.keyPairAlgorithm = $scope.selectOption; 193 $scope.newCSR.organization = ''; 194 $scope.newCSR.companyUnit = ''; 195 $scope.newCSR.state = ''; 196 }; 197 198 // copies the CSR code 199 $scope.copySuccess = function(event) { 200 $scope.copied = true; 201 $timeout(function() { 202 $scope.copied = false; 203 }, 5000); 204 }; 205 $scope.copyFailed = function(err) { 206 console.log(JSON.stringify(err)); 207 }; 208 209 210 var getBmcTime = function() { 211 APIUtils.getBMCTime().then(function(data) { 212 $scope.bmcTime = data.data.Elapsed; 213 }); 214 215 return $scope.bmcTime; 216 }; 217 218 var updateAvailableTypes = function(certificate) { 219 // TODO: at this time only one of each type of certificate is allowed. 220 // When this changes, this will need to be updated. 221 // Removes certificate type from available types to be added. 222 $scope.availableCertificateTypes = 223 $scope.availableCertificateTypes.filter(function(type) { 224 return type.Description !== certificate.Description; 225 }); 226 }; 227 228 $scope.getDays = function(endDate) { 229 // finds number of days until certificate expiration 230 // dividing bmc time by 1000 converts milliseconds to seconds 231 var ms = (new Date(endDate).getTime()) - ($scope.bmcTime) / 1000; 232 return Math.floor(ms / (24 * 60 * 60 * 1000)); 233 }; 234 235 $scope.loadCertificates(); 236 } 237 ]); 238})(angular); 239