1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 cr.define('options', function() { 6 7 var OptionsPage = options.OptionsPage; 8 9 ///////////////////////////////////////////////////////////////////////////// 10 // CertificateManagerTab class: 11 12 /** 13 * blah 14 * @param {!string} id The id of this tab. 15 */ 16 function CertificateManagerTab(id) { 17 this.tree = $(id + '-tree'); 18 19 options.CertificatesTree.decorate(this.tree); 20 this.tree.addEventListener('change', 21 this.handleCertificatesTreeChange_.bind(this)); 22 23 var tree = this.tree; 24 25 this.viewButton = $(id + '-view'); 26 this.viewButton.onclick = function(e) { 27 var selected = tree.selectedItem; 28 chrome.send('viewCertificate', [selected.data.id]); 29 } 30 31 this.editButton = $(id + '-edit'); 32 if (this.editButton !== null) { 33 if (id == 'serverCertsTab') { 34 this.editButton.onclick = function(e) { 35 var selected = tree.selectedItem; 36 chrome.send('editServerCertificate', [selected.data.id]); 37 } 38 } else if (id == 'caCertsTab') { 39 this.editButton.onclick = function(e) { 40 var data = tree.selectedItem.data; 41 CertificateEditCaTrustOverlay.show(data.id, data.name); 42 } 43 } 44 } 45 46 this.backupButton = $(id + '-backup'); 47 if (this.backupButton !== null) { 48 this.backupButton.onclick = function(e) { 49 var selected = tree.selectedItem; 50 chrome.send('exportPersonalCertificate', [selected.data.id]); 51 } 52 } 53 54 this.backupAllButton = $(id + '-backup-all'); 55 if (this.backupAllButton !== null) { 56 this.backupAllButton.onclick = function(e) { 57 chrome.send('exportAllPersonalCertificates', []); 58 } 59 } 60 61 this.importButton = $(id + '-import'); 62 if (this.importButton !== null) { 63 if (id == 'personalCertsTab') { 64 this.importButton.onclick = function(e) { 65 chrome.send('importPersonalCertificate', [false]); 66 } 67 } else if (id == 'serverCertsTab') { 68 this.importButton.onclick = function(e) { 69 chrome.send('importServerCertificate', []); 70 } 71 } else if (id == 'caCertsTab') { 72 this.importButton.onclick = function(e) { 73 chrome.send('importCaCertificate', []); 74 } 75 } 76 } 77 78 this.importAndBindButton = $(id + '-import-and-bind'); 79 if (this.importAndBindButton !== null) { 80 if (id == 'personalCertsTab') { 81 this.importAndBindButton.onclick = function(e) { 82 chrome.send('importPersonalCertificate', [true]); 83 } 84 } 85 } 86 87 this.exportButton = $(id + '-export'); 88 if (this.exportButton !== null) { 89 this.exportButton.onclick = function(e) { 90 var selected = tree.selectedItem; 91 chrome.send('exportCertificate', [selected.data.id]); 92 } 93 } 94 95 this.deleteButton = $(id + '-delete'); 96 this.deleteButton.onclick = function(e) { 97 var data = tree.selectedItem.data; 98 AlertOverlay.show( 99 localStrings.getStringF(id + 'DeleteConfirm', data.name), 100 localStrings.getString(id + 'DeleteImpact'), 101 localStrings.getString('ok'), 102 localStrings.getString('cancel'), 103 function() { chrome.send('deleteCertificate', [data.id]); }); 104 } 105 } 106 107 CertificateManagerTab.prototype = { 108 109 /** 110 * Update button state. 111 * @private 112 * @param {!Object} data The data of the selected item. 113 */ 114 updateButtonState: function(data) { 115 var isCert = !!data && data.id.substr(0, 5) == 'cert-'; 116 var readOnly = !!data && data.readonly; 117 var hasChildren = this.tree.items.length > 0; 118 this.viewButton.disabled = !isCert; 119 if (this.editButton !== null) 120 this.editButton.disabled = !isCert; 121 if (this.backupButton !== null) 122 this.backupButton.disabled = !isCert; 123 if (this.backupAllButton !== null) 124 this.backupAllButton.disabled = !hasChildren; 125 if (this.exportButton !== null) 126 this.exportButton.disabled = !isCert; 127 this.deleteButton.disabled = !isCert || readOnly; 128 }, 129 130 /** 131 * Handles certificate tree selection change. 132 * @private 133 * @param {!Event} e The change event object. 134 */ 135 handleCertificatesTreeChange_: function(e) { 136 var data = null; 137 if (this.tree.selectedItem) { 138 data = this.tree.selectedItem.data; 139 } 140 141 this.updateButtonState(data); 142 }, 143 144 } 145 146 // TODO(xiyuan): Use notification from backend instead of polling. 147 // TPM token check polling timer. 148 var tpmPollingTimer; 149 150 // Initiate tpm token check if needed. 151 function checkTpmToken() { 152 var importAndBindButton = $('personalCertsTab-import-and-bind'); 153 154 if (importAndBindButton && importAndBindButton.disabled) 155 chrome.send('checkTpmTokenReady'); 156 } 157 158 // Stop tpm polling timer. 159 function stopTpmTokenCheckPolling() { 160 if (tpmPollingTimer) { 161 window.clearTimeout(tpmPollingTimer); 162 tpmPollingTimer = undefined; 163 } 164 } 165 166 ///////////////////////////////////////////////////////////////////////////// 167 // CertificateManager class: 168 169 /** 170 * Encapsulated handling of ChromeOS accounts options page. 171 * @constructor 172 */ 173 function CertificateManager(model) { 174 OptionsPage.call(this, 'certificates', 175 templateData.certificateManagerPageTabTitle, 176 'certificateManagerPage'); 177 } 178 179 cr.addSingletonGetter(CertificateManager); 180 181 CertificateManager.prototype = { 182 __proto__: OptionsPage.prototype, 183 184 initializePage: function() { 185 OptionsPage.prototype.initializePage.call(this); 186 187 this.personalTab = new CertificateManagerTab('personalCertsTab'); 188 this.serverTab = new CertificateManagerTab('serverCertsTab'); 189 this.caTab = new CertificateManagerTab('caCertsTab'); 190 this.otherTab = new CertificateManagerTab('otherCertsTab'); 191 192 this.addEventListener('visibleChange', this.handleVisibleChange_); 193 }, 194 195 initalized_: false, 196 197 /** 198 * Handler for OptionsPage's visible property change event. 199 * @private 200 * @param {Event} e Property change event. 201 */ 202 handleVisibleChange_: function(e) { 203 if (!this.initalized_ && this.visible) { 204 this.initalized_ = true; 205 chrome.send('populateCertificateManager'); 206 } 207 208 if (cr.isChromeOS) { 209 // Ensure TPM token check on visible and stop polling when hidden. 210 if (this.visible) 211 checkTpmToken(); 212 else 213 stopTpmTokenCheckPolling(); 214 } 215 } 216 }; 217 218 // CertificateManagerHandler callbacks. 219 CertificateManager.onPopulateTree = function(args) { 220 $(args[0]).populate(args[1]); 221 }; 222 223 CertificateManager.exportPersonalAskPassword = function(args) { 224 CertificateBackupOverlay.show(); 225 }; 226 227 CertificateManager.importPersonalAskPassword = function(args) { 228 CertificateRestoreOverlay.show(); 229 }; 230 231 CertificateManager.onCheckTpmTokenReady = function(ready) { 232 var importAndBindButton = $('personalCertsTab-import-and-bind'); 233 if (importAndBindButton) { 234 importAndBindButton.disabled = !ready; 235 236 // Check again after 5 seconds if Tpm is not ready and certificate manager 237 // is still visible. 238 if (!ready && CertificateManager.getInstance().visible) 239 tpmPollingTimer = window.setTimeout(checkTpmToken, 5000); 240 } 241 }; 242 243 // Export 244 return { 245 CertificateManagerTab: CertificateManagerTab, 246 CertificateManager: CertificateManager 247 }; 248 249 }); 250