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, | |
tbarzic
2017/05/24 00:46:57
optional suggestion: you could rename this to some
stevenjb
2017/05/24 16:27:26
Acknowledged, but I think I prefer the more explic
| |
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 |