OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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 /** |
| 6 * @fileoverview |
| 7 * 'settings-internet-config' provides configuration of authentication |
| 8 * properties for new and existing networks. |
| 9 */ |
| 10 Polymer({ |
| 11 is: 'settings-internet-config', |
| 12 |
| 13 behaviors: [settings.RouteObserverBehavior, I18nBehavior], |
| 14 |
| 15 properties: { |
| 16 /** |
| 17 * Interface for networkingPrivate calls, passed from internet_page. |
| 18 * @type {NetworkingPrivate} |
| 19 */ |
| 20 networkingPrivate: Object, |
| 21 |
| 22 /** |
| 23 * The GUID when an existing network is being configured. This will be |
| 24 * empty when configuring a new network. |
| 25 * @private |
| 26 */ |
| 27 guid_: String, |
| 28 |
| 29 /** |
| 30 * The current properties if an existing network being configured. |
| 31 * This will be undefined when configuring a new network. |
| 32 * @private {!chrome.networkingPrivate.NetworkProperties|undefined} |
| 33 */ |
| 34 networkProperties_: Object, |
| 35 |
| 36 /** Set if |guid_| is not empty once networkProperties_ are received. */ |
| 37 propertiesReceived_: Boolean, |
| 38 |
| 39 /** Set once properties have been sent; prevents multiple saves. */ |
| 40 propertiesSent_: Boolean, |
| 41 |
| 42 /** |
| 43 * The configuration properties for the network. |configProperties_.Type| |
| 44 * will always be defined as the network type being configured. |
| 45 * @private {!chrome.networkingPrivate.NetworkConfigProperties} |
| 46 */ |
| 47 configProperties_: Object, |
| 48 |
| 49 /** |
| 50 * The title to display (network name or type). |
| 51 * @private |
| 52 */ |
| 53 title_: { |
| 54 type: String, |
| 55 computed: 'computeTitle_(networkProperties_)', |
| 56 }, |
| 57 |
| 58 /** |
| 59 * Whether this network should be shared with other users of the device. |
| 60 * @private |
| 61 */ |
| 62 shareNetwork_: { |
| 63 type: Boolean, |
| 64 value: true, |
| 65 }, |
| 66 |
| 67 /** |
| 68 * Saved security value, used to detect when Security changes. |
| 69 * @private |
| 70 */ |
| 71 savedSecurity_: String, |
| 72 |
| 73 /** |
| 74 * Dictionary of boolean values determining which EAP properties to show, |
| 75 * or null to hide all EAP settings. |
| 76 * @type {?{ |
| 77 * Inner: boolean, |
| 78 * ServerCA: boolean, |
| 79 * SubjectMatch: boolean, |
| 80 * UserCert: boolean, |
| 81 * Password: boolean, |
| 82 * AnonymousIdentity: boolean, |
| 83 * }} |
| 84 * @private |
| 85 */ |
| 86 showEap_: { |
| 87 type: Object, |
| 88 value: null, |
| 89 }, |
| 90 |
| 91 /** |
| 92 * Object providing network type values for data binding. Note: Currently |
| 93 * we only support WiFi, but support for other types will be following |
| 94 * shortly. |
| 95 * @const |
| 96 * @private |
| 97 */ |
| 98 NetworkType_: { |
| 99 type: Object, |
| 100 value: { |
| 101 ETHERNET: CrOnc.Type.ETHERNET, |
| 102 VPN: CrOnc.Type.VPN, |
| 103 WI_FI: CrOnc.Type.WI_FI, |
| 104 WI_MAX: CrOnc.Type.WI_MAX, |
| 105 }, |
| 106 readOnly: true |
| 107 }, |
| 108 |
| 109 /** |
| 110 * Array of values for the WiFi Security dropdown. |
| 111 * @type {!Array<string>} |
| 112 * @const |
| 113 * @private |
| 114 */ |
| 115 securityItems_: { |
| 116 type: Array, |
| 117 readOnly: true, |
| 118 value: [ |
| 119 CrOnc.Security.NONE, CrOnc.Security.WEP_PSK, CrOnc.Security.WPA_PSK, |
| 120 CrOnc.Security.WPA_EAP |
| 121 ], |
| 122 }, |
| 123 |
| 124 /** |
| 125 * Array of values for the EAP Method (Outer) dropdown. |
| 126 * @type {!Array<string>} |
| 127 * @const |
| 128 * @private |
| 129 */ |
| 130 eapOuterItems_: { |
| 131 type: Array, |
| 132 readOnly: true, |
| 133 value: [ |
| 134 CrOnc.EAPType.LEAP, CrOnc.EAPType.PEAP, CrOnc.EAPType.EAP_TLS, |
| 135 CrOnc.EAPType.EAP_TTLS |
| 136 ], |
| 137 }, |
| 138 |
| 139 /** |
| 140 * Array of values for the EAP EAP Phase 2 authentication (Inner) dropdown |
| 141 * when the Outer type is PEAP. |
| 142 * @type {!Array<string>} |
| 143 * @const |
| 144 * @private |
| 145 */ |
| 146 eapInnerItemsPeap_: { |
| 147 type: Array, |
| 148 readOnly: true, |
| 149 value: ['Automatic', 'MD5', 'MSCHAPv2'], |
| 150 }, |
| 151 |
| 152 /** |
| 153 * Array of values for the EAP EAP Phase 2 authentication (Inner) dropdown |
| 154 * when the Outer type is EAP-TTLS. |
| 155 * @type {!Array<string>} |
| 156 * @const |
| 157 * @private |
| 158 */ |
| 159 eapInnerItemsTtls_: { |
| 160 type: Array, |
| 161 readOnly: true, |
| 162 value: ['Automatic', 'MD5', 'MSCHAP', 'MSCHAPv2', 'PAP', 'CHAP', 'GTC'], |
| 163 }, |
| 164 }, |
| 165 |
| 166 observers: [ |
| 167 'updateConfigProperties_(networkProperties_)', |
| 168 'updateWiFiSecurity_(configProperties_.WiFi.Security)', |
| 169 'updateWiFiEapOuter_(configProperties_.WiFi.EAP.Outer)', |
| 170 ], |
| 171 |
| 172 /** @const */ |
| 173 MIN_PASSPHRASE_LENGTH: 5, |
| 174 |
| 175 /** |
| 176 * settings.RouteObserverBehavior |
| 177 * @param {!settings.Route} route |
| 178 * @protected |
| 179 */ |
| 180 currentRouteChanged: function(route) { |
| 181 if (route != settings.Route.NETWORK_CONFIG) |
| 182 return; |
| 183 |
| 184 var queryParams = settings.getQueryParameters(); |
| 185 this.guid_ = queryParams.get('guid') || ''; |
| 186 |
| 187 // Set networkProperties for new configurations and for existing |
| 188 // configurations until the current properties are loaded. |
| 189 var name = queryParams.get('name') || ''; |
| 190 var typeParam = queryParams.get('type'); |
| 191 var type = typeParam ? CrOnc.getValidType(typeParam) : CrOnc.Type.WI_FI; |
| 192 assert(type && type != CrOnc.Type.ALL); |
| 193 this.networkProperties_ = { |
| 194 GUID: this.guid_, |
| 195 Name: name, |
| 196 Type: type, |
| 197 }; |
| 198 if (this.guid_) { |
| 199 this.networkingPrivate.getProperties( |
| 200 this.guid_, this.getPropertiesCallback_.bind(this)); |
| 201 } |
| 202 }, |
| 203 |
| 204 /** @private */ |
| 205 close_: function() { |
| 206 if (settings.getCurrentRoute() == settings.Route.NETWORK_CONFIG) |
| 207 settings.navigateToPreviousRoute(); |
| 208 }, |
| 209 |
| 210 /** |
| 211 * networkingPrivate.getProperties callback. |
| 212 * @param {!chrome.networkingPrivate.NetworkProperties} properties |
| 213 * @private |
| 214 */ |
| 215 getPropertiesCallback_: function(properties) { |
| 216 if (!properties) { |
| 217 // If |properties| is null, the network no longer exists; close the page. |
| 218 console.error('Network no longer exists: ' + this.guid_); |
| 219 this.close_(); |
| 220 return; |
| 221 } |
| 222 this.propertiesReceived_ = true; |
| 223 this.networkProperties_ = properties; |
| 224 |
| 225 // Set the current shareNetwork_ value when porperties are received. |
| 226 var source = this.networkProperties_.Source; |
| 227 this.shareNetwork_ = source == CrOnc.Source.DEVICE || |
| 228 source == CrOnc.Source.DEVICE_POLICY; |
| 229 }, |
| 230 |
| 231 /** |
| 232 * @return {string} |
| 233 * @private |
| 234 */ |
| 235 computeTitle_: function() { |
| 236 return this.networkProperties_.Name || |
| 237 this.i18n('OncType' + this.networkProperties_.Type); |
| 238 }, |
| 239 |
| 240 /** |
| 241 * Updates the config properties when |this.networkProperties_| changes. |
| 242 * This gets called once when navigating to the page when default properties |
| 243 * are set, and again for existing networks when the properties are received. |
| 244 * @private |
| 245 */ |
| 246 updateConfigProperties_: function() { |
| 247 var properties = this.networkProperties_; |
| 248 var configProperties = |
| 249 /** @type {chrome.networkingPrivate.NetworkConfigProperties} */ ({ |
| 250 Name: properties.Name || '', |
| 251 Type: properties.Type, |
| 252 }); |
| 253 if (properties.Type == CrOnc.Type.WI_FI) { |
| 254 if (properties.WiFi) { |
| 255 configProperties.WiFi = { |
| 256 AutoConnect: properties.WiFi.AutoConnect, |
| 257 EAP: properties.WiFi.EAP, |
| 258 Passphrase: properties.WiFi.Passphrase, |
| 259 SSID: properties.WiFi.SSID, |
| 260 Security: properties.WiFi.Security |
| 261 }; |
| 262 this.savedSecurity_ = properties.WiFi.Security || ''; |
| 263 } else { |
| 264 configProperties.WiFi = { |
| 265 AutoConnect: false, |
| 266 SSID: '', |
| 267 Security: CrOnc.Security.NONE, |
| 268 }; |
| 269 } |
| 270 } |
| 271 this.configProperties_ = configProperties; |
| 272 }, |
| 273 |
| 274 /** |
| 275 * Ensures that the appropriate properties are set or deleted when the |
| 276 * Security type changes. |
| 277 * @private |
| 278 */ |
| 279 updateWiFiSecurity_: function() { |
| 280 assert(this.configProperties_.WiFi); |
| 281 var security = this.configProperties_.WiFi.Security || CrOnc.Security.NONE; |
| 282 if (security == this.savedSecurity_) |
| 283 return; |
| 284 this.savedSecurity_ = security || ''; |
| 285 |
| 286 if (!this.guid_) { |
| 287 // Set the default share state for new configurations. |
| 288 // TODO(stevenjb): also check login state. |
| 289 this.shareNetwork_ = security == CrOnc.Security.NONE; |
| 290 } |
| 291 |
| 292 if (security == CrOnc.Security.WPA_EAP) |
| 293 this.set('configProperties_.WiFi.EAP', {Outer: CrOnc.EAPType.LEAP}); |
| 294 else |
| 295 delete this.configProperties_.WiFi.EAP; |
| 296 }, |
| 297 |
| 298 /** |
| 299 * Ensures that the appropriate EAP properties are created (or deleted when |
| 300 * the EAP.Outer property changes. |
| 301 * @private |
| 302 */ |
| 303 updateWiFiEapOuter_: function() { |
| 304 var eap = this.configProperties_.WiFi.EAP; |
| 305 if (!eap || !eap.Outer) |
| 306 return; |
| 307 var innerItems = this.getEapInnerItems_(eap.Outer); |
| 308 if (innerItems.length > 0) { |
| 309 if (!eap.Inner || innerItems.indexOf(eap.Inner) < 0) |
| 310 this.set('configProperties_.WiFi.EAP.Inner', innerItems[0]); |
| 311 } else { |
| 312 delete eap.Inner; |
| 313 } |
| 314 this.setShowEap_(this.configProperties_.WiFi.EAP); |
| 315 }, |
| 316 |
| 317 /** |
| 318 * @param {CrOnc.Type} type The type to compare against. |
| 319 * @param {CrOnc.Type} networkType The current network type. |
| 320 * @return {boolean} True if the network type matches 'type'. |
| 321 * @private |
| 322 */ |
| 323 isType_: function(type, networkType) { |
| 324 return type == networkType; |
| 325 }, |
| 326 |
| 327 /** |
| 328 * @return {boolean} |
| 329 * @private |
| 330 */ |
| 331 saveIsEnabled_: function() { |
| 332 return this.propertiesReceived_ && !this.propertiesSent_; |
| 333 }, |
| 334 |
| 335 /** |
| 336 * @return {boolean} |
| 337 * @private |
| 338 */ |
| 339 connectIsEnabled_: function() { |
| 340 if (this.propertiesSent_) |
| 341 return false; |
| 342 if (this.configProperties_.Type == CrOnc.Type.WI_FI) { |
| 343 if (!this.get('WiFi.SSID', this.configProperties_)) |
| 344 return false; |
| 345 if (this.configRequiresPassphrase_()) { |
| 346 var passphrase = this.get('WiFi.Passphrase', this.configProperties_); |
| 347 if (!passphrase || passphrase.length < this.MIN_PASSPHRASE_LENGTH) |
| 348 return false; |
| 349 } |
| 350 } |
| 351 // TODO(stevenjb): Check certificates. |
| 352 return true; |
| 353 }, |
| 354 |
| 355 /** |
| 356 * @return {boolean} |
| 357 * @private |
| 358 */ |
| 359 shareIsEnabled_: function() { |
| 360 if (this.networkProperties_.Source == CrOnc.Source.DEVICE || |
| 361 this.networkProperties_.Source == CrOnc.Source.DEVICE_POLICY) { |
| 362 return false; |
| 363 } |
| 364 // TODO(stevenjb): Check login state. |
| 365 |
| 366 if (this.configProperties_.Type == CrOnc.Type.WI_FI) { |
| 367 var security = this.get('WiFi.Security', this.configProperties_); |
| 368 if (!security || security == CrOnc.Security.NONE) { |
| 369 return false; |
| 370 } else if (security == CrOnc.Security.WPA_EAP) { |
| 371 var outer = this.get('WiFi.EAP.Outer', this.configProperties_); |
| 372 if (outer == CrOnc.EAPType.EAP_TLS) |
| 373 return false; |
| 374 } |
| 375 // TODO(stevenjb): Check certificates. |
| 376 } |
| 377 return true; |
| 378 }, |
| 379 |
| 380 /** @private */ |
| 381 onSaveTap_: function() { |
| 382 assert(this.guid_); |
| 383 if (this.propertiesSent_) |
| 384 return; |
| 385 this.propertiesSent_ = true; |
| 386 var propertiesToSet = Object.assign({}, this.configProperties_); |
| 387 propertiesToSet.GUID = this.guid_; |
| 388 this.networkingPrivate.setProperties( |
| 389 this.guid_, propertiesToSet, this.setPropertiesCallback_.bind(this)); |
| 390 }, |
| 391 |
| 392 /** @private */ |
| 393 setPropertiesCallback_: function() { |
| 394 var error = chrome.runtime.lastError && chrome.runtime.lastError.message; |
| 395 if (error) { |
| 396 console.error( |
| 397 'Error setting network properties: ' + this.guid_ + ': ' + error); |
| 398 } |
| 399 this.close_(); |
| 400 }, |
| 401 |
| 402 /** @private */ |
| 403 onConnectTap_: function() { |
| 404 assert(!this.guid_); |
| 405 if (this.propertiesSent_) |
| 406 return; |
| 407 this.propertiesSent_ = true; |
| 408 // Create the configuration, then connect to it in the callback. |
| 409 this.networkingPrivate.createNetwork( |
| 410 this.shareNetwork_, this.configProperties_, |
| 411 this.createNetworkCallback_.bind(this)); |
| 412 }, |
| 413 |
| 414 /** |
| 415 * @param {string} guid |
| 416 * @private |
| 417 */ |
| 418 createNetworkCallback_: function(guid) { |
| 419 var error = chrome.runtime.lastError && chrome.runtime.lastError.message; |
| 420 if (error) { |
| 421 // TODO(stevenjb): Display error message. |
| 422 console.error( |
| 423 'Error creating network type: ' + this.networkProperties_.Type + |
| 424 ': ' + error); |
| 425 return; |
| 426 } |
| 427 this.networkProperties_.GUID = guid; |
| 428 this.fire('network-connect', {networkProperties: this.networkProperties_}); |
| 429 this.close_(); |
| 430 }, |
| 431 |
| 432 /** @private */ |
| 433 onCancelTap_: function() { |
| 434 this.close_(); |
| 435 }, |
| 436 |
| 437 /** |
| 438 * @return boolean |
| 439 * @private |
| 440 */ |
| 441 configRequiresPassphrase_: function() { |
| 442 if (this.configProperties_.Type != CrOnc.Type.WI_FI) |
| 443 return false; |
| 444 var security = this.get('WiFi.Security', this.configProperties_); |
| 445 return security == CrOnc.Security.WEP_PSK || |
| 446 security == CrOnc.Security.WPA_PSK; |
| 447 }, |
| 448 |
| 449 /** |
| 450 * Sets the EAP properties for |eap|, which may be WiFi.EAP, Ethernet.EAP etc. |
| 451 * @private |
| 452 */ |
| 453 setShowEap_: function(eap) { |
| 454 var outer = eap.Outer; |
| 455 this.showEap_ = { |
| 456 Inner: outer == CrOnc.EAPType.PEAP || outer == CrOnc.EAPType.EAP_TTLS, |
| 457 ServerCA: outer != CrOnc.EAPType.LEAP, |
| 458 SubjectMatch: outer == CrOnc.EAPType.EAP_TLS, |
| 459 UserCert: outer == CrOnc.EAPType.EAP_TLS, |
| 460 Password: outer != CrOnc.EAPType.EAP_TLS, |
| 461 AnonymousIdentity: |
| 462 outer == CrOnc.EAPType.PEAP || outer == CrOnc.EAPType.EAP_TTLS, |
| 463 }; |
| 464 }, |
| 465 |
| 466 /** |
| 467 * @param {string} outer |
| 468 * @return {!Array<string>} |
| 469 * @private |
| 470 */ |
| 471 getEapInnerItems_: function(outer) { |
| 472 if (outer == CrOnc.EAPType.PEAP) |
| 473 return this.eapInnerItemsPeap_; |
| 474 if (outer == CrOnc.EAPType.EAP_TTLS) |
| 475 return this.eapInnerItemsTtls_; |
| 476 return []; |
| 477 }, |
| 478 }); |
OLD | NEW |