summaryrefslogtreecommitdiffstats
path: root/chrome/common/net/gaia
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/common/net/gaia')
-rw-r--r--chrome/common/net/gaia/gaia_auth_consumer.h3
-rw-r--r--chrome/common/net/gaia/gaia_auth_fetcher.cc73
-rw-r--r--chrome/common/net/gaia/gaia_auth_fetcher.h20
-rw-r--r--chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc63
-rw-r--r--chrome/common/net/gaia/gaia_urls.cc6
-rw-r--r--chrome/common/net/gaia/gaia_urls.h2
6 files changed, 164 insertions, 3 deletions
diff --git a/chrome/common/net/gaia/gaia_auth_consumer.h b/chrome/common/net/gaia/gaia_auth_consumer.h
index 9878637..fdca0ab 100644
--- a/chrome/common/net/gaia/gaia_auth_consumer.h
+++ b/chrome/common/net/gaia/gaia_auth_consumer.h
@@ -49,6 +49,9 @@ class GaiaAuthConsumer {
virtual void OnTokenAuthSuccess(const std::string& data) {}
virtual void OnTokenAuthFailure(const GoogleServiceAuthError& error) {}
+
+ virtual void OnMergeSessionSuccess(const std::string& data) {}
+ virtual void OnMergeSessionFailure(const GoogleServiceAuthError& error) {}
};
#endif // CHROME_COMMON_NET_GAIA_GAIA_AUTH_CONSUMER_H_
diff --git a/chrome/common/net/gaia/gaia_auth_fetcher.cc b/chrome/common/net/gaia/gaia_auth_fetcher.cc
index b2fffb3..65318ff 100644
--- a/chrome/common/net/gaia/gaia_auth_fetcher.cc
+++ b/chrome/common/net/gaia/gaia_auth_fetcher.cc
@@ -54,6 +54,11 @@ const char GaiaAuthFetcher::kTokenAuthFormat[] =
"auth=%s&"
"continue=%s&"
"source=%s";
+// static
+const char GaiaAuthFetcher::kMergeSessionFormat[] =
+ "uberauth=%s&"
+ "continue=%s&"
+ "source=%s";
// static
const char GaiaAuthFetcher::kAccountDeletedError[] = "AccountDeleted";
@@ -104,6 +109,7 @@ GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer,
issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()),
get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()),
token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()),
+ merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()),
fetch_pending_(false) {}
GaiaAuthFetcher::~GaiaAuthFetcher() {}
@@ -122,6 +128,7 @@ URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher(
net::URLRequestContextGetter* getter,
const std::string& body,
const GURL& gaia_gurl,
+ bool send_cookies,
URLFetcher::Delegate* delegate) {
URLFetcher* to_return =
@@ -130,8 +137,16 @@ URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher(
URLFetcher::POST,
delegate);
to_return->set_request_context(getter);
- to_return->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES);
to_return->set_upload_data("application/x-www-form-urlencoded", body);
+
+ // The Gaia token exchange requests do not require any cookie-based
+ // identification as part of requests. We suppress sending any cookies to
+ // maintain a separation between the user's browsing and Chrome's internal
+ // services. Where such mixing is desired (MergeSession), it will be done
+ // explicitly.
+ if (!send_cookies)
+ to_return->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES);
+
return to_return;
}
@@ -213,6 +228,20 @@ std::string GaiaAuthFetcher::MakeTokenAuthBody(const std::string& auth_token,
encoded_source.c_str());
}
+// static
+std::string GaiaAuthFetcher::MakeMergeSessionBody(
+ const std::string& auth_token,
+ const std::string& continue_url,
+ const std::string& source) {
+ std::string encoded_auth_token = EscapeUrlEncodedData(auth_token, true);
+ std::string encoded_continue_url = EscapeUrlEncodedData(continue_url, true);
+ std::string encoded_source = EscapeUrlEncodedData(source, true);
+ return base::StringPrintf(kMergeSessionFormat,
+ encoded_auth_token.c_str(),
+ encoded_continue_url.c_str(),
+ encoded_source.c_str());
+}
+
// Helper method that extracts tokens from a successful reply.
// static
void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data,
@@ -288,6 +317,7 @@ void GaiaAuthFetcher::StartClientLogin(
fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_,
client_login_gurl_,
+ false,
this));
fetch_pending_ = true;
fetcher_->Start();
@@ -304,6 +334,7 @@ void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid,
fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_,
issue_auth_token_gurl_,
+ false,
this));
fetch_pending_ = true;
fetcher_->Start();
@@ -318,6 +349,7 @@ void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid,
fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_,
get_user_info_gurl_,
+ false,
this));
fetch_pending_ = true;
requested_info_key_ = info_key;
@@ -337,6 +369,31 @@ void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) {
fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_,
token_auth_gurl_,
+ false,
+ this));
+ fetch_pending_ = true;
+ fetcher_->Start();
+}
+
+void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) {
+ DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
+
+ VLOG(1) << "Starting MergeSession with auth_token=" << auth_token;
+
+ // The continue URL is a required parameter of the MergeSession API, but in
+ // this case we don't actually need or want to navigate to it. Setting it to
+ // an arbitrary Google URL.
+ //
+ // In order for the new session to be merged correctly, the server needs to
+ // know what sessions already exist in the browser. The fetcher needs to be
+ // created such that it sends the cookies with the request, which is
+ // different from all other requests the fetcher can make.
+ std::string continue_url("http://www.google.com");
+ request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_);
+ fetcher_.reset(CreateGaiaFetcher(getter_,
+ request_body_,
+ merge_session_gurl_,
+ true,
this));
fetch_pending_ = true;
fetcher_->Start();
@@ -512,6 +569,16 @@ void GaiaAuthFetcher::OnTokenAuthFetched(const std::string& data,
}
}
+void GaiaAuthFetcher::OnMergeSessionFetched(const std::string& data,
+ const net::URLRequestStatus& status,
+ int response_code) {
+ if (status.is_success() && response_code == RC_REQUEST_OK) {
+ consumer_->OnMergeSessionSuccess(data);
+ } else {
+ consumer_->OnMergeSessionFailure(GenerateAuthError(data, status));
+ }
+}
+
void GaiaAuthFetcher::OnURLFetchComplete(const URLFetcher* source,
const GURL& url,
const net::URLRequestStatus& status,
@@ -527,6 +594,10 @@ void GaiaAuthFetcher::OnURLFetchComplete(const URLFetcher* source,
OnGetUserInfoFetched(data, status, response_code);
} else if (url == token_auth_gurl_) {
OnTokenAuthFetched(data, status, response_code);
+ } else if (url == merge_session_gurl_ ||
+ (source && source->original_url() == merge_session_gurl_)) {
+ // MergeSession may redirect, so check the original URL of the fetcher.
+ OnMergeSessionFetched(data, status, response_code);
} else {
NOTREACHED();
}
diff --git a/chrome/common/net/gaia/gaia_auth_fetcher.h b/chrome/common/net/gaia/gaia_auth_fetcher.h
index 413b06a..1fb471a 100644
--- a/chrome/common/net/gaia/gaia_auth_fetcher.h
+++ b/chrome/common/net/gaia/gaia_auth_fetcher.h
@@ -71,6 +71,11 @@ class GaiaAuthFetcher : public URLFetcher::Delegate {
// Start a TokenAuth request to pre-login the user with the given credentials.
void StartTokenAuth(const std::string& auth_token);
+ // Start a MergeSession request to pre-login the user with the given
+ // credentials. Unlike TokenAuth above, MergeSession will not sign out any
+ // existing accounts.
+ void StartMergeSession(const std::string& auth_token);
+
// Implementation of URLFetcher::Delegate
virtual void OnURLFetchComplete(const URLFetcher* source,
const GURL& url,
@@ -108,6 +113,8 @@ class GaiaAuthFetcher : public URLFetcher::Delegate {
static const char kGetUserInfoFormat[];
// The format of the POST body for TokenAuth.
static const char kTokenAuthFormat[];
+ // The format of the POST body for MergeSession.
+ static const char kMergeSessionFormat[];
// Constants for parsing ClientLogin errors.
static const char kAccountDeletedError[];
@@ -142,6 +149,10 @@ class GaiaAuthFetcher : public URLFetcher::Delegate {
const net::URLRequestStatus& status,
int response_code);
+ void OnMergeSessionFetched(const std::string& data,
+ const net::URLRequestStatus& status,
+ int response_code);
+
// Tokenize the results of a ClientLogin fetch.
static void ParseClientLoginResponse(const std::string& data,
std::string* sid,
@@ -180,10 +191,16 @@ class GaiaAuthFetcher : public URLFetcher::Delegate {
const std::string& continue_url,
const std::string& source);
+ // Supply the authentication token returned from StartIssueAuthToken.
+ static std::string MakeMergeSessionBody(const std::string& auth_token,
+ const std::string& continue_url,
+ const std::string& source);
+
// Create a fetcher useable for making any Gaia request.
static URLFetcher* CreateGaiaFetcher(net::URLRequestContextGetter* getter,
const std::string& body,
- const GURL& gaia_gurl_,
+ const GURL& gaia_gurl,
+ bool send_cookies,
URLFetcher::Delegate* delegate);
// From a URLFetcher result, generate an appropriate error.
@@ -201,6 +218,7 @@ class GaiaAuthFetcher : public URLFetcher::Delegate {
const GURL issue_auth_token_gurl_;
const GURL get_user_info_gurl_;
const GURL token_auth_gurl_;
+ const GURL merge_session_gurl_;
// While a fetch is going on:
scoped_ptr<URLFetcher> fetcher_;
diff --git a/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc b/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc
index 51a77a6..6f12911 100644
--- a/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc
+++ b/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc
@@ -21,6 +21,7 @@
#include "content/common/url_fetcher.h"
#include "content/test/test_url_fetcher_factory.h"
#include "googleurl/src/gurl.h"
+#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_status.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -67,7 +68,8 @@ class GaiaAuthFetcherTest : public TestingBrowserProcessTest {
: client_login_source_(GaiaUrls::GetInstance()->client_login_url()),
issue_auth_token_source_(
GaiaUrls::GetInstance()->issue_auth_token_url()),
- token_auth_source_(GaiaUrls::GetInstance()->token_auth_url()) {}
+ token_auth_source_(GaiaUrls::GetInstance()->token_auth_url()),
+ merge_session_source_(GaiaUrls::GetInstance()->merge_session_url()) {}
void RunParsingTest(const std::string& data,
const std::string& sid,
@@ -111,6 +113,7 @@ class GaiaAuthFetcherTest : public TestingBrowserProcessTest {
GURL client_login_source_;
GURL issue_auth_token_source_;
GURL token_auth_source_;
+ GURL merge_session_source_;
TestingProfile profile_;
protected:
MessageLoop message_loop_;
@@ -125,11 +128,14 @@ class MockGaiaConsumer : public GaiaAuthConsumer {
MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service,
const std::string& token));
MOCK_METHOD1(OnTokenAuthSuccess, void(const std::string& data));
+ MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
MOCK_METHOD1(OnClientLoginFailure,
void(const GoogleServiceAuthError& error));
MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service,
const GoogleServiceAuthError& error));
MOCK_METHOD1(OnTokenAuthFailure, void(const GoogleServiceAuthError& error));
+ MOCK_METHOD1(OnMergeSessionFailure, void(
+ const GoogleServiceAuthError& error));
};
TEST_F(GaiaAuthFetcherTest, ErrorComparator) {
@@ -592,3 +598,58 @@ TEST_F(GaiaAuthFetcherTest, TokenAuthNetFailure) {
"");
EXPECT_FALSE(auth.HasPendingFetch());
}
+
+TEST_F(GaiaAuthFetcherTest, MergeSessionSuccess) {
+ MockGaiaConsumer consumer;
+ EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
+ .Times(1);
+
+ TestingProfile profile;
+ TestURLFetcherFactory factory;
+
+ GaiaAuthFetcher auth(&consumer, std::string(),
+ profile_.GetRequestContext());
+ auth.StartMergeSession("myubertoken");
+
+ EXPECT_TRUE(auth.HasPendingFetch());
+ auth.OnURLFetchComplete(
+ NULL,
+ merge_session_source_,
+ net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
+ RC_REQUEST_OK,
+ cookies_,
+ "<html></html>");
+ EXPECT_FALSE(auth.HasPendingFetch());
+}
+
+TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) {
+ MockGaiaConsumer consumer;
+ EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
+ .Times(1);
+
+ TestingProfile profile;
+ TestURLFetcherFactory factory;
+
+ GaiaAuthFetcher auth(&consumer, std::string(),
+ profile_.GetRequestContext());
+ auth.StartMergeSession("myubertoken");
+
+ // Make sure the fetcher created has the expected flags. Set its url()
+ // properties to reflect a redirect.
+ TestURLFetcher* test_fetcher = factory.GetFetcherByID(0);
+ EXPECT_TRUE(test_fetcher != NULL);
+ EXPECT_TRUE(test_fetcher->load_flags() == net::LOAD_NORMAL);
+ EXPECT_TRUE(auth.HasPendingFetch());
+
+ GURL final_url("http://www.google.com/CheckCookie");
+ test_fetcher->set_url(final_url);
+
+ auth.OnURLFetchComplete(
+ test_fetcher,
+ test_fetcher->url(),
+ net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
+ RC_REQUEST_OK,
+ cookies_,
+ "<html></html>");
+ EXPECT_FALSE(auth.HasPendingFetch());
+}
diff --git a/chrome/common/net/gaia/gaia_urls.cc b/chrome/common/net/gaia/gaia_urls.cc
index cf64fb5..ca06741 100644
--- a/chrome/common/net/gaia/gaia_urls.cc
+++ b/chrome/common/net/gaia/gaia_urls.cc
@@ -15,6 +15,7 @@ const char kClientLoginUrlSuffix[] = "/accounts/ClientLogin";
const char kIssueAuthTokenUrlSuffix[] = "/accounts/IssueAuthToken";
const char kGetUserInfoUrlSuffix[] = "/accounts/GetUserInfo";
const char kTokenAuthUrlSuffix[] = "/accounts/TokenAuth";
+const char kMergeSessionUrlSuffix[] = "/accounts/MergeSession";
} // namespacce
@@ -35,6 +36,7 @@ GaiaUrls::GaiaUrls() {
issue_auth_token_url_ = "https://" + host_base_ + kIssueAuthTokenUrlSuffix;
get_user_info_url_ = "https://" + host_base_ + kGetUserInfoUrlSuffix;
token_auth_url_ = "https://" + host_base_ + kTokenAuthUrlSuffix;
+ merge_session_url_ = "https://" + host_base_ + kMergeSessionUrlSuffix;
}
GaiaUrls::~GaiaUrls() {
@@ -59,3 +61,7 @@ const std::string& GaiaUrls::get_user_info_url() {
const std::string& GaiaUrls::token_auth_url() {
return token_auth_url_;
}
+
+const std::string& GaiaUrls::merge_session_url() {
+ return merge_session_url_;
+}
diff --git a/chrome/common/net/gaia/gaia_urls.h b/chrome/common/net/gaia/gaia_urls.h
index 327110d..c82823a 100644
--- a/chrome/common/net/gaia/gaia_urls.h
+++ b/chrome/common/net/gaia/gaia_urls.h
@@ -21,6 +21,7 @@ class GaiaUrls {
const std::string& issue_auth_token_url();
const std::string& get_user_info_url();
const std::string& token_auth_url();
+ const std::string& merge_session_url();
private:
GaiaUrls();
@@ -34,6 +35,7 @@ class GaiaUrls {
std::string issue_auth_token_url_;
std::string get_user_info_url_;
std::string token_auth_url_;
+ std::string merge_session_url_;
DISALLOW_COPY_AND_ASSIGN(GaiaUrls);
};