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

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

Issue 2600683002: Run tools/clang-format-js on some of chrome/browser/resources/ (Closed)
Patch Set: event_handler.js Created 4 years 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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="post_message_channel.js"> 5 // <include src="post_message_channel.js">
6 6
7 /** 7 /**
8 * @fileoverview Saml support for webview based auth. 8 * @fileoverview Saml support for webview based auth.
9 */ 9 */
10 10
11 cr.define('cr.login', function() { 11 cr.define('cr.login', function() {
12 'use strict'; 12 'use strict';
13 13
14 /** 14 /**
15 * The lowest version of the credentials passing API supported. 15 * The lowest version of the credentials passing API supported.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 136
137 /* 137 /*
138 * Whether to abort the authentication flow and show an error messagen when 138 * Whether to abort the authentication flow and show an error messagen when
139 * content served over an unencrypted connection is detected. 139 * content served over an unencrypted connection is detected.
140 * @type {boolean} 140 * @type {boolean}
141 */ 141 */
142 this.blockInsecureContent = false; 142 this.blockInsecureContent = false;
143 143
144 this.webview_.addEventListener( 144 this.webview_.addEventListener(
145 'contentload', this.onContentLoad_.bind(this)); 145 'contentload', this.onContentLoad_.bind(this));
146 this.webview_.addEventListener( 146 this.webview_.addEventListener('loadabort', this.onLoadAbort_.bind(this));
147 'loadabort', this.onLoadAbort_.bind(this)); 147 this.webview_.addEventListener('loadcommit', this.onLoadCommit_.bind(this));
148 this.webview_.addEventListener(
149 'loadcommit', this.onLoadCommit_.bind(this));
150 this.webview_.addEventListener( 148 this.webview_.addEventListener(
151 'permissionrequest', this.onPermissionRequest_.bind(this)); 149 'permissionrequest', this.onPermissionRequest_.bind(this));
152 150
153 this.webview_.request.onBeforeRequest.addListener( 151 this.webview_.request.onBeforeRequest.addListener(
154 this.onInsecureRequest.bind(this), 152 this.onInsecureRequest.bind(this),
155 {urls: ['http://*/*', 'file://*/*', 'ftp://*/*']}, 153 {urls: ['http://*/*', 'file://*/*', 'ftp://*/*']}, ['blocking']);
156 ['blocking']);
157 this.webview_.request.onHeadersReceived.addListener( 154 this.webview_.request.onHeadersReceived.addListener(
158 this.onHeadersReceived_.bind(this), 155 this.onHeadersReceived_.bind(this),
159 {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, 156 {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']},
160 ['blocking', 'responseHeaders']); 157 ['blocking', 'responseHeaders']);
161 158
162 this.webview_.addContentScripts([{ 159 this.webview_.addContentScripts([{
163 name: 'samlInjected', 160 name: 'samlInjected',
164 matches: ['http://*/*', 'https://*/*'], 161 matches: ['http://*/*', 'https://*/*'],
165 js: { 162 js: {code: injectedJs},
166 code: injectedJs
167 },
168 all_frames: true, 163 all_frames: true,
169 run_at: 'document_start' 164 run_at: 'document_start'
170 }]); 165 }]);
171 166
172 PostMessageChannel.runAsDaemon(this.onConnected_.bind(this)); 167 PostMessageChannel.runAsDaemon(this.onConnected_.bind(this));
173 } 168 }
174 169
175 SamlHandler.prototype = { 170 SamlHandler.prototype = {
176 __proto__: cr.EventTarget.prototype, 171 __proto__: cr.EventTarget.prototype,
177 172
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 * an unencrypted connection is detected. Determines whether the request 278 * an unencrypted connection is detected. Determines whether the request
284 * should be blocked and if so, signals that an error message needs to be 279 * should be blocked and if so, signals that an error message needs to be
285 * shown. 280 * shown.
286 * @param {Object} details 281 * @param {Object} details
287 * @return {!Object} Decision whether to block the request. 282 * @return {!Object} Decision whether to block the request.
288 */ 283 */
289 onInsecureRequest: function(details) { 284 onInsecureRequest: function(details) {
290 if (!this.blockInsecureContent) 285 if (!this.blockInsecureContent)
291 return {}; 286 return {};
292 var strippedUrl = stripParams(details.url); 287 var strippedUrl = stripParams(details.url);
293 this.dispatchEvent(new CustomEvent('insecureContentBlocked', 288 this.dispatchEvent(new CustomEvent(
294 {detail: {url: strippedUrl}})); 289 'insecureContentBlocked', {detail: {url: strippedUrl}}));
295 return {cancel: true}; 290 return {cancel: true};
296 }, 291 },
297 292
298 /** 293 /**
299 * Invoked when headers are received for the main frame. 294 * Invoked when headers are received for the main frame.
300 * @private 295 * @private
301 */ 296 */
302 onHeadersReceived_: function(details) { 297 onHeadersReceived_: function(details) {
303 var headers = details.responseHeaders; 298 var headers = details.responseHeaders;
304 299
305 // Check whether GAIA headers indicating the start or end of a SAML 300 // Check whether GAIA headers indicating the start or end of a SAML
306 // redirect are present. If so, synthesize cookies to mark these points. 301 // redirect are present. If so, synthesize cookies to mark these points.
307 for (var i = 0; headers && i < headers.length; ++i) { 302 for (var i = 0; headers && i < headers.length; ++i) {
308 var header = headers[i]; 303 var header = headers[i];
309 var headerName = header.name.toLowerCase(); 304 var headerName = header.name.toLowerCase();
310 305
311 if (headerName == SAML_HEADER) { 306 if (headerName == SAML_HEADER) {
312 var action = header.value.toLowerCase(); 307 var action = header.value.toLowerCase();
313 if (action == 'start') { 308 if (action == 'start') {
314 this.pendingIsSamlPage_ = true; 309 this.pendingIsSamlPage_ = true;
315 310
316 // GAIA is redirecting to a SAML IdP. Any cookies contained in the 311 // GAIA is redirecting to a SAML IdP. Any cookies contained in the
317 // current |headers| were set by GAIA. Any cookies set in future 312 // current |headers| were set by GAIA. Any cookies set in future
318 // requests will be coming from the IdP. Append a cookie to the 313 // requests will be coming from the IdP. Append a cookie to the
319 // current |headers| that marks the point at which the redirect 314 // current |headers| that marks the point at which the redirect
320 // occurred. 315 // occurred.
321 headers.push({name: 'Set-Cookie', 316 headers.push(
322 value: 'google-accounts-saml-start=now'}); 317 {name: 'Set-Cookie', value: 'google-accounts-saml-start=now'});
323 return {responseHeaders: headers}; 318 return {responseHeaders: headers};
324 } else if (action == 'end') { 319 } else if (action == 'end') {
325 this.pendingIsSamlPage_ = false; 320 this.pendingIsSamlPage_ = false;
326 321
327 // The SAML IdP has redirected back to GAIA. Add a cookie that marks 322 // The SAML IdP has redirected back to GAIA. Add a cookie that marks
328 // the point at which the redirect occurred occurred. It is 323 // the point at which the redirect occurred occurred. It is
329 // important that this cookie be prepended to the current |headers| 324 // important that this cookie be prepended to the current |headers|
330 // because any cookies contained in the |headers| were already set 325 // because any cookies contained in the |headers| were already set
331 // by GAIA, not the IdP. Due to limitations in the webRequest API, 326 // by GAIA, not the IdP. Due to limitations in the webRequest API,
332 // it is not trivial to prepend a cookie: 327 // it is not trivial to prepend a cookie:
333 // 328 //
334 // The webRequest API only allows for deleting and appending 329 // The webRequest API only allows for deleting and appending
335 // headers. To prepend a cookie (C), three steps are needed: 330 // headers. To prepend a cookie (C), three steps are needed:
336 // 1) Delete any headers that set cookies (e.g., A, B). 331 // 1) Delete any headers that set cookies (e.g., A, B).
337 // 2) Append a header which sets the cookie (C). 332 // 2) Append a header which sets the cookie (C).
338 // 3) Append the original headers (A, B). 333 // 3) Append the original headers (A, B).
339 // 334 //
340 // Due to a further limitation of the webRequest API, it is not 335 // Due to a further limitation of the webRequest API, it is not
341 // possible to delete a header in step 1) and append an identical 336 // possible to delete a header in step 1) and append an identical
342 // header in step 3). To work around this, a trailing semicolon is 337 // header in step 3). To work around this, a trailing semicolon is
343 // added to each header before appending it. Trailing semicolons are 338 // added to each header before appending it. Trailing semicolons are
344 // ignored by Chrome in cookie headers, causing the modified headers 339 // ignored by Chrome in cookie headers, causing the modified headers
345 // to actually set the original cookies. 340 // to actually set the original cookies.
346 var otherHeaders = []; 341 var otherHeaders = [];
347 var cookies = [{name: 'Set-Cookie', 342 var cookies =
348 value: 'google-accounts-saml-end=now'}]; 343 [{name: 'Set-Cookie', value: 'google-accounts-saml-end=now'}];
349 for (var j = 0; j < headers.length; ++j) { 344 for (var j = 0; j < headers.length; ++j) {
350 if (headers[j].name.toLowerCase().startsWith('set-cookie')) { 345 if (headers[j].name.toLowerCase().startsWith('set-cookie')) {
351 var header = headers[j]; 346 var header = headers[j];
352 header.value += ';'; 347 header.value += ';';
353 cookies.push(header); 348 cookies.push(header);
354 } else { 349 } else {
355 otherHeaders.push(headers[j]); 350 otherHeaders.push(headers[j]);
356 } 351 }
357 } 352 }
358 return {responseHeaders: otherHeaders.concat(cookies)}; 353 return {responseHeaders: otherHeaders.concat(cookies)};
359 } 354 }
360 } 355 }
361 } 356 }
362 357
363 return {}; 358 return {};
364 }, 359 },
365 360
366 /** 361 /**
367 * Invoked when the injected JS makes a connection. 362 * Invoked when the injected JS makes a connection.
368 */ 363 */
369 onConnected_: function(port) { 364 onConnected_: function(port) {
370 if (port.targetWindow != this.webview_.contentWindow) 365 if (port.targetWindow != this.webview_.contentWindow)
371 return; 366 return;
372 367
373 var channel = Channel.create(); 368 var channel = Channel.create();
374 channel.init(port); 369 channel.init(port);
375 370
376 channel.registerMessage( 371 channel.registerMessage('apiCall', this.onAPICall_.bind(this, channel));
377 'apiCall', this.onAPICall_.bind(this, channel));
378 channel.registerMessage( 372 channel.registerMessage(
379 'updatePassword', this.onUpdatePassword_.bind(this, channel)); 373 'updatePassword', this.onUpdatePassword_.bind(this, channel));
380 channel.registerMessage( 374 channel.registerMessage(
381 'pageLoaded', this.onPageLoaded_.bind(this, channel)); 375 'pageLoaded', this.onPageLoaded_.bind(this, channel));
382 channel.registerMessage( 376 channel.registerMessage(
383 'getSAMLFlag', this.onGetSAMLFlag_.bind(this, channel)); 377 'getSAMLFlag', this.onGetSAMLFlag_.bind(this, channel));
384 }, 378 },
385 379
386 sendInitializationSuccess_: function(channel) { 380 sendInitializationSuccess_: function(channel) {
387 channel.send({name: 'apiResponse', response: { 381 channel.send({
388 result: 'initialized', 382 name: 'apiResponse',
389 version: this.apiVersion_, 383 response: {
390 keyTypes: API_KEY_TYPES 384 result: 'initialized',
391 }}); 385 version: this.apiVersion_,
386 keyTypes: API_KEY_TYPES
387 }
388 });
392 }, 389 },
393 390
394 sendInitializationFailure_: function(channel) { 391 sendInitializationFailure_: function(channel) {
395 channel.send({ 392 channel.send(
396 name: 'apiResponse', 393 {name: 'apiResponse', response: {result: 'initialization_failed'}});
397 response: {result: 'initialization_failed'}
398 });
399 }, 394 },
400 395
401 /** 396 /**
402 * Handlers for channel messages. 397 * Handlers for channel messages.
403 * @param {Channel} channel A channel to send back response. 398 * @param {Channel} channel A channel to send back response.
404 * @param {Object} msg Received message. 399 * @param {Object} msg Received message.
405 * @private 400 * @private
406 */ 401 */
407 onAPICall_: function(channel, msg) { 402 onAPICall_: function(channel, msg) {
408 var call = msg.call; 403 var call = msg.call;
409 if (call.method == 'initialize') { 404 if (call.method == 'initialize') {
410 if (!Number.isInteger(call.requestedVersion) || 405 if (!Number.isInteger(call.requestedVersion) ||
411 call.requestedVersion < MIN_API_VERSION_VERSION) { 406 call.requestedVersion < MIN_API_VERSION_VERSION) {
412 this.sendInitializationFailure_(channel); 407 this.sendInitializationFailure_(channel);
413 return; 408 return;
414 } 409 }
415 410
416 this.apiVersion_ = Math.min(call.requestedVersion, 411 this.apiVersion_ =
417 MAX_API_VERSION_VERSION); 412 Math.min(call.requestedVersion, MAX_API_VERSION_VERSION);
418 this.apiInitialized_ = true; 413 this.apiInitialized_ = true;
419 this.sendInitializationSuccess_(channel); 414 this.sendInitializationSuccess_(channel);
420 return; 415 return;
421 } 416 }
422 417
423 if (call.method == 'add') { 418 if (call.method == 'add') {
424 if (API_KEY_TYPES.indexOf(call.keyType) == -1) { 419 if (API_KEY_TYPES.indexOf(call.keyType) == -1) {
425 console.error('SamlHandler.onAPICall_: unsupported key type'); 420 console.error('SamlHandler.onAPICall_: unsupported key type');
426 return; 421 return;
427 } 422 }
(...skipping 11 matching lines...) Expand all
439 } 434 }
440 }, 435 },
441 436
442 onUpdatePassword_: function(channel, msg) { 437 onUpdatePassword_: function(channel, msg) {
443 if (this.isSamlPage_) 438 if (this.isSamlPage_)
444 this.passwordStore_[msg.id] = msg.password; 439 this.passwordStore_[msg.id] = msg.password;
445 }, 440 },
446 441
447 onPageLoaded_: function(channel, msg) { 442 onPageLoaded_: function(channel, msg) {
448 this.authDomain = extractDomain(msg.url); 443 this.authDomain = extractDomain(msg.url);
449 this.dispatchEvent(new CustomEvent( 444 this.dispatchEvent(new CustomEvent('authPageLoaded', {
450 'authPageLoaded', 445 detail: {
451 {detail: {url: url, 446 url: url,
452 isSAMLPage: this.isSamlPage_, 447 isSAMLPage: this.isSamlPage_,
453 domain: this.authDomain}})); 448 domain: this.authDomain
449 }
450 }));
454 }, 451 },
455 452
456 onPermissionRequest_: function(permissionEvent) { 453 onPermissionRequest_: function(permissionEvent) {
457 if (permissionEvent.permission === 'media') { 454 if (permissionEvent.permission === 'media') {
458 // The actual permission check happens in 455 // The actual permission check happens in
459 // WebUILoginView::RequestMediaAccessPermission(). 456 // WebUILoginView::RequestMediaAccessPermission().
460 this.dispatchEvent(new CustomEvent('videoEnabled')); 457 this.dispatchEvent(new CustomEvent('videoEnabled'));
461 permissionEvent.request.allow(); 458 permissionEvent.request.allow();
462 } 459 }
463 }, 460 },
464 461
465 onGetSAMLFlag_: function(channel, msg) { 462 onGetSAMLFlag_: function(channel, msg) {
466 return this.isSamlPage_; 463 return this.isSamlPage_;
467 }, 464 },
468 }; 465 };
469 466
470 return { 467 return {SamlHandler: SamlHandler};
471 SamlHandler: SamlHandler
472 };
473 }); 468 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698