Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Side by Side Diff: chrome/browser/resources/gaia_auth_host/authenticator.js

Issue 1063753004: Use HTML messages to inform GAIA about deviceId. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update after review. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 <include src="saml_handler.js"> 5 <include src="saml_handler.js">
6 6
7 /** 7 /**
8 * @fileoverview An UI component to authenciate to Chrome. The component hosts 8 * @fileoverview An UI component to authenciate to Chrome. The component hosts
9 * IdP web pages in a webview. A client who is interested in monitoring 9 * IdP web pages in a webview. A client who is interested in monitoring
10 * authentication events should pass a listener object of type 10 * authentication events should pass a listener object of type
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 path = IDP_PATH; 240 path = IDP_PATH;
241 var url = this.idpOrigin_ + path; 241 var url = this.idpOrigin_ + path;
242 242
243 if (this.isNewGaiaFlowChromeOS) { 243 if (this.isNewGaiaFlowChromeOS) {
244 if (data.chromeType) 244 if (data.chromeType)
245 url = appendParam(url, 'chrometype', data.chromeType); 245 url = appendParam(url, 'chrometype', data.chromeType);
246 if (data.clientId) 246 if (data.clientId)
247 url = appendParam(url, 'client_id', data.clientId); 247 url = appendParam(url, 'client_id', data.clientId);
248 if (data.enterpriseDomain) 248 if (data.enterpriseDomain)
249 url = appendParam(url, 'manageddomain', data.enterpriseDomain); 249 url = appendParam(url, 'manageddomain', data.enterpriseDomain);
250 this.setDeviceId(data.deviceId); 250 this.deviceId_ = data.deviceId;
251 this.sessionIsEphemeral_ = data.sessionIsEphemeral; 251 this.sessionIsEphemeral_ = data.sessionIsEphemeral;
252 } else { 252 } else {
253 url = appendParam(url, 'continue', this.continueUrl_); 253 url = appendParam(url, 'continue', this.continueUrl_);
254 url = appendParam(url, 'service', data.service || SERVICE_ID); 254 url = appendParam(url, 'service', data.service || SERVICE_ID);
255 } 255 }
256 if (data.hl) 256 if (data.hl)
257 url = appendParam(url, 'hl', data.hl); 257 url = appendParam(url, 'hl', data.hl);
258 if (data.gaiaId) 258 if (data.gaiaId)
259 url = appendParam(url, 'user_id', data.gaiaId); 259 url = appendParam(url, 'user_id', data.gaiaId);
260 if (data.email) 260 if (data.email)
261 url = appendParam(url, 'Email', data.email); 261 url = appendParam(url, 'Email', data.email);
262 if (this.isConstrainedWindow_) 262 if (this.isConstrainedWindow_)
263 url = appendParam(url, 'source', CONSTRAINED_FLOW_SOURCE); 263 url = appendParam(url, 'source', CONSTRAINED_FLOW_SOURCE);
264 if (data.flow) 264 if (data.flow)
265 url = appendParam(url, 'flow', data.flow); 265 url = appendParam(url, 'flow', data.flow);
266 if (data.emailDomain) 266 if (data.emailDomain)
267 url = appendParam(url, 'emaildomain', data.emailDomain); 267 url = appendParam(url, 'emaildomain', data.emailDomain);
268 return url; 268 return url;
269 }; 269 };
270 270
271 /** 271 /**
272 * Invoked when deviceId is set or updated.
273 */
274 Authenticator.prototype.setDeviceId = function(deviceId) {
275 this.deviceId_ = deviceId;
276 };
277
278 /**
279 * Invoked when a main frame request in the webview has completed. 272 * Invoked when a main frame request in the webview has completed.
280 * @private 273 * @private
281 */ 274 */
282 Authenticator.prototype.onRequestCompleted_ = function(details) { 275 Authenticator.prototype.onRequestCompleted_ = function(details) {
283 var currentUrl = details.url; 276 var currentUrl = details.url;
284 277
285 if (currentUrl.lastIndexOf(this.continueUrlWithoutParams_, 0) == 0) { 278 if (currentUrl.lastIndexOf(this.continueUrlWithoutParams_, 0) == 0) {
286 if (currentUrl.indexOf('ntp=1') >= 0) 279 if (currentUrl.indexOf('ntp=1') >= 0)
287 this.skipForNow_ = true; 280 this.skipForNow_ = true;
288 281
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 * Handler for webView.request.onBeforeSendHeaders . 386 * Handler for webView.request.onBeforeSendHeaders .
394 * @return {!Object} Modified request headers. 387 * @return {!Object} Modified request headers.
395 * @private 388 * @private
396 */ 389 */
397 Authenticator.prototype.onBeforeSendHeaders_ = function(details) { 390 Authenticator.prototype.onBeforeSendHeaders_ = function(details) {
398 // deviceId_ is empty when we do not need to send it. For example, 391 // deviceId_ is empty when we do not need to send it. For example,
399 // in case of device enrollment. 392 // in case of device enrollment.
400 if (this.isNewGaiaFlowChromeOS && this.deviceId_) { 393 if (this.isNewGaiaFlowChromeOS && this.deviceId_) {
401 var headers = details.requestHeaders; 394 var headers = details.requestHeaders;
402 var found = false; 395 var found = false;
403 var deviceId; 396 var deviceId = this.getGAIADeviceId_();
404 if (this.sessionIsEphemeral_)
405 deviceId = EPHEMERAL_DEVICE_ID_PREFIX + this.deviceId_;
406 else
407 deviceId = this.deviceId_;
408 397
409 for (var i = 0, l = headers.length; i < l; ++i) { 398 for (var i = 0, l = headers.length; i < l; ++i) {
410 if (headers[i].name == X_DEVICE_ID_HEADER) { 399 if (headers[i].name == X_DEVICE_ID_HEADER) {
411 headers[i].value = deviceId; 400 headers[i].value = deviceId;
412 found = true; 401 found = true;
413 break; 402 break;
414 } 403 }
415 } 404 }
416 if (!found) { 405 if (!found) {
417 details.requestHeaders.push( 406 details.requestHeaders.push(
418 {name: X_DEVICE_ID_HEADER, value: deviceId}); 407 {name: X_DEVICE_ID_HEADER, value: deviceId});
419 } 408 }
420 } 409 }
421 return { 410 return {
422 requestHeaders: details.requestHeaders 411 requestHeaders: details.requestHeaders
423 }; 412 };
424 }; 413 };
425 414
426 /** 415 /**
416 * Returns true if given HTML5 message is received from the webview element.
417 * @param {object} e Payload of the received HTML5 message.
418 */
419 Authenticator.prototype.isGaiaMessage = function(e) {
420 if (!this.isWebviewEvent_(e))
421 return false;
422
423 // The event origin does not have a trailing slash.
424 if (e.origin != this.idpOrigin_.substring(0, this.idpOrigin_.length - 1)) {
425 return false;
426 }
427
428 // Gaia messages must be an object with 'method' property.
429 if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) {
430 return false;
431 }
432 return true;
433 };
434
435 /**
427 * Invoked when an HTML5 message is received from the webview element. 436 * Invoked when an HTML5 message is received from the webview element.
428 * @param {object} e Payload of the received HTML5 message. 437 * @param {object} e Payload of the received HTML5 message.
429 * @private 438 * @private
430 */ 439 */
431 Authenticator.prototype.onMessageFromWebview_ = function(e) { 440 Authenticator.prototype.onMessageFromWebview_ = function(e) {
432 if (!this.isWebviewEvent_(e)) 441 if (!this.isGaiaMessage(e))
433 return; 442 return;
434 443
435 // The event origin does not have a trailing slash.
436 if (e.origin != this.idpOrigin_.substring(0, this.idpOrigin_.length - 1)) {
437 return;
438 }
439
440 // Gaia messages must be an object with 'method' property.
441 if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) {
442 return;
443 }
444
445 var msg = e.data; 444 var msg = e.data;
446 if (msg.method == 'attemptLogin') { 445 if (msg.method == 'attemptLogin') {
447 this.email_ = msg.email; 446 this.email_ = msg.email;
448 this.password_ = msg.password; 447 this.password_ = msg.password;
449 this.chooseWhatToSync_ = msg.chooseWhatToSync; 448 this.chooseWhatToSync_ = msg.chooseWhatToSync;
449 // We need to dispatch only first event, before user enters password.
450 if (!msg.password) {
451 this.dispatchEvent(
452 new CustomEvent('attemptLogin', {detail: msg.email}));
453 }
450 } else if (msg.method == 'dialogShown') { 454 } else if (msg.method == 'dialogShown') {
451 this.dispatchEvent(new Event('dialogShown')); 455 this.dispatchEvent(new Event('dialogShown'));
452 } else if (msg.method == 'dialogHidden') { 456 } else if (msg.method == 'dialogHidden') {
453 this.dispatchEvent(new Event('dialogHidden')); 457 this.dispatchEvent(new Event('dialogHidden'));
454 } else if (msg.method == 'backButton') { 458 } else if (msg.method == 'backButton') {
455 this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show})); 459 this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show}));
456 } else if (msg.method == 'showView') { 460 } else if (msg.method == 'showView') {
457 this.dispatchEvent(new Event('showView')); 461 this.dispatchEvent(new Event('showView'));
458 } else { 462 } else {
459 console.warn('Unrecognized message from GAIA: ' + msg.method); 463 console.warn('Unrecognized message from GAIA: ' + msg.method);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 // webview from the zooming of other webviews using the 'per-view' zoom 609 // webview from the zooming of other webviews using the 'per-view' zoom
606 // mode, and then set it to 100% zoom. 610 // mode, and then set it to 100% zoom.
607 this.webview_.setZoomMode('per-view'); 611 this.webview_.setZoomMode('per-view');
608 this.webview_.setZoom(1); 612 this.webview_.setZoom(1);
609 } 613 }
610 614
611 // Posts a message to IdP pages to initiate communication. 615 // Posts a message to IdP pages to initiate communication.
612 var currentUrl = this.webview_.src; 616 var currentUrl = this.webview_.src;
613 if (currentUrl.lastIndexOf(this.idpOrigin_) == 0) { 617 if (currentUrl.lastIndexOf(this.idpOrigin_) == 0) {
614 var msg = { 618 var msg = {
615 'method': 'handshake' 619 'method': 'handshake',
620 'deviceId': this.getGAIADeviceId_(),
616 }; 621 };
622
617 this.webview_.contentWindow.postMessage(msg, currentUrl); 623 this.webview_.contentWindow.postMessage(msg, currentUrl);
618 } 624 }
619 }; 625 };
620 626
621 /** 627 /**
622 * Invoked when the webview fails loading a page. 628 * Invoked when the webview fails loading a page.
623 * @private 629 * @private
624 */ 630 */
625 Authenticator.prototype.onLoadAbort_ = function(e) { 631 Authenticator.prototype.onLoadAbort_ = function(e) {
626 this.dispatchEvent(new CustomEvent('loadAbort', 632 this.dispatchEvent(new CustomEvent('loadAbort',
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 */ 664 */
659 Authenticator.prototype.isWebviewEvent_ = function(e) { 665 Authenticator.prototype.isWebviewEvent_ = function(e) {
660 // Note: <webview> prints error message to console if |contentWindow| is not 666 // Note: <webview> prints error message to console if |contentWindow| is not
661 // defined. 667 // defined.
662 // TODO(dzhioev): remove the message. http://crbug.com/469522 668 // TODO(dzhioev): remove the message. http://crbug.com/469522
663 var webviewWindow = this.webview_.contentWindow; 669 var webviewWindow = this.webview_.contentWindow;
664 return !!webviewWindow && webviewWindow === e.source; 670 return !!webviewWindow && webviewWindow === e.source;
665 }; 671 };
666 672
667 /** 673 /**
674 * Format deviceId for GAIA .
675 * @return {string} deviceId.
676 * @private
677 */
678 Authenticator.prototype.getGAIADeviceId_ = function() {
679 // deviceId_ is empty when we do not need to send it. For example,
680 // in case of device enrollment.
681 if (!(this.isNewGaiaFlowChromeOS && this.deviceId_))
682 return;
683
684 if (this.sessionIsEphemeral_)
685 return EPHEMERAL_DEVICE_ID_PREFIX + this.deviceId_;
686 else
687 return this.deviceId_;
688 };
689
690 /**
691 * Informs Gaia of new deviceId to be used.
692 */
693 Authenticator.prototype.updateDeviceId = function(deviceId) {
694 this.deviceId_ = deviceId;
695 var msg = {
696 'method': 'updateDeviceId',
697 'deviceId': this.getGAIADeviceId_(),
698 };
699
700 var currentUrl = this.webview_.src;
701 this.webview_.contentWindow.postMessage(msg, currentUrl);
702 };
703
704 /**
668 * The current auth flow of the hosted auth page. 705 * The current auth flow of the hosted auth page.
669 * @type {AuthFlow} 706 * @type {AuthFlow}
670 */ 707 */
671 cr.defineProperty(Authenticator, 'authFlow'); 708 cr.defineProperty(Authenticator, 'authFlow');
672 709
673 Authenticator.AuthFlow = AuthFlow; 710 Authenticator.AuthFlow = AuthFlow;
674 Authenticator.AuthMode = AuthMode; 711 Authenticator.AuthMode = AuthMode;
675 Authenticator.SUPPORTED_PARAMS = SUPPORTED_PARAMS; 712 Authenticator.SUPPORTED_PARAMS = SUPPORTED_PARAMS;
676 713
677 return { 714 return {
678 // TODO(guohui, xiyuan): Rename GaiaAuthHost to Authenticator once the old 715 // TODO(guohui, xiyuan): Rename GaiaAuthHost to Authenticator once the old
679 // iframe-based flow is deprecated. 716 // iframe-based flow is deprecated.
680 GaiaAuthHost: Authenticator, 717 GaiaAuthHost: Authenticator,
681 Authenticator: Authenticator 718 Authenticator: Authenticator
682 }; 719 };
683 }); 720 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698