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

Side by Side Diff: chrome/browser/resources/gaia_auth/main.js

Issue 671183002: Revert of Inline sign in extracts gaia id from HTTP header and seeds account tracker (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 /** 5 /**
6 * Authenticator class wraps the communications between Gaia and its host. 6 * Authenticator class wraps the communications between Gaia and its host.
7 */ 7 */
8 function Authenticator() { 8 function Authenticator() {
9 } 9 }
10 10
(...skipping 30 matching lines...) Expand all
41 */ 41 */
42 Authenticator.getInstance = function() { 42 Authenticator.getInstance = function() {
43 if (!Authenticator.instance_) { 43 if (!Authenticator.instance_) {
44 Authenticator.instance_ = new Authenticator(); 44 Authenticator.instance_ = new Authenticator();
45 } 45 }
46 return Authenticator.instance_; 46 return Authenticator.instance_;
47 }; 47 };
48 48
49 Authenticator.prototype = { 49 Authenticator.prototype = {
50 email_: null, 50 email_: null,
51 gaiaId_: null,
52 51
53 // Depending on the key type chosen, this will contain the plain text password 52 // Depending on the key type chosen, this will contain the plain text password
54 // or a credential derived from it along with the information required to 53 // or a credential derived from it along with the information required to
55 // repeat the derivation, such as a salt. The information will be encoded so 54 // repeat the derivation, such as a salt. The information will be encoded so
56 // that it contains printable ASCII characters only. The exact encoding is TBD 55 // that it contains printable ASCII characters only. The exact encoding is TBD
57 // when support for key types other than plain text password is added. 56 // when support for key types other than plain text password is added.
58 passwordBytes_: null, 57 passwordBytes_: null,
59 58
60 chooseWhatToSync_: false,
61 skipForNow_: false,
62 sessionIndex_: null,
63 attemptToken_: null, 59 attemptToken_: null,
64 60
65 // Input params from extension initialization URL. 61 // Input params from extension initialization URL.
66 inputLang_: undefined, 62 inputLang_: undefined,
67 intputEmail_: undefined, 63 intputEmail_: undefined,
68 64
69 isSAMLFlow_: false, 65 isSAMLFlow_: false,
70 gaiaLoaded_: false, 66 gaiaLoaded_: false,
71 supportChannel_: null, 67 supportChannel_: null,
72 68
(...skipping 28 matching lines...) Expand all
101 97
102 document.addEventListener('DOMContentLoaded', this.onPageLoad_.bind(this)); 98 document.addEventListener('DOMContentLoaded', this.onPageLoad_.bind(this));
103 }, 99 },
104 100
105 isGaiaMessage_: function(msg) { 101 isGaiaMessage_: function(msg) {
106 // Not quite right, but good enough. 102 // Not quite right, but good enough.
107 return this.gaiaUrl_.indexOf(msg.origin) == 0 || 103 return this.gaiaUrl_.indexOf(msg.origin) == 0 ||
108 this.GAIA_URL.indexOf(msg.origin) == 0; 104 this.GAIA_URL.indexOf(msg.origin) == 0;
109 }, 105 },
110 106
107 isInternalMessage_: function(msg) {
108 return msg.origin == Authenticator.THIS_EXTENSION_ORIGIN;
109 },
110
111 isParentMessage_: function(msg) { 111 isParentMessage_: function(msg) {
112 return msg.origin == this.parentPage_; 112 return msg.origin == this.parentPage_;
113 }, 113 },
114 114
115 constructInitialFrameUrl_: function() { 115 constructInitialFrameUrl_: function() {
116 var url = this.gaiaUrl_ + this.gaiaPath_; 116 var url = this.gaiaUrl_ + this.gaiaPath_;
117 117
118 url = appendParam(url, 'service', this.service_); 118 url = appendParam(url, 'service', this.service_);
119 url = appendParam(url, 'continue', this.continueUrl_); 119 url = appendParam(url, 'continue', this.continueUrl_);
120 if (this.inputLang_) 120 if (this.inputLang_)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 158
159 if (this.desktopMode_) { 159 if (this.desktopMode_) {
160 this.supportChannel_.send({ 160 this.supportChannel_.send({
161 name: 'initDesktopFlow', 161 name: 'initDesktopFlow',
162 gaiaUrl: this.gaiaUrl_, 162 gaiaUrl: this.gaiaUrl_,
163 continueUrl: stripParams(this.continueUrl_), 163 continueUrl: stripParams(this.continueUrl_),
164 isConstrainedWindow: this.isConstrainedWindow_ 164 isConstrainedWindow: this.isConstrainedWindow_
165 }); 165 });
166 this.supportChannel_.registerMessage( 166 this.supportChannel_.registerMessage(
167 'switchToFullTab', this.switchToFullTab_.bind(this)); 167 'switchToFullTab', this.switchToFullTab_.bind(this));
168 this.supportChannel_.registerMessage(
169 'completeLogin', this.completeLogin_.bind(this));
168 } 170 }
169 this.supportChannel_.registerMessage(
170 'completeLogin', this.onCompleteLogin_.bind(this));
171 this.initSAML_(); 171 this.initSAML_();
172 this.maybeInitialized_(); 172 this.maybeInitialized_();
173 }.bind(this)); 173 }.bind(this));
174 174
175 window.setTimeout(function() { 175 window.setTimeout(function() {
176 if (!this.supportChannel_) { 176 if (!this.supportChannel_) {
177 // Re-initialize the channel if it is not connected properly, e.g. 177 // Re-initialize the channel if it is not connected properly, e.g.
178 // connect may be called before background script started running. 178 // connect may be called before background script started running.
179 this.initSupportChannel_(); 179 this.initSupportChannel_();
180 } 180 }
(...skipping 10 matching lines...) Expand all
191 return; 191 return;
192 var msg = { 192 var msg = {
193 'method': 'loginUILoaded' 193 'method': 'loginUILoaded'
194 }; 194 };
195 window.parent.postMessage(msg, this.parentPage_); 195 window.parent.postMessage(msg, this.parentPage_);
196 }, 196 },
197 197
198 /** 198 /**
199 * Invoked when the background script sends a message to indicate that the 199 * Invoked when the background script sends a message to indicate that the
200 * current content does not fit in a constrained window. 200 * current content does not fit in a constrained window.
201 * @param {Object=} msg Extra info to send. 201 * @param {Object=} opt_extraMsg Optional extra info to send.
202 */ 202 */
203 switchToFullTab_: function(msg) { 203 switchToFullTab_: function(msg) {
204 var parentMsg = { 204 var parentMsg = {
205 'method': 'switchToFullTab', 205 'method': 'switchToFullTab',
206 'url': msg.url 206 'url': msg.url
207 }; 207 };
208 window.parent.postMessage(parentMsg, this.parentPage_); 208 window.parent.postMessage(parentMsg, this.parentPage_);
209 }, 209 },
210 210
211 /** 211 /**
212 * Invoked when the signin flow is complete. 212 * Invoked when the signin flow is complete.
213 * @param {Object=} opt_extraMsg Optional extra info to send. 213 * @param {Object=} opt_extraMsg Optional extra info to send.
214 */ 214 */
215 completeLogin_: function(opt_extraMsg) { 215 completeLogin_: function(opt_extraMsg) {
216 var msg = { 216 var msg = {
217 'method': 'completeLogin', 217 'method': 'completeLogin',
218 'email': (opt_extraMsg && opt_extraMsg.email) || this.email_, 218 'email': (opt_extraMsg && opt_extraMsg.email) || this.email_,
219 'password': (opt_extraMsg && opt_extraMsg.password) || 219 'password': (opt_extraMsg && opt_extraMsg.password) ||
220 this.passwordBytes_, 220 this.passwordBytes_,
221 'usingSAML': this.isSAMLFlow_, 221 'usingSAML': this.isSAMLFlow_,
222 'chooseWhatToSync': this.chooseWhatToSync_ || false, 222 'chooseWhatToSync': this.chooseWhatToSync_ || false,
223 'skipForNow': (opt_extraMsg && opt_extraMsg.skipForNow) || 223 'skipForNow': opt_extraMsg && opt_extraMsg.skipForNow,
224 this.skipForNow_, 224 'sessionIndex': opt_extraMsg && opt_extraMsg.sessionIndex
225 'sessionIndex': (opt_extraMsg && opt_extraMsg.sessionIndex) ||
226 this.sessionIndex_,
227 'gaiaId': (opt_extraMsg && opt_extraMsg.gaiaId) || this.gaiaId_
228 }; 225 };
229 window.parent.postMessage(msg, this.parentPage_); 226 window.parent.postMessage(msg, this.parentPage_);
230 this.supportChannel_.send({name: 'resetAuth'}); 227 this.supportChannel_.send({name: 'resetAuth'});
231 }, 228 },
232 229
233 /** 230 /**
234 * Invoked when support channel is connected. 231 * Invoked when support channel is connected.
235 */ 232 */
236 initSAML_: function() { 233 initSAML_: function() {
237 this.isSAMLFlow_ = false; 234 this.isSAMLFlow_ = false;
(...skipping 26 matching lines...) Expand all
264 */ 261 */
265 onAuthPageLoaded_: function(msg) { 262 onAuthPageLoaded_: function(msg) {
266 var isSAMLPage = msg.url.indexOf(this.gaiaUrl_) != 0; 263 var isSAMLPage = msg.url.indexOf(this.gaiaUrl_) != 0;
267 264
268 if (isSAMLPage && !this.isSAMLFlow_) { 265 if (isSAMLPage && !this.isSAMLFlow_) {
269 // GAIA redirected to a SAML login page. The credentials provided to this 266 // GAIA redirected to a SAML login page. The credentials provided to this
270 // page will determine what user gets logged in. The credentials obtained 267 // page will determine what user gets logged in. The credentials obtained
271 // from the GAIA login form are no longer relevant and can be discarded. 268 // from the GAIA login form are no longer relevant and can be discarded.
272 this.isSAMLFlow_ = true; 269 this.isSAMLFlow_ = true;
273 this.email_ = null; 270 this.email_ = null;
274 this.gaiaId_ = null;
275 this.passwordBytes_ = null; 271 this.passwordBytes_ = null;
276 } 272 }
277 273
278 window.parent.postMessage({ 274 window.parent.postMessage({
279 'method': 'authPageLoaded', 275 'method': 'authPageLoaded',
280 'isSAML': this.isSAMLFlow_, 276 'isSAML': this.isSAMLFlow_,
281 'domain': extractDomain(msg.url) 277 'domain': extractDomain(msg.url)
282 }, this.parentPage_); 278 }, this.parentPage_);
283 }, 279 },
284 280
(...skipping 28 matching lines...) Expand all
313 this.initialized_ = true; 309 this.initialized_ = true;
314 this.sendInitializationSuccess_(); 310 this.sendInitializationSuccess_();
315 return; 311 return;
316 } 312 }
317 313
318 if (call.method == 'add') { 314 if (call.method == 'add') {
319 if (Authenticator.API_KEY_TYPES.indexOf(call.keyType) == -1) { 315 if (Authenticator.API_KEY_TYPES.indexOf(call.keyType) == -1) {
320 console.error('Authenticator.onAPICall_: unsupported key type'); 316 console.error('Authenticator.onAPICall_: unsupported key type');
321 return; 317 return;
322 } 318 }
323 // Not setting |email_| and |gaiaId_| because this API call will
324 // eventually be followed by onCompleteLogin_() which does set it.
325 this.apiToken_ = call.token; 319 this.apiToken_ = call.token;
320 this.email_ = call.user;
326 this.passwordBytes_ = call.passwordBytes; 321 this.passwordBytes_ = call.passwordBytes;
327 } else if (call.method == 'confirm') { 322 } else if (call.method == 'confirm') {
328 if (call.token != this.apiToken_) 323 if (call.token != this.apiToken_)
329 console.error('Authenticator.onAPICall_: token mismatch'); 324 console.error('Authenticator.onAPICall_: token mismatch');
330 } else { 325 } else {
331 console.error('Authenticator.onAPICall_: unknown message'); 326 console.error('Authenticator.onAPICall_: unknown message');
332 } 327 }
333 }, 328 },
334 329
335 sendInitializationSuccess_: function() { 330 sendInitializationSuccess_: function() {
336 this.supportChannel_.send({name: 'apiResponse', response: { 331 this.supportChannel_.send({name: 'apiResponse', response: {
337 result: 'initialized', 332 result: 'initialized',
338 version: this.apiVersion_, 333 version: this.apiVersion_,
339 keyTypes: Authenticator.API_KEY_TYPES 334 keyTypes: Authenticator.API_KEY_TYPES
340 }}); 335 }});
341 }, 336 },
342 337
343 sendInitializationFailure_: function() { 338 sendInitializationFailure_: function() {
344 this.supportChannel_.send({ 339 this.supportChannel_.send({
345 name: 'apiResponse', 340 name: 'apiResponse',
346 response: {result: 'initialization_failed'} 341 response: {result: 'initialization_failed'}
347 }); 342 });
348 }, 343 },
349 344
350 /** 345 onConfirmLogin_: function() {
351 * Callback invoked for 'completeLogin' message. 346 if (!this.isSAMLFlow_) {
352 * @param {Object=} msg Message sent from background page. 347 this.completeLogin_();
353 */
354 onCompleteLogin_: function(msg) {
355 if (!msg.email || !msg.gaiaId || !msg.sessionIndex) {
356 console.error('Missing fields to complete login.');
357 window.parent.postMessage({method: 'missingGaiaInfo'}, this.parentPage_);
358 return; 348 return;
359 } 349 }
360 350
361 // Skip SAML extra steps for desktop flow and non-SAML flow. 351 var apiUsed = !!this.passwordBytes_;
362 if (!this.isSAMLFlow_ || this.desktopMode_) {
363 this.completeLogin_(msg);
364 return;
365 }
366 352
367 this.email_ = msg.email; 353 // Retrieve the e-mail address of the user who just authenticated from GAIA.
368 this.gaiaId_ = msg.gaiaId; 354 window.parent.postMessage({method: 'retrieveAuthenticatedUserEmail',
369 // Password from |msg| is not used because ChromeOS SAML flow 355 attemptToken: this.attemptToken_,
370 // gets password by asking user to confirm. 356 apiUsed: apiUsed},
371 this.skipForNow_ = msg.skipForNow; 357 this.parentPage_);
372 this.sessionIndex_ = msg.sessionIndex;
373 358
374 if (this.passwordBytes_) { 359 if (!apiUsed) {
375 window.parent.postMessage({method: 'samlApiUsed'}, this.parentPage_);
376 this.completeLogin_(msg);
377 } else {
378 this.supportChannel_.sendWithCallback( 360 this.supportChannel_.sendWithCallback(
379 {name: 'getScrapedPasswords'}, 361 {name: 'getScrapedPasswords'},
380 function(passwords) { 362 function(passwords) {
381 if (passwords.length == 0) { 363 if (passwords.length == 0) {
382 window.parent.postMessage( 364 window.parent.postMessage(
383 {method: 'noPassword', email: this.email_}, 365 {method: 'noPassword', email: this.email_},
384 this.parentPage_); 366 this.parentPage_);
385 } else { 367 } else {
386 window.parent.postMessage({method: 'confirmPassword', 368 window.parent.postMessage({method: 'confirmPassword',
387 email: this.email_, 369 email: this.email_,
388 passwordCount: passwords.length}, 370 passwordCount: passwords.length},
389 this.parentPage_); 371 this.parentPage_);
390 } 372 }
391 }.bind(this)); 373 }.bind(this));
392 } 374 }
393 }, 375 },
394 376
377 maybeCompleteSAMLLogin_: function() {
378 // SAML login is complete when the user's e-mail address has been retrieved
379 // from GAIA and the user has successfully confirmed the password.
380 if (this.email_ !== null && this.passwordBytes_ !== null)
381 this.completeLogin_();
382 },
383
395 onVerifyConfirmedPassword_: function(password) { 384 onVerifyConfirmedPassword_: function(password) {
396 this.supportChannel_.sendWithCallback( 385 this.supportChannel_.sendWithCallback(
397 {name: 'getScrapedPasswords'}, 386 {name: 'getScrapedPasswords'},
398 function(passwords) { 387 function(passwords) {
399 for (var i = 0; i < passwords.length; ++i) { 388 for (var i = 0; i < passwords.length; ++i) {
400 if (passwords[i] == password) { 389 if (passwords[i] == password) {
401 this.passwordBytes_ = passwords[i]; 390 this.passwordBytes_ = passwords[i];
402 // SAML login is complete when the user has successfully 391 this.maybeCompleteSAMLLogin_();
403 // confirmed the password.
404 if (this.passwordBytes_ !== null)
405 this.completeLogin_();
406 return; 392 return;
407 } 393 }
408 } 394 }
409 window.parent.postMessage( 395 window.parent.postMessage(
410 {method: 'confirmPassword', email: this.email_}, 396 {method: 'confirmPassword', email: this.email_},
411 this.parentPage_); 397 this.parentPage_);
412 }.bind(this)); 398 }.bind(this));
413 }, 399 },
414 400
415 onMessage: function(e) { 401 onMessage: function(e) {
416 var msg = e.data; 402 var msg = e.data;
417 if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) { 403 if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) {
418 // At this point GAIA does not yet know the gaiaId, so its not set here.
419 this.email_ = msg.email; 404 this.email_ = msg.email;
420 this.passwordBytes_ = msg.password; 405 this.passwordBytes_ = msg.password;
421 this.attemptToken_ = msg.attemptToken; 406 this.attemptToken_ = msg.attemptToken;
422 this.chooseWhatToSync_ = msg.chooseWhatToSync; 407 this.chooseWhatToSync_ = msg.chooseWhatToSync;
423 this.isSAMLFlow_ = false; 408 this.isSAMLFlow_ = false;
424 if (this.supportChannel_) 409 if (this.supportChannel_)
425 this.supportChannel_.send({name: 'startAuth'}); 410 this.supportChannel_.send({name: 'startAuth'});
426 else 411 else
427 console.error('Support channel is not initialized.'); 412 console.error('Support channel is not initialized.');
428 } else if (msg.method == 'clearOldAttempts' && this.isGaiaMessage_(e)) { 413 } else if (msg.method == 'clearOldAttempts' && this.isGaiaMessage_(e)) {
429 if (!this.gaiaLoaded_) { 414 if (!this.gaiaLoaded_) {
430 this.gaiaLoaded_ = true; 415 this.gaiaLoaded_ = true;
431 this.maybeInitialized_(); 416 this.maybeInitialized_();
432 } 417 }
433 this.email_ = null; 418 this.email_ = null;
434 this.gaiaId_ = null;
435 this.sessionIndex_ = false;
436 this.passwordBytes_ = null; 419 this.passwordBytes_ = null;
437 this.attemptToken_ = null; 420 this.attemptToken_ = null;
438 this.isSAMLFlow_ = false; 421 this.isSAMLFlow_ = false;
439 this.skipForNow_ = false;
440 this.chooseWhatToSync_ = false;
441 if (this.supportChannel_) 422 if (this.supportChannel_)
442 this.supportChannel_.send({name: 'resetAuth'}); 423 this.supportChannel_.send({name: 'resetAuth'});
424 } else if (msg.method == 'setAuthenticatedUserEmail' &&
425 this.isParentMessage_(e)) {
426 if (this.attemptToken_ == msg.attemptToken) {
427 this.email_ = msg.email;
428 this.maybeCompleteSAMLLogin_();
429 }
430 } else if (msg.method == 'confirmLogin' && this.isInternalMessage_(e)) {
431 // In the desktop mode, Chrome needs to wait for extra info such as
432 // session index from the background JS.
433 if (this.desktopMode_)
434 return;
435
436 if (this.attemptToken_ == msg.attemptToken)
437 this.onConfirmLogin_();
438 else
439 console.error('Authenticator.onMessage: unexpected attemptToken!?');
443 } else if (msg.method == 'verifyConfirmedPassword' && 440 } else if (msg.method == 'verifyConfirmedPassword' &&
444 this.isParentMessage_(e)) { 441 this.isParentMessage_(e)) {
445 this.onVerifyConfirmedPassword_(msg.password); 442 this.onVerifyConfirmedPassword_(msg.password);
446 } else if (msg.method == 'redirectToSignin' && 443 } else if (msg.method == 'redirectToSignin' &&
447 this.isParentMessage_(e)) { 444 this.isParentMessage_(e)) {
448 $('gaia-frame').src = this.constructInitialFrameUrl_(); 445 $('gaia-frame').src = this.constructInitialFrameUrl_();
449 } else { 446 } else {
450 console.error('Authenticator.onMessage: unknown message + origin!?'); 447 console.error('Authenticator.onMessage: unknown message + origin!?');
451 } 448 }
452 } 449 }
453 }; 450 };
454 451
455 Authenticator.getInstance().initialize(); 452 Authenticator.getInstance().initialize();
OLDNEW
« no previous file with comments | « chrome/browser/resources/gaia_auth/background.js ('k') | chrome/browser/resources/gaia_auth/success.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698