| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 * @fileoverview | 6 * @fileoverview |
| 7 * A background script of the auth extension that bridges the communication | 7 * A background script of the auth extension that bridges the communication |
| 8 * between the main and injected scripts. | 8 * between the main and injected scripts. |
| 9 * | 9 * |
| 10 * Here is an overview of the communication flow when SAML is being used: | 10 * Here is an overview of the communication flow when SAML is being used: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 /** | 26 /** |
| 27 * BackgroundBridgeManager maintains an array of BackgroundBridge, indexed by | 27 * BackgroundBridgeManager maintains an array of BackgroundBridge, indexed by |
| 28 * the associated tab id. | 28 * the associated tab id. |
| 29 */ | 29 */ |
| 30 function BackgroundBridgeManager() { | 30 function BackgroundBridgeManager() { |
| 31 } | 31 } |
| 32 | 32 |
| 33 BackgroundBridgeManager.prototype = { | 33 BackgroundBridgeManager.prototype = { |
| 34 CONTINUE_URL_BASE: 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik' + |
| 35 '/success.html', |
| 34 // Maps a tab id to its associated BackgroundBridge. | 36 // Maps a tab id to its associated BackgroundBridge. |
| 35 bridges_: {}, | 37 bridges_: {}, |
| 36 | 38 |
| 37 run: function() { | 39 run: function() { |
| 38 chrome.runtime.onConnect.addListener(this.onConnect_.bind(this)); | 40 chrome.runtime.onConnect.addListener(this.onConnect_.bind(this)); |
| 39 | 41 |
| 40 chrome.webRequest.onBeforeRequest.addListener( | 42 chrome.webRequest.onBeforeRequest.addListener( |
| 41 function(details) { | 43 function(details) { |
| 42 if (this.bridges_[details.tabId]) | 44 if (this.bridges_[details.tabId]) |
| 43 return this.bridges_[details.tabId].onInsecureRequest(details.url); | 45 return this.bridges_[details.tabId].onInsecureRequest(details.url); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 61 this.bridges_[details.tabId].onHeadersReceived(details); | 63 this.bridges_[details.tabId].onHeadersReceived(details); |
| 62 }.bind(this), | 64 }.bind(this), |
| 63 {urls: ['*://*/*'], types: ['sub_frame']}, | 65 {urls: ['*://*/*'], types: ['sub_frame']}, |
| 64 ['responseHeaders']); | 66 ['responseHeaders']); |
| 65 | 67 |
| 66 chrome.webRequest.onCompleted.addListener( | 68 chrome.webRequest.onCompleted.addListener( |
| 67 function(details) { | 69 function(details) { |
| 68 if (this.bridges_[details.tabId]) | 70 if (this.bridges_[details.tabId]) |
| 69 this.bridges_[details.tabId].onCompleted(details); | 71 this.bridges_[details.tabId].onCompleted(details); |
| 70 }.bind(this), | 72 }.bind(this), |
| 71 {urls: ['*://*/*'], types: ['sub_frame']}, | 73 {urls: ['*://*/*', this.CONTINUE_URL_BASE + '*'], types: ['sub_frame']}, |
| 72 ['responseHeaders']); | 74 ['responseHeaders']); |
| 73 }, | 75 }, |
| 74 | 76 |
| 75 onConnect_: function(port) { | 77 onConnect_: function(port) { |
| 76 var tabId = this.getTabIdFromPort_(port); | 78 var tabId = this.getTabIdFromPort_(port); |
| 77 if (!this.bridges_[tabId]) | 79 if (!this.bridges_[tabId]) |
| 78 this.bridges_[tabId] = new BackgroundBridge(tabId); | 80 this.bridges_[tabId] = new BackgroundBridge(tabId); |
| 79 if (port.name == 'authMain') { | 81 if (port.name == 'authMain') { |
| 80 this.bridges_[tabId].setupForAuthMain(port); | 82 this.bridges_[tabId].setupForAuthMain(port); |
| 81 port.onDisconnect.addListener(function() { | 83 port.onDisconnect.addListener(function() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 102 function BackgroundBridge(tabId) { | 104 function BackgroundBridge(tabId) { |
| 103 this.tabId_ = tabId; | 105 this.tabId_ = tabId; |
| 104 } | 106 } |
| 105 | 107 |
| 106 BackgroundBridge.prototype = { | 108 BackgroundBridge.prototype = { |
| 107 // The associated tab ID. Only used for debugging now. | 109 // The associated tab ID. Only used for debugging now. |
| 108 tabId: null, | 110 tabId: null, |
| 109 | 111 |
| 110 isDesktopFlow_: false, | 112 isDesktopFlow_: false, |
| 111 | 113 |
| 112 // Continue URL that is set from main auth script. | |
| 113 continueUrl_: null, | |
| 114 | |
| 115 // Whether the extension is loaded in a constrained window. | 114 // Whether the extension is loaded in a constrained window. |
| 116 // Set from main auth script. | 115 // Set from main auth script. |
| 117 isConstrainedWindow_: null, | 116 isConstrainedWindow_: null, |
| 118 | 117 |
| 119 // Email of the newly authenticated user based on the gaia response header | 118 // Email of the newly authenticated user based on the gaia response header |
| 120 // 'google-accounts-signin'. | 119 // 'google-accounts-signin'. |
| 121 email_: null, | 120 email_: null, |
| 122 | 121 |
| 123 // Session index of the newly authenticated user based on the gaia response | 122 // Session index of the newly authenticated user based on the gaia response |
| 124 // header 'google-accounts-signin'. | 123 // header 'google-accounts-signin'. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 'pageLoaded', this.onPageLoaded_.bind(this)); | 185 'pageLoaded', this.onPageLoaded_.bind(this)); |
| 187 }, | 186 }, |
| 188 | 187 |
| 189 /** | 188 /** |
| 190 * Handler for 'initDesktopFlow' signal sent from the main script. | 189 * Handler for 'initDesktopFlow' signal sent from the main script. |
| 191 * Only called in desktop mode. | 190 * Only called in desktop mode. |
| 192 */ | 191 */ |
| 193 onInitDesktopFlow_: function(msg) { | 192 onInitDesktopFlow_: function(msg) { |
| 194 this.isDesktopFlow_ = true; | 193 this.isDesktopFlow_ = true; |
| 195 this.gaiaUrl_ = msg.gaiaUrl; | 194 this.gaiaUrl_ = msg.gaiaUrl; |
| 196 this.continueUrl_ = msg.continueUrl; | |
| 197 this.isConstrainedWindow_ = msg.isConstrainedWindow; | 195 this.isConstrainedWindow_ = msg.isConstrainedWindow; |
| 198 }, | 196 }, |
| 199 | 197 |
| 200 /** | 198 /** |
| 201 * Handler for webRequest.onCompleted. It 1) detects loading of continue URL | 199 * Handler for webRequest.onCompleted. It 1) detects loading of continue URL |
| 202 * and notifies the main script of signin completion; 2) detects if the | 200 * and notifies the main script of signin completion; 2) detects if the |
| 203 * current page could be loaded in a constrained window and signals the main | 201 * current page could be loaded in a constrained window and signals the main |
| 204 * script of switching to full tab if necessary. | 202 * script of switching to full tab if necessary. |
| 205 */ | 203 */ |
| 206 onCompleted: function(details) { | 204 onCompleted: function(details) { |
| 207 // Only monitors requests in the gaia frame whose parent frame ID must be | 205 // Only monitors requests in the gaia frame whose parent frame ID must be |
| 208 // positive. | 206 // positive. |
| 209 if (!this.isDesktopFlow_ || details.parentFrameId <= 0) | 207 if (!this.isDesktopFlow_ || details.parentFrameId <= 0) |
| 210 return; | 208 return; |
| 211 | 209 |
| 212 var msg = null; | 210 if (details.url.lastIndexOf(backgroundBridgeManager.CONTINUE_URL_BASE, 0) == |
| 213 if (this.continueUrl_ && | 211 0) { |
| 214 details.url.lastIndexOf(this.continueUrl_, 0) == 0) { | |
| 215 var skipForNow = false; | 212 var skipForNow = false; |
| 216 if (details.url.indexOf('ntp=1') >= 0) | 213 if (details.url.indexOf('ntp=1') >= 0) |
| 217 skipForNow = true; | 214 skipForNow = true; |
| 218 | 215 |
| 219 // TOOD(guohui): Show password confirmation UI. | 216 // TOOD(guohui): Show password confirmation UI. |
| 220 var passwords = this.onGetScrapedPasswords_(); | 217 var passwords = this.onGetScrapedPasswords_(); |
| 221 msg = { | 218 var msg = { |
| 222 'name': 'completeLogin', | 219 'name': 'completeLogin', |
| 223 'email': this.email_, | 220 'email': this.email_, |
| 224 'password': passwords[0], | 221 'password': passwords[0], |
| 225 'sessionIndex': this.sessionIndex_, | 222 'sessionIndex': this.sessionIndex_, |
| 226 'skipForNow': skipForNow | 223 'skipForNow': skipForNow |
| 227 }; | 224 }; |
| 228 this.channelMain_.send(msg); | 225 this.channelMain_.send(msg); |
| 229 } else if (this.isConstrainedWindow_) { | 226 } else if (this.isConstrainedWindow_) { |
| 230 // The header google-accounts-embedded is only set on gaia domain. | 227 // The header google-accounts-embedded is only set on gaia domain. |
| 231 if (this.gaiaUrl_ && details.url.lastIndexOf(this.gaiaUrl_) == 0) { | 228 if (this.gaiaUrl_ && details.url.lastIndexOf(this.gaiaUrl_) == 0) { |
| 232 var headers = details.responseHeaders; | 229 var headers = details.responseHeaders; |
| 233 for (var i = 0; headers && i < headers.length; ++i) { | 230 for (var i = 0; headers && i < headers.length; ++i) { |
| 234 if (headers[i].name.toLowerCase() == 'google-accounts-embedded') | 231 if (headers[i].name.toLowerCase() == 'google-accounts-embedded') |
| 235 return; | 232 return; |
| 236 } | 233 } |
| 237 } | 234 } |
| 238 msg = { | 235 var msg = { |
| 239 'name': 'switchToFullTab', | 236 'name': 'switchToFullTab', |
| 240 'url': details.url | 237 'url': details.url |
| 241 }; | 238 }; |
| 242 this.channelMain_.send(msg); | 239 this.channelMain_.send(msg); |
| 243 } | 240 } |
| 244 }, | 241 }, |
| 245 | 242 |
| 246 /** | 243 /** |
| 247 * Handler for webRequest.onBeforeRequest, invoked when content served over an | 244 * Handler for webRequest.onBeforeRequest, invoked when content served over an |
| 248 * unencrypted connection is detected. Determines whether the request should | 245 * unencrypted connection is detected. Determines whether the request should |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 }, | 361 }, |
| 365 | 362 |
| 366 onPageLoaded_: function(msg) { | 363 onPageLoaded_: function(msg) { |
| 367 if (this.channelMain_) | 364 if (this.channelMain_) |
| 368 this.channelMain_.send({name: 'onAuthPageLoaded', url: msg.url}); | 365 this.channelMain_.send({name: 'onAuthPageLoaded', url: msg.url}); |
| 369 } | 366 } |
| 370 }; | 367 }; |
| 371 | 368 |
| 372 var backgroundBridgeManager = new BackgroundBridgeManager(); | 369 var backgroundBridgeManager = new BackgroundBridgeManager(); |
| 373 backgroundBridgeManager.run(); | 370 backgroundBridgeManager.run(); |
| OLD | NEW |