diff options
Diffstat (limited to 'chrome/common/net/gaia')
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_consumer.h | 3 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_fetcher.cc | 73 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_fetcher.h | 20 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc | 63 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_urls.cc | 6 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_urls.h | 2 |
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); }; |