Commit 69f4e90e authored by rogerta@chromium.org's avatar rogerta@chromium.org

Changes to the GAIA auth fetching to support one-click login.

BUG=110050
TEST=no user visible functionality, see new unit tests.

Review URL: http://codereview.chromium.org/9465018

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124490 0039d316-1c4b-4281-b951-d872f2087c98
parent 3d5a60bf
...@@ -8,9 +8,14 @@ ...@@ -8,9 +8,14 @@
#include <string> #include <string>
#include <map> #include <map>
#include <vector>
class GoogleServiceAuthError; class GoogleServiceAuthError;
namespace net {
typedef std::vector<std::string> ResponseCookies;
}
typedef std::map<std::string, std::string> UserInfoMap; typedef std::map<std::string, std::string> UserInfoMap;
// An interface that defines the callbacks for objects that // An interface that defines the callbacks for objects that
...@@ -53,7 +58,8 @@ class GaiaAuthConsumer { ...@@ -53,7 +58,8 @@ class GaiaAuthConsumer {
virtual void OnGetUserInfoSuccess(const UserInfoMap& data) {} virtual void OnGetUserInfoSuccess(const UserInfoMap& data) {}
virtual void OnGetUserInfoFailure(const GoogleServiceAuthError& error) {} virtual void OnGetUserInfoFailure(const GoogleServiceAuthError& error) {}
virtual void OnTokenAuthSuccess(const std::string& data) {} virtual void OnTokenAuthSuccess(const net::ResponseCookies& cookies,
const std::string& data) {}
virtual void OnTokenAuthFailure(const GoogleServiceAuthError& error) {} virtual void OnTokenAuthFailure(const GoogleServiceAuthError& error) {}
virtual void OnUberAuthTokenSuccess(const std::string& token) {} virtual void OnUberAuthTokenSuccess(const std::string& token) {}
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
#include "net/url_request/url_request_status.h" #include "net/url_request/url_request_status.h"
namespace { namespace {
const int kLoadFlagsIgnoreCookies = net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES;
static bool CookiePartsContains(const std::vector<std::string>& parts, static bool CookiePartsContains(const std::vector<std::string>& parts,
const char* part) { const char* part) {
return std::find(parts.begin(), parts.end(), part) != parts.end(); return std::find(parts.begin(), parts.end(), part) != parts.end();
...@@ -148,8 +151,8 @@ const char GaiaAuthFetcher::kOAuth2AccessTokenKey[] = "access_token"; ...@@ -148,8 +151,8 @@ const char GaiaAuthFetcher::kOAuth2AccessTokenKey[] = "access_token";
const char GaiaAuthFetcher::kOAuth2ExpiresInKey[] = "expires_in"; const char GaiaAuthFetcher::kOAuth2ExpiresInKey[] = "expires_in";
GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer,
const std::string& source, const std::string& source,
net::URLRequestContextGetter* getter) net::URLRequestContextGetter* getter)
: consumer_(consumer), : consumer_(consumer),
getter_(getter), getter_(getter),
source_(source), source_(source),
...@@ -182,7 +185,7 @@ content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( ...@@ -182,7 +185,7 @@ content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher(
const std::string& body, const std::string& body,
const std::string& headers, const std::string& headers,
const GURL& gaia_gurl, const GURL& gaia_gurl,
bool use_cookies, int load_flags,
content::URLFetcherDelegate* delegate) { content::URLFetcherDelegate* delegate) {
content::URLFetcher* to_return = content::URLFetcher::Create( content::URLFetcher* to_return = content::URLFetcher::Create(
0, gaia_gurl, 0, gaia_gurl,
...@@ -196,10 +199,8 @@ content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( ...@@ -196,10 +199,8 @@ content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher(
// maintain a separation between the user's browsing and Chrome's internal // maintain a separation between the user's browsing and Chrome's internal
// services. Where such mixing is desired (MergeSession), it will be done // services. Where such mixing is desired (MergeSession), it will be done
// explicitly. // explicitly.
if (!use_cookies) { to_return->SetLoadFlags(load_flags);
to_return->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES);
}
if (!headers.empty()) if (!headers.empty())
to_return->SetExtraRequestHeaders(headers); to_return->SetExtraRequestHeaders(headers);
...@@ -478,7 +479,7 @@ void GaiaAuthFetcher::StartClientLogin( ...@@ -478,7 +479,7 @@ void GaiaAuthFetcher::StartClientLogin(
request_body_, request_body_,
"", "",
client_login_gurl_, client_login_gurl_,
false, kLoadFlagsIgnoreCookies,
this)); this));
fetch_pending_ = true; fetch_pending_ = true;
fetcher_->Start(); fetcher_->Start();
...@@ -496,7 +497,7 @@ void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, ...@@ -496,7 +497,7 @@ void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid,
request_body_, request_body_,
"", "",
issue_auth_token_gurl_, issue_auth_token_gurl_,
false, kLoadFlagsIgnoreCookies,
this)); this));
fetch_pending_ = true; fetch_pending_ = true;
fetcher_->Start(); fetcher_->Start();
...@@ -508,11 +509,23 @@ void GaiaAuthFetcher::StartOAuthLoginTokenFetch( ...@@ -508,11 +509,23 @@ void GaiaAuthFetcher::StartOAuthLoginTokenFetch(
DVLOG(1) << "Starting OAuth login token fetch"; DVLOG(1) << "Starting OAuth login token fetch";
request_body_ = MakeGetAuthCodeBody(); request_body_ = MakeGetAuthCodeBody();
// If no auth_token is given, then make sure to use the cookie jar with this
// request. Otherwise the token contains all the necessary information and
// the cookie jar should not be touched.
int load_flags = net::LOAD_NORMAL;
std::string auth_code_header = "";
if (!auth_token.empty()) {
load_flags = kLoadFlagsIgnoreCookies;
auth_code_header = MakeGetAuthCodeHeader(auth_token);
}
fetcher_.reset(CreateGaiaFetcher(getter_, fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_, request_body_,
MakeGetAuthCodeHeader(auth_token), auth_code_header,
client_login_to_oauth2_gurl_, client_login_to_oauth2_gurl_,
false, load_flags,
this)); this));
fetch_pending_ = true; fetch_pending_ = true;
fetcher_->Start(); fetcher_->Start();
...@@ -527,7 +540,7 @@ void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid) { ...@@ -527,7 +540,7 @@ void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid) {
request_body_, request_body_,
"", "",
get_user_info_gurl_, get_user_info_gurl_,
false, kLoadFlagsIgnoreCookies,
this)); this));
fetch_pending_ = true; fetch_pending_ = true;
fetcher_->Start(); fetcher_->Start();
...@@ -547,7 +560,7 @@ void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { ...@@ -547,7 +560,7 @@ void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) {
request_body_, request_body_,
"", "",
token_auth_gurl_, token_auth_gurl_,
false, kLoadFlagsIgnoreCookies,
this)); this));
fetch_pending_ = true; fetch_pending_ = true;
fetcher_->Start(); fetcher_->Start();
...@@ -572,7 +585,7 @@ void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { ...@@ -572,7 +585,7 @@ void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) {
request_body_, request_body_,
"", "",
merge_session_gurl_, merge_session_gurl_,
true, net::LOAD_NORMAL,
this)); this));
fetch_pending_ = true; fetch_pending_ = true;
fetcher_->Start(); fetcher_->Start();
...@@ -590,7 +603,7 @@ void GaiaAuthFetcher::StartUberAuthTokenFetch(const std::string& access_token) { ...@@ -590,7 +603,7 @@ void GaiaAuthFetcher::StartUberAuthTokenFetch(const std::string& access_token) {
"", "",
authentication_header, authentication_header,
uberauth_token_gurl_, uberauth_token_gurl_,
false, kLoadFlagsIgnoreCookies,
this)); this));
fetch_pending_ = true; fetch_pending_ = true;
fetcher_->Start(); fetcher_->Start();
...@@ -755,7 +768,7 @@ void GaiaAuthFetcher::StartOAuth2TokenPairFetch(const std::string& auth_code) { ...@@ -755,7 +768,7 @@ void GaiaAuthFetcher::StartOAuth2TokenPairFetch(const std::string& auth_code) {
request_body_, request_body_,
"", "",
oauth2_token_gurl_, oauth2_token_gurl_,
false, kLoadFlagsIgnoreCookies,
this)); this));
fetch_pending_ = true; fetch_pending_ = true;
fetcher_->Start(); fetcher_->Start();
...@@ -797,11 +810,12 @@ void GaiaAuthFetcher::OnGetUserInfoFetched( ...@@ -797,11 +810,12 @@ void GaiaAuthFetcher::OnGetUserInfoFetched(
} }
} }
void GaiaAuthFetcher::OnTokenAuthFetched(const std::string& data, void GaiaAuthFetcher::OnTokenAuthFetched(const net::ResponseCookies& cookies,
const std::string& data,
const net::URLRequestStatus& status, const net::URLRequestStatus& status,
int response_code) { int response_code) {
if (status.is_success() && response_code == net::HTTP_OK) { if (status.is_success() && response_code == net::HTTP_OK) {
consumer_->OnTokenAuthSuccess(data); consumer_->OnTokenAuthSuccess(cookies, data);
} else { } else {
consumer_->OnTokenAuthFailure(GenerateAuthError(data, status)); consumer_->OnTokenAuthFailure(GenerateAuthError(data, status));
} }
...@@ -829,7 +843,10 @@ void GaiaAuthFetcher::OnUberAuthTokenFetch(const std::string& data, ...@@ -829,7 +843,10 @@ void GaiaAuthFetcher::OnUberAuthTokenFetch(const std::string& data,
void GaiaAuthFetcher::OnURLFetchComplete(const content::URLFetcher* source) { void GaiaAuthFetcher::OnURLFetchComplete(const content::URLFetcher* source) {
fetch_pending_ = false; fetch_pending_ = false;
const GURL& url = source->GetURL(); // Some of the GAIA requests perform redirects, which results in the final
// URL of the fetcher not being the original URL requested. Therefore use
// the original URL when determining which OnXXX function to call.
const GURL& url = source->GetOriginalURL();
const net::URLRequestStatus& status = source->GetStatus(); const net::URLRequestStatus& status = source->GetStatus();
int response_code = source->GetResponseCode(); int response_code = source->GetResponseCode();
std::string data; std::string data;
...@@ -846,10 +863,8 @@ void GaiaAuthFetcher::OnURLFetchComplete(const content::URLFetcher* source) { ...@@ -846,10 +863,8 @@ void GaiaAuthFetcher::OnURLFetchComplete(const content::URLFetcher* source) {
} else if (url == get_user_info_gurl_) { } else if (url == get_user_info_gurl_) {
OnGetUserInfoFetched(data, status, response_code); OnGetUserInfoFetched(data, status, response_code);
} else if (url == token_auth_gurl_) { } else if (url == token_auth_gurl_) {
OnTokenAuthFetched(data, status, response_code); OnTokenAuthFetched(source->GetCookies(), data, status, response_code);
} else if (url == merge_session_gurl_ || } else if (url == merge_session_gurl_) {
(source && source->GetOriginalURL() == merge_session_gurl_)) {
// MergeSession may redirect, so check the original URL of the fetcher.
OnMergeSessionFetched(data, status, response_code); OnMergeSessionFetched(data, status, response_code);
} else if (url == uberauth_token_gurl_) { } else if (url == uberauth_token_gurl_) {
OnUberAuthTokenFetch(data, status, response_code); OnUberAuthTokenFetch(data, status, response_code);
......
...@@ -30,7 +30,6 @@ class GaiaAuthFetcherTest; ...@@ -30,7 +30,6 @@ class GaiaAuthFetcherTest;
namespace net { namespace net {
class URLRequestContextGetter; class URLRequestContextGetter;
class URLRequestStatus; class URLRequestStatus;
typedef std::vector<std::string> ResponseCookies;
} }
class GaiaAuthFetcher : public content::URLFetcherDelegate { class GaiaAuthFetcher : public content::URLFetcherDelegate {
...@@ -89,7 +88,8 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -89,7 +88,8 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
void StartMergeSession(const std::string& auth_token); void StartMergeSession(const std::string& auth_token);
// Start a request to get an uber-auth token. The given |access_token| must // Start a request to get an uber-auth token. The given |access_token| must
// be an OAuth2 valid access token. // be an OAuth2 valid access token. If |access_token| is an empty string,
// then the cookie jar is used with the request.
void StartUberAuthTokenFetch(const std::string& access_token); void StartUberAuthTokenFetch(const std::string& access_token);
// Implementation of content::URLFetcherDelegate // Implementation of content::URLFetcherDelegate
...@@ -182,7 +182,8 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -182,7 +182,8 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
const net::URLRequestStatus& status, const net::URLRequestStatus& status,
int response_code); int response_code);
void OnTokenAuthFetched(const std::string& data, void OnTokenAuthFetched(const net::ResponseCookies& cookies,
const std::string& data,
const net::URLRequestStatus& status, const net::URLRequestStatus& status,
int response_code); int response_code);
...@@ -259,13 +260,18 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -259,13 +260,18 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
void StartOAuth2TokenPairFetch(const std::string& auth_code); void StartOAuth2TokenPairFetch(const std::string& auth_code);
// Create a fetcher useable for making any Gaia request. // Create a fetcher usable for making any Gaia request. |body| is used
// as the body of the POST request sent to GAIA. Any strings listed in
// |headers| are added as extra HTTP headers in the request.
//
// |load_flags| are passed to directly to content::URLFetcher::Create() when
// creating the URL fetcher.
static content::URLFetcher* CreateGaiaFetcher( static content::URLFetcher* CreateGaiaFetcher(
net::URLRequestContextGetter* getter, net::URLRequestContextGetter* getter,
const std::string& body, const std::string& body,
const std::string& headers, const std::string& headers,
const GURL& gaia_gurl, const GURL& gaia_gurl,
bool use_cookies, int load_flags,
content::URLFetcherDelegate* delegate); content::URLFetcherDelegate* delegate);
// From a URLFetcher result, generate an appropriate error. // From a URLFetcher result, generate an appropriate error.
......
...@@ -130,9 +130,9 @@ class GaiaAuthFetcherTest : public testing::Test { ...@@ -130,9 +130,9 @@ class GaiaAuthFetcherTest : public testing::Test {
std::string out_token; std::string out_token;
GaiaAuthFetcher::ParseClientLoginResponse(data, GaiaAuthFetcher::ParseClientLoginResponse(data,
&out_sid, &out_sid,
&out_lsid, &out_lsid,
&out_token); &out_token);
EXPECT_EQ(lsid, out_lsid); EXPECT_EQ(lsid, out_lsid);
EXPECT_EQ(sid, out_sid); EXPECT_EQ(sid, out_sid);
EXPECT_EQ(token, out_token); EXPECT_EQ(token, out_token);
...@@ -149,10 +149,10 @@ class GaiaAuthFetcherTest : public testing::Test { ...@@ -149,10 +149,10 @@ class GaiaAuthFetcherTest : public testing::Test {
std::string out_captcha_token; std::string out_captcha_token;
GaiaAuthFetcher::ParseClientLoginFailure(data, GaiaAuthFetcher::ParseClientLoginFailure(data,
&out_error, &out_error,
&out_error_url, &out_error_url,
&out_captcha_url, &out_captcha_url,
&out_captcha_token); &out_captcha_token);
EXPECT_EQ(error, out_error); EXPECT_EQ(error, out_error);
EXPECT_EQ(error_url, out_error_url); EXPECT_EQ(error_url, out_error_url);
EXPECT_EQ(captcha_url, out_captcha_url); EXPECT_EQ(captcha_url, out_captcha_url);
...@@ -184,7 +184,8 @@ class MockGaiaConsumer : public GaiaAuthConsumer { ...@@ -184,7 +184,8 @@ class MockGaiaConsumer : public GaiaAuthConsumer {
void(const std::string& refresh_token, void(const std::string& refresh_token,
const std::string& access_token, const std::string& access_token,
int expires_in_secs)); int expires_in_secs));
MOCK_METHOD1(OnTokenAuthSuccess, void(const std::string& data)); MOCK_METHOD2(OnTokenAuthSuccess,
void(const net::ResponseCookies&, const std::string& data));
MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data)); MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
MOCK_METHOD1(OnUberAuthTokenSuccess, void(const std::string& data)); MOCK_METHOD1(OnUberAuthTokenSuccess, void(const std::string& data));
MOCK_METHOD1(OnClientLoginFailure, MOCK_METHOD1(OnClientLoginFailure,
...@@ -594,6 +595,10 @@ TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) { ...@@ -594,6 +595,10 @@ TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) {
GaiaAuthFetcher auth(&consumer, std::string(), GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext()); profile_.GetRequestContext());
auth.StartOAuthLoginTokenFetch("lso_token"); auth.StartOAuthLoginTokenFetch("lso_token");
TestURLFetcher* fetcher = factory.GetFetcherByID(0);
EXPECT_TRUE(NULL != fetcher);
EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES,
fetcher->GetLoadFlags());
net::ResponseCookies cookies; net::ResponseCookies cookies;
cookies.push_back(kGetAuthCodeValidCookie); cookies.push_back(kGetAuthCodeValidCookie);
...@@ -614,6 +619,18 @@ TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) { ...@@ -614,6 +619,18 @@ TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) {
EXPECT_FALSE(auth.HasPendingFetch()); EXPECT_FALSE(auth.HasPendingFetch());
} }
TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithEmptyToken) {
MockGaiaConsumer consumer;
TestingProfile profile;
TestURLFetcherFactory factory;
GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.StartOAuthLoginTokenFetch("");
TestURLFetcher* fetcher = factory.GetFetcherByID(0);
EXPECT_TRUE(NULL != fetcher);
EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
}
TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) { TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) {
MockGaiaConsumer consumer; MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnOAuthLoginTokenFailure(_)) EXPECT_CALL(consumer, OnOAuthLoginTokenFailure(_))
...@@ -670,7 +687,8 @@ TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) { ...@@ -670,7 +687,8 @@ TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) {
TEST_F(GaiaAuthFetcherTest, TokenAuthSuccess) { TEST_F(GaiaAuthFetcherTest, TokenAuthSuccess) {
MockGaiaConsumer consumer; MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnTokenAuthSuccess("<html></html>")) net::ResponseCookies cookies;
EXPECT_CALL(consumer, OnTokenAuthSuccess(cookies, "<html></html>"))
.Times(1); .Times(1);
TestingProfile profile; TestingProfile profile;
......
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