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

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

Issue 258123002: Implement a second version of the credentials passing API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comment. Created 6 years, 7 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
11 /** 11 /**
12 * Gaia auth extension url origin. 12 * Gaia auth extension url origin.
13 * @type {string} 13 * @type {string}
14 */ 14 */
15 Authenticator.THIS_EXTENSION_ORIGIN = 15 Authenticator.THIS_EXTENSION_ORIGIN =
16 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik'; 16 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik';
17 17
18 /** 18 /**
19 * The lowest version of the credentials passing API supported.
20 * @type {number}
21 */
22 Authenticator.MIN_API_VERSION_VERSION = 1;
23
24 /**
25 * The highest version of the credentials passing API supported.
26 * @type {number}
27 */
28 Authenticator.MAX_API_VERSION_VERSION = 2;
29
30 /**
31 * The key types supported for credentials passing API 2 and higher.
32 * @type {Array} Array of strings.
33 */
34 Authenticator.API_KEY_TYPES = [
35 'KEY_TYPE_PASSWORD_PLAIN',
Jorge Lucangeli Obes 2014/04/30 22:31:37 Is this equivalent of what we're doing in v1?
bartfab (slow) 2014/05/01 22:47:48 Yes. For now, both v1 and v2 expect the password i
Jorge Lucangeli Obes 2014/05/01 23:00:24 IIUC the password is transmitted in plaintext, but
bartfab (slow) 2014/05/02 06:29:53 The password is sent to two places: 1) The SAML I
36 ];
37
38 /**
19 * Singleton getter of Authenticator. 39 * Singleton getter of Authenticator.
20 * @return {Object} The singleton instance of Authenticator. 40 * @return {Object} The singleton instance of Authenticator.
21 */ 41 */
22 Authenticator.getInstance = function() { 42 Authenticator.getInstance = function() {
23 if (!Authenticator.instance_) { 43 if (!Authenticator.instance_) {
24 Authenticator.instance_ = new Authenticator(); 44 Authenticator.instance_ = new Authenticator();
25 } 45 }
26 return Authenticator.instance_; 46 return Authenticator.instance_;
27 }; 47 };
28 48
29 Authenticator.prototype = { 49 Authenticator.prototype = {
30 email_: null, 50 email_: null,
31 password_: null, 51 passwordBytes_: null,
32 attemptToken_: null, 52 attemptToken_: null,
33 53
34 // Input params from extension initialization URL. 54 // Input params from extension initialization URL.
35 inputLang_: undefined, 55 inputLang_: undefined,
36 intputEmail_: undefined, 56 intputEmail_: undefined,
37 57
38 isSAMLFlow_: false, 58 isSAMLFlow_: false,
39 isSAMLEnabled_: false, 59 isSAMLEnabled_: false,
40 supportChannel_: null, 60 supportChannel_: null,
41 61
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 }, 188 },
169 189
170 /** 190 /**
171 * Invoked when the signin flow is complete. 191 * Invoked when the signin flow is complete.
172 * @param {Object=} opt_extraMsg Optional extra info to send. 192 * @param {Object=} opt_extraMsg Optional extra info to send.
173 */ 193 */
174 completeLogin_: function(opt_extraMsg) { 194 completeLogin_: function(opt_extraMsg) {
175 var msg = { 195 var msg = {
176 'method': 'completeLogin', 196 'method': 'completeLogin',
177 'email': (opt_extraMsg && opt_extraMsg.email) || this.email_, 197 'email': (opt_extraMsg && opt_extraMsg.email) || this.email_,
178 'password': (opt_extraMsg && opt_extraMsg.password) || this.password_, 198 'password': (opt_extraMsg && opt_extraMsg.password) ||
199 this.passwordBytes_,
179 'usingSAML': this.isSAMLFlow_, 200 'usingSAML': this.isSAMLFlow_,
180 'chooseWhatToSync': this.chooseWhatToSync_ || false, 201 'chooseWhatToSync': this.chooseWhatToSync_ || false,
181 'skipForNow': opt_extraMsg && opt_extraMsg.skipForNow, 202 'skipForNow': opt_extraMsg && opt_extraMsg.skipForNow,
182 'sessionIndex': opt_extraMsg && opt_extraMsg.sessionIndex 203 'sessionIndex': opt_extraMsg && opt_extraMsg.sessionIndex
183 }; 204 };
184 window.parent.postMessage(msg, this.parentPage_); 205 window.parent.postMessage(msg, this.parentPage_);
185 if (this.isSAMLEnabled_) 206 if (this.isSAMLEnabled_)
186 this.supportChannel_.send({name: 'resetAuth'}); 207 this.supportChannel_.send({name: 'resetAuth'});
187 }, 208 },
188 209
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 /** 245 /**
225 * Invoked when the background page sends 'onHostedPageLoaded' message. 246 * Invoked when the background page sends 'onHostedPageLoaded' message.
226 * @param {!Object} msg Details sent with the message. 247 * @param {!Object} msg Details sent with the message.
227 */ 248 */
228 onAuthPageLoaded_: function(msg) { 249 onAuthPageLoaded_: function(msg) {
229 var isSAMLPage = msg.url.indexOf(this.gaiaUrl_) != 0; 250 var isSAMLPage = msg.url.indexOf(this.gaiaUrl_) != 0;
230 251
231 if (isSAMLPage && !this.isSAMLFlow_) { 252 if (isSAMLPage && !this.isSAMLFlow_) {
232 // GAIA redirected to a SAML login page. The credentials provided to this 253 // GAIA redirected to a SAML login page. The credentials provided to this
233 // page will determine what user gets logged in. The credentials obtained 254 // page will determine what user gets logged in. The credentials obtained
234 // from the GAIA login from are no longer relevant and can be discarded. 255 // from the GAIA login form are no longer relevant and can be discarded.
235 this.isSAMLFlow_ = true; 256 this.isSAMLFlow_ = true;
236 this.email_ = null; 257 this.email_ = null;
237 this.password_ = null; 258 this.passwordBytes_ = null;
238 } 259 }
239 260
240 window.parent.postMessage({ 261 window.parent.postMessage({
241 'method': 'authPageLoaded', 262 'method': 'authPageLoaded',
242 'isSAML': this.isSAMLFlow_, 263 'isSAML': this.isSAMLFlow_,
243 'domain': extractDomain(msg.url) 264 'domain': extractDomain(msg.url)
244 }, this.parentPage_); 265 }, this.parentPage_);
245 }, 266 },
246 267
247 /** 268 /**
248 * Invoked when the background page sends an 'onInsecureContentBlocked' 269 * Invoked when the background page sends an 'onInsecureContentBlocked'
249 * message. 270 * message.
250 */ 271 */
251 onInsecureContentBlocked_: function() { 272 onInsecureContentBlocked_: function() {
252 window.parent.postMessage({'method': 'insecureContentBlocked'}, 273 window.parent.postMessage({'method': 'insecureContentBlocked'},
253 this.parentPage_); 274 this.parentPage_);
254 }, 275 },
255 276
256 /** 277 /**
257 * Invoked when one of the credential passing API methods is called by a SAML 278 * Invoked when one of the credential passing API methods is called by a SAML
258 * provider. 279 * provider.
259 * @param {!Object} msg Details of the API call. 280 * @param {!Object} msg Details of the API call.
260 */ 281 */
261 onAPICall_: function(msg) { 282 onAPICall_: function(msg) {
262 var call = msg.call; 283 var call = msg.call;
284 if (call.method == 'initialize') {
285 // TODO(bartfab): There was no |requestedVersion| parameter in version 1
286 // of the API. Remove this code once all consumers have switched to
287 // version 2 or higher.
288 if (!call.hasOwnProperty('requestedVersion')) {
289 if (Authenticator.MIN_API_VERSION_VERSION == 1) {
290 this.apiVersion_ = 1;
291 this.initialized_ = true;
292 this.sendInitializationSuccess_();
293 }
294 // The glue code for API version 1 interprets all responses as success.
295 // Instead of reporting failure, do not send any response at all.
296 return;
297 }
298
299 if (!Number.isInteger(call.requestedVersion) ||
300 call.requestedVersion < Authenticator.MIN_API_VERSION_VERSION) {
301 this.sendInitializationFailure_();
302 return;
303 }
304
305 this.apiVersion_ = Math.min(call.requested_version,
306 Authenticator.MAX_API_VERSION_VERSION);
307 this.initialized_ = true;
308 this.sendInitializationSuccess_();
309 return;
310 }
311
263 if (call.method == 'add') { 312 if (call.method == 'add') {
313 if (this.apiVersion_ > 1 &&
314 Authenticator.API_KEY_TYPES.indexOf(call.keyType) == -1) {
315 console.error('Authenticator.onAPICall_: unsupported key type');
316 return;
317 }
264 this.apiToken_ = call.token; 318 this.apiToken_ = call.token;
265 this.email_ = call.user; 319 this.email_ = call.user;
266 this.password_ = call.password; 320 if (this.apiVersion_ == 1)
321 this.passwordBytes_ = call.password;
322 else
323 this.passwordBytes_ = call.passwordBytes;
267 } else if (call.method == 'confirm') { 324 } else if (call.method == 'confirm') {
268 if (call.token != this.apiToken_) 325 if (call.token != this.apiToken_)
269 console.error('Authenticator.onAPICall_: token mismatch'); 326 console.error('Authenticator.onAPICall_: token mismatch');
270 } else { 327 } else {
271 console.error('Authenticator.onAPICall_: unknown message'); 328 console.error('Authenticator.onAPICall_: unknown message');
272 } 329 }
273 }, 330 },
274 331
332 sendInitializationSuccess_: function() {
333 var response = {
334 result: 'initialized',
335 version: this.apiVersion_
336 };
337 if (this.apiVersion_ >= 2)
338 response['keyTypes'] = Authenticator.API_KEY_TYPES;
339
340 this.supportChannel_.send({name: 'apiResponse', response: response});
341 },
342
343 sendInitializationFailure_: function() {
344 this.supportChannel_.send({
345 name: 'apiResponse',
346 response: {result: 'initialization_failed'}
347 });
348 },
349
275 onConfirmLogin_: function() { 350 onConfirmLogin_: function() {
276 if (!this.isSAMLFlow_) { 351 if (!this.isSAMLFlow_) {
277 this.completeLogin_(); 352 this.completeLogin_();
278 return; 353 return;
279 } 354 }
280 355
281 var apiUsed = !!this.password_; 356 var apiUsed = !!this.passwordBytes_;
282 357
283 // Retrieve the e-mail address of the user who just authenticated from GAIA. 358 // Retrieve the e-mail address of the user who just authenticated from GAIA.
284 window.parent.postMessage({method: 'retrieveAuthenticatedUserEmail', 359 window.parent.postMessage({method: 'retrieveAuthenticatedUserEmail',
285 attemptToken: this.attemptToken_, 360 attemptToken: this.attemptToken_,
286 apiUsed: apiUsed}, 361 apiUsed: apiUsed},
287 this.parentPage_); 362 this.parentPage_);
288 363
289 if (!apiUsed) { 364 if (!apiUsed) {
290 this.supportChannel_.sendWithCallback( 365 this.supportChannel_.sendWithCallback(
291 {name: 'getScrapedPasswords'}, 366 {name: 'getScrapedPasswords'},
292 function(passwords) { 367 function(passwords) {
293 if (passwords.length == 0) { 368 if (passwords.length == 0) {
294 window.parent.postMessage( 369 window.parent.postMessage(
295 {method: 'noPassword', email: this.email_}, 370 {method: 'noPassword', email: this.email_},
296 this.parentPage_); 371 this.parentPage_);
297 } else { 372 } else {
298 window.parent.postMessage({method: 'confirmPassword', 373 window.parent.postMessage({method: 'confirmPassword',
299 email: this.email_, 374 email: this.email_,
300 passwordCount: passwords.length}, 375 passwordCount: passwords.length},
301 this.parentPage_); 376 this.parentPage_);
302 } 377 }
303 }.bind(this)); 378 }.bind(this));
304 } 379 }
305 }, 380 },
306 381
307 maybeCompleteSAMLLogin_: function() { 382 maybeCompleteSAMLLogin_: function() {
308 // SAML login is complete when the user's e-mail address has been retrieved 383 // SAML login is complete when the user's e-mail address has been retrieved
309 // from GAIA and the user has successfully confirmed the password. 384 // from GAIA and the user has successfully confirmed the password.
310 if (this.email_ !== null && this.password_ !== null) 385 if (this.email_ !== null && this.passwordBytes_ !== null)
311 this.completeLogin_(); 386 this.completeLogin_();
312 }, 387 },
313 388
314 onVerifyConfirmedPassword_: function(password) { 389 onVerifyConfirmedPassword_: function(password) {
315 this.supportChannel_.sendWithCallback( 390 this.supportChannel_.sendWithCallback(
316 {name: 'getScrapedPasswords'}, 391 {name: 'getScrapedPasswords'},
317 function(passwords) { 392 function(passwords) {
318 for (var i = 0; i < passwords.length; ++i) { 393 for (var i = 0; i < passwords.length; ++i) {
319 if (passwords[i] == password) { 394 if (passwords[i] == password) {
320 this.password_ = passwords[i]; 395 this.passwordBytes_ = passwords[i];
321 this.maybeCompleteSAMLLogin_(); 396 this.maybeCompleteSAMLLogin_();
322 return; 397 return;
323 } 398 }
324 } 399 }
325 window.parent.postMessage( 400 window.parent.postMessage(
326 {method: 'confirmPassword', email: this.email_}, 401 {method: 'confirmPassword', email: this.email_},
327 this.parentPage_); 402 this.parentPage_);
328 }.bind(this)); 403 }.bind(this));
329 }, 404 },
330 405
331 onMessage: function(e) { 406 onMessage: function(e) {
332 var msg = e.data; 407 var msg = e.data;
333 if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) { 408 if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) {
334 this.email_ = msg.email; 409 this.email_ = msg.email;
335 this.password_ = msg.password; 410 this.passwordBytes_ = msg.password;
336 this.attemptToken_ = msg.attemptToken; 411 this.attemptToken_ = msg.attemptToken;
337 this.chooseWhatToSync_ = msg.chooseWhatToSync; 412 this.chooseWhatToSync_ = msg.chooseWhatToSync;
338 this.isSAMLFlow_ = false; 413 this.isSAMLFlow_ = false;
339 if (this.isSAMLEnabled_) 414 if (this.isSAMLEnabled_)
340 this.supportChannel_.send({name: 'startAuth'}); 415 this.supportChannel_.send({name: 'startAuth'});
341 } else if (msg.method == 'clearOldAttempts' && this.isGaiaMessage_(e)) { 416 } else if (msg.method == 'clearOldAttempts' && this.isGaiaMessage_(e)) {
342 this.email_ = null; 417 this.email_ = null;
343 this.password_ = null; 418 this.passwordBytes_ = null;
344 this.attemptToken_ = null; 419 this.attemptToken_ = null;
345 this.isSAMLFlow_ = false; 420 this.isSAMLFlow_ = false;
346 this.onLoginUILoaded_(); 421 this.onLoginUILoaded_();
347 if (this.isSAMLEnabled_) 422 if (this.isSAMLEnabled_)
348 this.supportChannel_.send({name: 'resetAuth'}); 423 this.supportChannel_.send({name: 'resetAuth'});
349 } else if (msg.method == 'setAuthenticatedUserEmail' && 424 } else if (msg.method == 'setAuthenticatedUserEmail' &&
350 this.isParentMessage_(e)) { 425 this.isParentMessage_(e)) {
351 if (this.attemptToken_ == msg.attemptToken) { 426 if (this.attemptToken_ == msg.attemptToken) {
352 this.email_ = msg.email; 427 this.email_ = msg.email;
353 this.maybeCompleteSAMLLogin_(); 428 this.maybeCompleteSAMLLogin_();
354 } 429 }
355 } else if (msg.method == 'confirmLogin' && this.isInternalMessage_(e)) { 430 } else if (msg.method == 'confirmLogin' && this.isInternalMessage_(e)) {
356 if (this.attemptToken_ == msg.attemptToken) 431 if (this.attemptToken_ == msg.attemptToken)
357 this.onConfirmLogin_(); 432 this.onConfirmLogin_();
358 else 433 else
359 console.error('Authenticator.onMessage: unexpected attemptToken!?'); 434 console.error('Authenticator.onMessage: unexpected attemptToken!?');
360 } else if (msg.method == 'verifyConfirmedPassword' && 435 } else if (msg.method == 'verifyConfirmedPassword' &&
361 this.isParentMessage_(e)) { 436 this.isParentMessage_(e)) {
362 this.onVerifyConfirmedPassword_(msg.password); 437 this.onVerifyConfirmedPassword_(msg.password);
363 } else if (msg.method == 'redirectToSignin' && 438 } else if (msg.method == 'redirectToSignin' &&
364 this.isParentMessage_(e)) { 439 this.isParentMessage_(e)) {
365 $('gaia-frame').src = this.constructInitialFrameUrl_(); 440 $('gaia-frame').src = this.constructInitialFrameUrl_();
366 } else { 441 } else {
367 console.error('Authenticator.onMessage: unknown message + origin!?'); 442 console.error('Authenticator.onMessage: unknown message + origin!?');
368 } 443 }
369 } 444 }
370 }; 445 };
371 446
372 Authenticator.getInstance().initialize(); 447 Authenticator.getInstance().initialize();
OLDNEW
« no previous file with comments | « chrome/browser/resources/gaia_auth/background.js ('k') | chrome/browser/resources/gaia_auth/saml_injected.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698