Commit cf73af4a authored by John Abd-El-Malek's avatar John Abd-El-Malek Committed by Commit Bot

Send GAPS cookie during reauthentication when the network service is enabled.

Similar to the Set-Cookie case in r600570, Cookie headers can't be read/written
by webRequest handlers when the network service is enabled. Instead of sending
the GAPS cookie from C++ to JS which then sets it in the webRequest callback,
have the C++ code directly write it to the temporary storage partition for login
using CookieManager interface.

Bug: 887061
Change-Id: I50acfb324e830f42d6a0d53ed32aa63e48aaab3a
Reviewed-on: https://chromium-review.googlesource.com/c/1289960
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601151}
parent 37c66216
...@@ -28,8 +28,6 @@ cr.define('cr.login', function() { ...@@ -28,8 +28,6 @@ cr.define('cr.login', function() {
var SIGN_IN_HEADER = 'google-accounts-signin'; var SIGN_IN_HEADER = 'google-accounts-signin';
var EMBEDDED_FORM_HEADER = 'google-accounts-embedded'; var EMBEDDED_FORM_HEADER = 'google-accounts-embedded';
var LOCATION_HEADER = 'location'; var LOCATION_HEADER = 'location';
var COOKIE_HEADER = 'cookie';
var GAPS_COOKIE = 'GAPS';
var SERVICE_ID = 'chromeoslogin'; var SERVICE_ID = 'chromeoslogin';
var EMBEDDED_SETUP_CHROMEOS_ENDPOINT = 'embedded/setup/chromeos'; var EMBEDDED_SETUP_CHROMEOS_ENDPOINT = 'embedded/setup/chromeos';
var EMBEDDED_SETUP_CHROMEOS_ENDPOINT_V2 = 'embedded/setup/v2/chromeos'; var EMBEDDED_SETUP_CHROMEOS_ENDPOINT_V2 = 'embedded/setup/v2/chromeos';
...@@ -86,7 +84,6 @@ cr.define('cr.login', function() { ...@@ -86,7 +84,6 @@ cr.define('cr.login', function() {
'platformVersion', // Version of the OS build. 'platformVersion', // Version of the OS build.
'releaseChannel', // Installation channel. 'releaseChannel', // Installation channel.
'endpointGen', // Current endpoint generation. 'endpointGen', // Current endpoint generation.
'gapsCookie', // GAPS cookie
'chromeOSApiVersion', // GAIA Chrome OS API version 'chromeOSApiVersion', // GAIA Chrome OS API version
'menuGuestMode', // Enables "Guest mode" menu item 'menuGuestMode', // Enables "Guest mode" menu item
'menuKeyboardOptions', // Enables "Keyboard options" menu item 'menuKeyboardOptions', // Enables "Keyboard options" menu item
...@@ -138,8 +135,6 @@ cr.define('cr.login', function() { ...@@ -138,8 +135,6 @@ cr.define('cr.login', function() {
this.initialFrameUrl_ = null; this.initialFrameUrl_ = null;
this.reloadUrl_ = null; this.reloadUrl_ = null;
this.trusted_ = true; this.trusted_ = true;
this.gapsCookie_ = null;
this.gapsCookieSent_ = false;
this.readyFired_ = false; this.readyFired_ = false;
this.webviewEventManager_ = WebviewEventManager.create(); this.webviewEventManager_ = WebviewEventManager.create();
...@@ -187,8 +182,6 @@ cr.define('cr.login', function() { ...@@ -187,8 +182,6 @@ cr.define('cr.login', function() {
this.email_ = null; this.email_ = null;
this.gaiaId_ = null; this.gaiaId_ = null;
this.password_ = null; this.password_ = null;
this.gapsCookie_ = null;
this.gapsCookieSent_ = false;
this.readyFired_ = false; this.readyFired_ = false;
this.chooseWhatToSync_ = false; this.chooseWhatToSync_ = false;
this.skipForNow_ = false; this.skipForNow_ = false;
...@@ -251,7 +244,6 @@ cr.define('cr.login', function() { ...@@ -251,7 +244,6 @@ cr.define('cr.login', function() {
this.onHeadersReceived_.bind(this), this.onHeadersReceived_.bind(this),
{urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']},
['responseHeaders']); ['responseHeaders']);
this.onBeforeSetHeadersSet_ = false;
}; };
/** /**
...@@ -295,8 +287,6 @@ cr.define('cr.login', function() { ...@@ -295,8 +287,6 @@ cr.define('cr.login', function() {
this.isConstrainedWindow_ = data.constrained == '1'; this.isConstrainedWindow_ = data.constrained == '1';
this.isNewGaiaFlow = data.isNewGaiaFlow; this.isNewGaiaFlow = data.isNewGaiaFlow;
this.clientId_ = data.clientId; this.clientId_ = data.clientId;
this.gapsCookie_ = data.gapsCookie;
this.gapsCookieSent_ = false;
this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages; this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages;
this.chromeOSApiVersion_ = data.chromeOSApiVersion; this.chromeOSApiVersion_ = data.chromeOSApiVersion;
...@@ -312,16 +302,6 @@ cr.define('cr.login', function() { ...@@ -312,16 +302,6 @@ cr.define('cr.login', function() {
this.webview_.contextMenus.onShow.addListener(function(e) { this.webview_.contextMenus.onShow.addListener(function(e) {
e.preventDefault(); e.preventDefault();
}); });
if (!this.onBeforeSetHeadersSet_) {
this.onBeforeSetHeadersSet_ = true;
var filterPrefix = this.constructChromeOSAPIUrl_();
// This depends on gaiaUrl parameter, that is why it is here.
this.webview_.request.onBeforeSendHeaders.addListener(
this.onBeforeSendHeaders_.bind(this),
{urls: [filterPrefix + '?*', filterPrefix + '/*']},
['requestHeaders', 'blocking']);
}
} }
this.webview_.src = this.reloadUrl_; this.webview_.src = this.reloadUrl_;
...@@ -552,64 +532,6 @@ cr.define('cr.login', function() { ...@@ -552,64 +532,6 @@ cr.define('cr.login', function() {
} }
}; };
/**
* This method replaces cookie value in cookie header.
* @param@ {string} header_value Original string value of Cookie header.
* @param@ {string} cookie_name Name of cookie to be replaced.
* @param@ {string} cookie_value New cookie value.
* @return {string} New Cookie header value.
* @private
*/
Authenticator.prototype.updateCookieValue_ = function(
header_value, cookie_name, cookie_value) {
var cookies = header_value.split(/\s*;\s*/);
var found = false;
for (var i = 0; i < cookies.length; ++i) {
if (cookies[i].startsWith(cookie_name + '=')) {
found = true;
cookies[i] = cookie_name + '=' + cookie_value;
break;
}
}
if (!found) {
cookies.push(cookie_name + '=' + cookie_value);
}
return cookies.join('; ');
};
/**
* Handler for webView.request.onBeforeSendHeaders .
* @return {!Object} Modified request headers.
* @private
*/
Authenticator.prototype.onBeforeSendHeaders_ = function(details) {
// We should re-send cookie if first request was unsuccessful (i.e. no new
// GAPS cookie was received).
if (this.isNewGaiaFlow && this.gapsCookie_ &&
(!this.gapsCookieSent_ || !this.newGapsCookie_)) {
var headers = details.requestHeaders;
var found = false;
var gapsCookie = this.gapsCookie_;
for (var i = 0, l = headers.length; i < l; ++i) {
if (headers[i].name == COOKIE_HEADER) {
// TODO(jam): this doesn't work with network service since webRequest
// won't see the Cookie header. Who uses this?
headers[i].value = this.updateCookieValue_(
headers[i].value, GAPS_COOKIE, gapsCookie);
found = true;
break;
}
}
if (!found) {
details.requestHeaders.push(
{name: COOKIE_HEADER, value: GAPS_COOKIE + '=' + gapsCookie});
}
this.gapsCookieSent_ = true;
}
return {requestHeaders: details.requestHeaders};
};
/** /**
* Returns true if given HTML5 message is received from the webview element. * Returns true if given HTML5 message is received from the webview element.
* @param {object} e Payload of the received HTML5 message. * @param {object} e Payload of the received HTML5 message.
......
...@@ -91,6 +91,9 @@ const char kRestrictiveProxyURL[] = "https://www.google.com/generate_204"; ...@@ -91,6 +91,9 @@ const char kRestrictiveProxyURL[] = "https://www.google.com/generate_204";
const char kEndpointGen[] = "1.0"; const char kEndpointGen[] = "1.0";
const char kOAUTHCodeCookie[] = "oauth_code";
const char kGAPSCookie[] = "GAPS";
// The possible modes that the Gaia signin screen can be in. // The possible modes that the Gaia signin screen can be in.
enum GaiaScreenMode { enum GaiaScreenMode {
// Default Gaia authentication will be used. // Default Gaia authentication will be used.
...@@ -352,6 +355,38 @@ void GaiaScreenHandler::LoadGaia(const GaiaContext& context) { ...@@ -352,6 +355,38 @@ void GaiaScreenHandler::LoadGaia(const GaiaContext& context) {
void GaiaScreenHandler::LoadGaiaWithPartition( void GaiaScreenHandler::LoadGaiaWithPartition(
const GaiaContext& context, const GaiaContext& context,
const std::string& partition_name) { const std::string& partition_name) {
auto callback =
base::BindOnce(&GaiaScreenHandler::OnSetCookieForLoadGaiaWithPartition,
weak_factory_.GetWeakPtr(), context, partition_name);
if (context.gaps_cookie.empty()) {
std::move(callback).Run(true);
return;
}
// When the network service is enabled the webRequest API doesn't allow
// modification of the cookie header. So manually write the GAPS cookie into
// the CookieManager.
login::SigninPartitionManager* signin_partition_manager =
login::SigninPartitionManager::Factory::GetForBrowserContext(
Profile::FromWebUI(web_ui()));
content::StoragePartition* partition =
signin_partition_manager->GetCurrentStoragePartition();
std::string gaps_cookie_value(kGAPSCookie);
gaps_cookie_value += "=" + context.gaps_cookie;
std::unique_ptr<net::CanonicalCookie> cc(net::CanonicalCookie::Create(
GaiaUrls::GetInstance()->gaia_url(), gaps_cookie_value, base::Time::Now(),
net::CookieOptions()));
partition->GetCookieManagerForBrowserProcess()->SetCanonicalCookie(
*cc.get(), true /* secure_source */, true /* modify_http_only */,
std::move(callback));
}
void GaiaScreenHandler::OnSetCookieForLoadGaiaWithPartition(
const GaiaContext& context,
const std::string& partition_name,
bool success) {
std::unique_ptr<std::string> version = std::make_unique<std::string>(); std::unique_ptr<std::string> version = std::make_unique<std::string>();
std::unique_ptr<bool> consent = std::make_unique<bool>(); std::unique_ptr<bool> consent = std::make_unique<bool>();
base::OnceClosure get_version_and_consent = base::OnceClosure get_version_and_consent =
...@@ -377,7 +412,6 @@ void GaiaScreenHandler::LoadGaiaWithPartitionAndVersionAndConsent( ...@@ -377,7 +412,6 @@ void GaiaScreenHandler::LoadGaiaWithPartitionAndVersionAndConsent(
params.SetString("gaiaId", context.gaia_id); params.SetString("gaiaId", context.gaia_id);
params.SetBoolean("readOnlyEmail", true); params.SetBoolean("readOnlyEmail", true);
params.SetString("email", context.email); params.SetString("email", context.email);
params.SetString("gapsCookie", context.gaps_cookie);
UpdateAuthParams(&params, IsRestrictiveProxy()); UpdateAuthParams(&params, IsRestrictiveProxy());
...@@ -776,9 +810,9 @@ void GaiaScreenHandler::OnGetCookiesForCompleteAuthentication( ...@@ -776,9 +810,9 @@ void GaiaScreenHandler::OnGetCookiesForCompleteAuthentication(
const std::vector<net::CanonicalCookie>& cookies) { const std::vector<net::CanonicalCookie>& cookies) {
std::string auth_code, gaps_cookie; std::string auth_code, gaps_cookie;
for (const auto& cookie : cookies) { for (const auto& cookie : cookies) {
if (cookie.Name() == "oauth_code") if (cookie.Name() == kOAUTHCodeCookie)
auth_code = cookie.Value(); auth_code = cookie.Value();
else if (cookie.Name() == "GAPS") else if (cookie.Name() == kGAPSCookie)
gaps_cookie = cookie.Value(); gaps_cookie = cookie.Value();
} }
......
...@@ -74,6 +74,11 @@ class GaiaScreenHandler : public BaseScreenHandler, ...@@ -74,6 +74,11 @@ class GaiaScreenHandler : public BaseScreenHandler,
void LoadGaiaWithPartition(const GaiaContext& context, void LoadGaiaWithPartition(const GaiaContext& context,
const std::string& partition_name); const std::string& partition_name);
// Called after the GAPS cookie, if present, is added to the cookie store.
void OnSetCookieForLoadGaiaWithPartition(const GaiaContext& context,
const std::string& partition_name,
bool success);
// Callback that loads GAIA after version and stat consent information has // Callback that loads GAIA after version and stat consent information has
// been retrieved. // been retrieved.
void LoadGaiaWithPartitionAndVersionAndConsent( void LoadGaiaWithPartitionAndVersionAndConsent(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment