Index: chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc |
diff --git a/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc b/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc |
index d98d0fc84960fa841553a026652bdcab56e002e6..4eb711c4ec4611c64e6e7c1188dde44c756d578d 100644 |
--- a/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc |
+++ b/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc |
@@ -18,6 +18,9 @@ |
#include "google_apis/gaia/gaia_constants.h" |
#include "google_apis/gaia/gaia_urls.h" |
#include "net/base/escape.h" |
+#include "net/ssl/channel_id_service.h" |
+#include "net/url_request/url_request_context.h" |
+#include "net/url_request/url_request_context_getter.h" |
namespace extensions { |
@@ -91,19 +94,79 @@ GaiaWebAuthFlow::~GaiaWebAuthFlow() { |
} |
void GaiaWebAuthFlow::Start() { |
+ main_context_ = profile_->GetRequestContext(); |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&GaiaWebAuthFlow::StartOnIOThread, base::Unretained(this))); |
+} |
+ |
+void GaiaWebAuthFlow::StartOnIOThread() { |
+ net::URLRequestContext* base_context = main_context_->GetURLRequestContext(); |
+ // Create a temporary request context for the Uber Token Fetch that doesn't |
+ // have a Channel ID. This way, the Uber Token will not be channel bound and |
+ // will be useable for the MergeSession call that will take place in the app's |
+ // request context. |
+ ProfileIOData::AppRequestContext* context = |
+ new ProfileIOData::AppRequestContext; |
+ ubertoken_request_context_.reset(context); |
+ |
+ context->CopyFrom(base_context); |
+ context->SetChannelIDService(nullptr); |
+ |
+ // Merely setting the Channel ID Service isn't enough, we also have to build a |
+ // new HttpNetworkSession. |
+ std::unique_ptr<net::HttpCache::BackendFactory> app_backend = |
+ net::HttpCache::DefaultBackend::InMemory(0); |
+ net::HttpNetworkSession::Params network_params = |
+ *base_context->GetNetworkSessionParams(); |
+ network_params.channel_id_service = nullptr; |
+ std::unique_ptr<net::HttpNetworkSession> http_network_session( |
+ new net::HttpNetworkSession(network_params)); |
+ std::unique_ptr<net::HttpCache> app_http_cache( |
+ new net::HttpCache(http_network_session.get(), |
+ std::move(app_backend), true)); |
+ |
+ context->SetHttpNetworkSession( |
+ std::move(http_network_session)); |
+ context->SetHttpTransactionFactory(std::move(app_http_cache)); |
+ |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&GaiaWebAuthFlow::StartUberTokenFetch, |
+ base::Unretained(this))); |
+} |
+ |
+void GaiaWebAuthFlow::StartUberTokenFetch() { |
ProfileOAuth2TokenService* token_service = |
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
+ context_getter_ = new net::TrivialURLRequestContextGetter( |
+ ubertoken_request_context_.get(), |
+ main_context_->GetNetworkTaskRunner()); |
ubertoken_fetcher_.reset(new UbertokenFetcher(token_service, |
this, |
GaiaConstants::kChromeSource, |
- profile_->GetRequestContext())); |
+ context_getter_.get())); |
ubertoken_fetcher_->StartFetchingToken(account_id_); |
} |
+void GaiaWebAuthFlow::CleanupRequestContextOnIOThread() { |
+ ubertoken_request_context_.reset(); |
+} |
+ |
void GaiaWebAuthFlow::OnUbertokenSuccess(const std::string& token) { |
TRACE_EVENT_ASYNC_STEP_PAST0( |
"identity", "GaiaWebAuthFlow", this, "OnUbertokenSuccess"); |
+ // The temporary request context isn't required after the Uber Token request |
+ // completes. It needs to be deleted on the IO Thread, so do that here. |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&GaiaWebAuthFlow::CleanupRequestContextOnIOThread, |
+ base::Unretained(this))); |
+ |
const char kMergeSessionQueryFormat[] = "?uberauth=%s&" |
"continue=%s&" |
"source=appsv2"; |
@@ -127,6 +190,14 @@ void GaiaWebAuthFlow::OnUbertokenFailure(const GoogleServiceAuthError& error) { |
"error", |
error.ToString()); |
+ // The temporary request context isn't required after the Uber Token request |
+ // completes. It needs to be deleted on the IO Thread, so do that here. |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&GaiaWebAuthFlow::CleanupRequestContextOnIOThread, |
+ base::Unretained(this))); |
+ |
DVLOG(1) << "OnUbertokenFailure: " << error.error_message(); |
delegate_->OnGaiaFlowFailure( |
GaiaWebAuthFlow::SERVICE_AUTH_ERROR, error, std::string()); |