Commit 8c181fd4 authored by abodenha@chromium.org's avatar abodenha@chromium.org

Revert 111270 - Part 1 of work to do user sign in based on OAuth2:

- Add a couple of more flow methods to GaiaAuthFetcher.
- Add a new fetcher class to get a new access token from refresh token.
- Full set o tests.
Review URL: http://codereview.chromium.org/8632005

TBR=munjal@chromium.org
Review URL: http://codereview.chromium.org/8669010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111277 0039d316-1c4b-4281-b951-d872f2087c98
parent c926f86c
...@@ -375,9 +375,6 @@ ...@@ -375,9 +375,6 @@
'common/net/gaia/google_service_auth_error.h', 'common/net/gaia/google_service_auth_error.h',
'common/net/gaia/oauth_request_signer.cc', 'common/net/gaia/oauth_request_signer.cc',
'common/net/gaia/oauth_request_signer.h', 'common/net/gaia/oauth_request_signer.h',
'common/net/gaia/oauth2_access_token_consumer.h',
'common/net/gaia/oauth2_access_token_fetcher.cc',
'common/net/gaia/oauth2_access_token_fetcher.h',
'common/net/x509_certificate_model.cc', 'common/net/x509_certificate_model.cc',
'common/net/x509_certificate_model_nss.cc', 'common/net/x509_certificate_model_nss.cc',
'common/net/x509_certificate_model_openssl.cc', 'common/net/x509_certificate_model_openssl.cc',
......
...@@ -1972,7 +1972,6 @@ ...@@ -1972,7 +1972,6 @@
'common/net/gaia/gaia_oauth_client_unittest.cc', 'common/net/gaia/gaia_oauth_client_unittest.cc',
'common/net/gaia/google_service_auth_error_unittest.cc', 'common/net/gaia/google_service_auth_error_unittest.cc',
'common/net/gaia/oauth_request_signer_unittest.cc', 'common/net/gaia/oauth_request_signer_unittest.cc',
'common/net/gaia/oauth2_access_token_fetcher_unittest.cc',
'common/random_unittest.cc', 'common/random_unittest.cc',
'common/service_process_util_unittest.cc', 'common/service_process_util_unittest.cc',
'common/string_ordinal_unittest.cc', 'common/string_ordinal_unittest.cc',
......
...@@ -42,11 +42,6 @@ class GaiaAuthConsumer { ...@@ -42,11 +42,6 @@ class GaiaAuthConsumer {
virtual void OnIssueAuthTokenFailure(const std::string& service, virtual void OnIssueAuthTokenFailure(const std::string& service,
const GoogleServiceAuthError& error) {} const GoogleServiceAuthError& error) {}
virtual void OnOAuthLoginTokenSuccess(const std::string& refresh_token,
const std::string& access_token,
int expires_in_secs) {}
virtual void OnOAuthLoginTokenFailure(const GoogleServiceAuthError& error) {}
virtual void OnGetUserInfoSuccess(const std::string& key, virtual void OnGetUserInfoSuccess(const std::string& key,
const std::string& value) {} const std::string& value) {}
virtual void OnGetUserInfoKeyNotFound(const std::string& key) {} virtual void OnGetUserInfoKeyNotFound(const std::string& key) {}
......
...@@ -4,16 +4,13 @@ ...@@ -4,16 +4,13 @@
#include "chrome/common/net/gaia/gaia_auth_fetcher.h" #include "chrome/common/net/gaia/gaia_auth_fetcher.h"
#include <algorithm>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "base/json/json_reader.h"
#include "base/string_split.h" #include "base/string_split.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/stringprintf.h" #include "base/stringprintf.h"
#include "base/values.h"
#include "chrome/common/net/gaia/gaia_auth_consumer.h" #include "chrome/common/net/gaia/gaia_auth_consumer.h"
#include "chrome/common/net/gaia/gaia_constants.h" #include "chrome/common/net/gaia/gaia_constants.h"
#include "chrome/common/net/gaia/gaia_urls.h" #include "chrome/common/net/gaia/gaia_urls.h"
...@@ -25,13 +22,6 @@ ...@@ -25,13 +22,6 @@
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h" #include "net/url_request/url_request_status.h"
namespace {
static bool CookiePartsContains(const std::vector<std::string>& parts,
const char* part) {
return std::find(parts.begin(), parts.end(), part) != parts.end();
}
} // namespace
// TODO(chron): Add sourceless version of this formatter. // TODO(chron): Add sourceless version of this formatter.
// static // static
const char GaiaAuthFetcher::kClientLoginFormat[] = const char GaiaAuthFetcher::kClientLoginFormat[] =
...@@ -58,16 +48,6 @@ const char GaiaAuthFetcher::kIssueAuthTokenFormat[] = ...@@ -58,16 +48,6 @@ const char GaiaAuthFetcher::kIssueAuthTokenFormat[] =
"service=%s&" "service=%s&"
"Session=%s"; "Session=%s";
// static // static
const char GaiaAuthFetcher::kClientLoginToOAuth2BodyFormat[] =
"scope=%s&client_id=%s";
// static
const char GaiaAuthFetcher::kOAuth2CodeToTokenPairBodyFormat[] =
"scope=%s&"
"grant_type=authorization_code&"
"client_id=%s&"
"client_secret=%s&"
"code=%s";
// static
const char GaiaAuthFetcher::kGetUserInfoFormat[] = const char GaiaAuthFetcher::kGetUserInfoFormat[] =
"LSID=%s"; "LSID=%s";
// static // static
...@@ -120,27 +100,6 @@ const char GaiaAuthFetcher::kAccountTypeGoogle[] = ...@@ -120,27 +100,6 @@ const char GaiaAuthFetcher::kAccountTypeGoogle[] =
// static // static
const char GaiaAuthFetcher::kSecondFactor[] = "Info=InvalidSecondFactor"; const char GaiaAuthFetcher::kSecondFactor[] = "Info=InvalidSecondFactor";
// static
const char GaiaAuthFetcher::kAuthHeaderFormat[] =
"Authorization: GoogleLogin auth=%s";
// static
const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartSecure[] = "Secure";
// static
const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartHttpOnly[] =
"HttpOnly";
// static
const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefix[] =
"oauth_code=";
// static
const int GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefixLength =
arraysize(GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefix) - 1;
// static
const char GaiaAuthFetcher::kOAuth2RefreshTokenKey[] = "refresh_token";
// static
const char GaiaAuthFetcher::kOAuth2AccessTokenKey[] = "access_token";
// static
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)
...@@ -149,9 +108,6 @@ GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, ...@@ -149,9 +108,6 @@ GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer,
source_(source), source_(source),
client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()),
issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()),
client_login_to_oauth2_gurl_(
GaiaUrls::GetInstance()->client_login_to_oauth2_url()),
oauth2_token_gurl_(GaiaUrls::GetInstance()->oauth2_token_url()),
get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()),
token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()),
merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()),
...@@ -172,9 +128,8 @@ void GaiaAuthFetcher::CancelRequest() { ...@@ -172,9 +128,8 @@ void GaiaAuthFetcher::CancelRequest() {
content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher(
net::URLRequestContextGetter* getter, net::URLRequestContextGetter* getter,
const std::string& body, const std::string& body,
const std::string& headers,
const GURL& gaia_gurl, const GURL& gaia_gurl,
bool use_cookies, bool send_cookies,
content::URLFetcherDelegate* delegate) { content::URLFetcherDelegate* delegate) {
content::URLFetcher* to_return = content::URLFetcher::Create( content::URLFetcher* to_return = content::URLFetcher::Create(
0, gaia_gurl, content::URLFetcher::POST, delegate); 0, gaia_gurl, content::URLFetcher::POST, delegate);
...@@ -186,12 +141,8 @@ content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( ...@@ -186,12 +141,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) { if (!send_cookies)
to_return->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | to_return->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES);
net::LOAD_DO_NOT_SAVE_COOKIES);
}
if (!headers.empty())
to_return->SetExtraRequestHeaders(headers);
return to_return; return to_return;
} }
...@@ -257,34 +208,6 @@ std::string GaiaAuthFetcher::MakeIssueAuthTokenBody( ...@@ -257,34 +208,6 @@ std::string GaiaAuthFetcher::MakeIssueAuthTokenBody(
session ? "true" : "false"); session ? "true" : "false");
} }
// static
std::string GaiaAuthFetcher::MakeGetAuthCodeBody() {
std::string encoded_scope = net::EscapeUrlEncodedData(
GaiaUrls::GetInstance()->oauth1_login_scope(), true);
std::string encoded_client_id = net::EscapeUrlEncodedData(
GaiaUrls::GetInstance()->oauth2_chrome_client_id(), true);
return StringPrintf(kClientLoginToOAuth2BodyFormat,
encoded_scope.c_str(),
encoded_client_id.c_str());
}
// static
std::string GaiaAuthFetcher::MakeGetTokenPairBody(
const std::string& auth_code) {
std::string encoded_scope = net::EscapeUrlEncodedData(
GaiaUrls::GetInstance()->oauth1_login_scope(), true);
std::string encoded_client_id = net::EscapeUrlEncodedData(
GaiaUrls::GetInstance()->oauth2_chrome_client_id(), true);
std::string encoded_client_secret = net::EscapeUrlEncodedData(
GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), true);
std::string encoded_auth_code = net::EscapeUrlEncodedData(auth_code, true);
return StringPrintf(kOAuth2CodeToTokenPairBodyFormat,
encoded_scope.c_str(),
encoded_client_id.c_str(),
encoded_client_secret.c_str(),
encoded_auth_code.c_str());
}
// static // static
std::string GaiaAuthFetcher::MakeGetUserInfoBody(const std::string& lsid) { std::string GaiaAuthFetcher::MakeGetUserInfoBody(const std::string& lsid) {
std::string encoded_lsid = net::EscapeUrlEncodedData(lsid, true); std::string encoded_lsid = net::EscapeUrlEncodedData(lsid, true);
...@@ -320,12 +243,6 @@ std::string GaiaAuthFetcher::MakeMergeSessionBody( ...@@ -320,12 +243,6 @@ std::string GaiaAuthFetcher::MakeMergeSessionBody(
encoded_source.c_str()); encoded_source.c_str());
} }
// static
std::string GaiaAuthFetcher::MakeGetAuthCodeHeader(
const std::string& auth_token) {
return StringPrintf(kAuthHeaderFormat, auth_token.c_str());
}
// Helper method that extracts tokens from a successful reply. // Helper method that extracts tokens from a successful reply.
// static // static
void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data,
...@@ -376,72 +293,6 @@ void GaiaAuthFetcher::ParseClientLoginFailure(const std::string& data, ...@@ -376,72 +293,6 @@ void GaiaAuthFetcher::ParseClientLoginFailure(const std::string& data,
} }
} }
// static
bool GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
const net::ResponseCookies& cookies,
std::string* auth_code) {
DCHECK(auth_code);
net::ResponseCookies::const_iterator iter;
for (iter = cookies.begin(); iter != cookies.end(); ++iter) {
if (ParseClientLoginToOAuth2Cookie(*iter, auth_code))
return true;
}
return false;
}
// static
bool GaiaAuthFetcher::ParseOAuth2TokenPairResponse(const std::string& data,
std::string* refresh_token,
std::string* access_token,
int* expires_in_secs) {
DCHECK(refresh_token);
DCHECK(access_token);
base::JSONReader reader;
scoped_ptr<base::Value> value(reader.Read(data, false));
if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY)
return false;
DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
std::string rt;
std::string at;
int exp;
if (!dict->GetStringWithoutPathExpansion(kOAuth2RefreshTokenKey, &rt) ||
!dict->GetStringWithoutPathExpansion(kOAuth2AccessTokenKey, &at) ||
!dict->GetIntegerWithoutPathExpansion(kOAuth2ExpiresInKey, &exp)) {
return false;
}
refresh_token->assign(rt);
access_token->assign(at);
*expires_in_secs = exp;
return true;
}
// static
bool GaiaAuthFetcher::ParseClientLoginToOAuth2Cookie(const std::string& cookie,
std::string* auth_code) {
std::vector<std::string> parts;
base::SplitString(cookie, ';', &parts);
// Per documentation, the cookie should have Secure and HttpOnly.
if (!CookiePartsContains(parts, kClientLoginToOAuth2CookiePartSecure) ||
!CookiePartsContains(parts, kClientLoginToOAuth2CookiePartHttpOnly)) {
return false;
}
std::vector<std::string>::const_iterator iter;
for (iter = parts.begin(); iter != parts.end(); ++iter) {
const std::string& part = *iter;
if (StartsWithASCII(
part, kClientLoginToOAuth2CookiePartCodePrefix, false)) {
auth_code->assign(part.substr(
kClientLoginToOAuth2CookiePartCodePrefixLength));
return true;
}
}
return false;
}
void GaiaAuthFetcher::StartClientLogin( void GaiaAuthFetcher::StartClientLogin(
const std::string& username, const std::string& username,
const std::string& password, const std::string& password,
...@@ -466,7 +317,6 @@ void GaiaAuthFetcher::StartClientLogin( ...@@ -466,7 +317,6 @@ void GaiaAuthFetcher::StartClientLogin(
allow_hosted_accounts); allow_hosted_accounts);
fetcher_.reset(CreateGaiaFetcher(getter_, fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_, request_body_,
"",
client_login_gurl_, client_login_gurl_,
false, false,
this)); this));
...@@ -484,7 +334,6 @@ void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, ...@@ -484,7 +334,6 @@ void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid,
request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); request_body_ = MakeIssueAuthTokenBody(sid, lsid, service);
fetcher_.reset(CreateGaiaFetcher(getter_, fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_, request_body_,
"",
issue_auth_token_gurl_, issue_auth_token_gurl_,
false, false,
this)); this));
...@@ -492,22 +341,6 @@ void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, ...@@ -492,22 +341,6 @@ void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid,
fetcher_->Start(); fetcher_->Start();
} }
void GaiaAuthFetcher::StartOAuthLoginTokenFetch(
const std::string& auth_token) {
DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
DVLOG(1) << "Starting OAuth login token fetch";
request_body_ = MakeGetAuthCodeBody();
fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_,
MakeGetAuthCodeHeader(auth_token),
client_login_to_oauth2_gurl_,
false,
this));
fetch_pending_ = true;
fetcher_->Start();
}
void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid,
const std::string& info_key) { const std::string& info_key) {
DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
...@@ -516,7 +349,6 @@ void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, ...@@ -516,7 +349,6 @@ void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid,
request_body_ = MakeGetUserInfoBody(lsid); request_body_ = MakeGetUserInfoBody(lsid);
fetcher_.reset(CreateGaiaFetcher(getter_, fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_, request_body_,
"",
get_user_info_gurl_, get_user_info_gurl_,
false, false,
this)); this));
...@@ -537,7 +369,6 @@ void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { ...@@ -537,7 +369,6 @@ void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) {
request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_); request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_);
fetcher_.reset(CreateGaiaFetcher(getter_, fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_, request_body_,
"",
token_auth_gurl_, token_auth_gurl_,
false, false,
this)); this));
...@@ -562,7 +393,6 @@ void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { ...@@ -562,7 +393,6 @@ void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) {
request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_); request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_);
fetcher_.reset(CreateGaiaFetcher(getter_, fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_, request_body_,
"",
merge_session_gurl_, merge_session_gurl_,
true, true,
this)); this));
...@@ -706,61 +536,6 @@ void GaiaAuthFetcher::OnIssueAuthTokenFetched( ...@@ -706,61 +536,6 @@ void GaiaAuthFetcher::OnIssueAuthTokenFetched(
} }
} }
void GaiaAuthFetcher::OnClientLoginToOAuth2Fetched(
const std::string& data,
const net::ResponseCookies& cookies,
const net::URLRequestStatus& status,
int response_code) {
if (status.is_success() && response_code == RC_REQUEST_OK) {
std::string auth_code;
if (!ParseClientLoginToOAuth2Response(cookies, &auth_code)) {
consumer_->OnOAuthLoginTokenFailure(GoogleServiceAuthError(
GoogleServiceAuthError::UNEXPECTED_RESPONSE));
} else {
// Start GetTokenPair.
StartOAuth2TokenPairFetch(auth_code);
}
} else {
consumer_->OnOAuthLoginTokenFailure(GenerateAuthError(data, status));
}
}
void GaiaAuthFetcher::StartOAuth2TokenPairFetch(const std::string& auth_code) {
DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
DVLOG(1) << "Starting OAuth token pair fetch";
request_body_ = MakeGetTokenPairBody(auth_code);
fetcher_.reset(CreateGaiaFetcher(getter_,
request_body_,
"",
oauth2_token_gurl_,
false,
this));
fetch_pending_ = true;
fetcher_->Start();
}
void GaiaAuthFetcher::OnOAuth2TokenPairFetched(
const std::string& data,
const net::URLRequestStatus& status,
int response_code) {
if (status.is_success() && response_code == RC_REQUEST_OK) {
std::string refresh_token;
std::string access_token;
int expires_in_secs;
if (ParseOAuth2TokenPairResponse(
data, &refresh_token, &access_token, &expires_in_secs)) {
consumer_->OnOAuthLoginTokenSuccess(
refresh_token, access_token, expires_in_secs);
} else {
consumer_->OnOAuthLoginTokenFailure(GoogleServiceAuthError(
GoogleServiceAuthError::UNEXPECTED_RESPONSE));
}
} else {
consumer_->OnOAuthLoginTokenFailure(GenerateAuthError(data, status));
}
}
void GaiaAuthFetcher::OnGetUserInfoFetched( void GaiaAuthFetcher::OnGetUserInfoFetched(
const std::string& data, const std::string& data,
const net::URLRequestStatus& status, const net::URLRequestStatus& status,
...@@ -816,11 +591,6 @@ void GaiaAuthFetcher::OnURLFetchComplete(const content::URLFetcher* source) { ...@@ -816,11 +591,6 @@ void GaiaAuthFetcher::OnURLFetchComplete(const content::URLFetcher* source) {
OnClientLoginFetched(data, status, response_code); OnClientLoginFetched(data, status, response_code);
} else if (url == issue_auth_token_gurl_) { } else if (url == issue_auth_token_gurl_) {
OnIssueAuthTokenFetched(data, status, response_code); OnIssueAuthTokenFetched(data, status, response_code);
} else if (url == client_login_to_oauth2_gurl_) {
OnClientLoginToOAuth2Fetched(
data, source->GetCookies(), status, response_code);
} else if (url == oauth2_token_gurl_) {
OnOAuth2TokenPairFetched(data, status, response_code);
} 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_) {
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#pragma once #pragma once
#include <string> #include <string>
#include <vector>
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
...@@ -30,7 +29,6 @@ class GaiaAuthFetcherTest; ...@@ -30,7 +29,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 {
...@@ -68,12 +66,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -68,12 +66,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
const std::string& lsid, const std::string& lsid,
const char* const service); const char* const service);
// Start fetching OAuth login scoped token from the given ClientLogin token
// for "lso" service.
// Either OnOAuthLoginTokenSuccess or OnOAuthLoginTokenFailure method will be
// called on the consumer with results.
void StartOAuthLoginTokenFetch(const std::string& auth_token);
// Start a request to get a particular key from user info. // Start a request to get a particular key from user info.
// GaiaAuthConsumer will be called back on the same thread when // GaiaAuthConsumer will be called back on the same thread when
// results come back. // results come back.
...@@ -117,10 +109,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -117,10 +109,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
static const char kClientLoginCaptchaFormat[]; static const char kClientLoginCaptchaFormat[];
// The format of the POST body for IssueAuthToken. // The format of the POST body for IssueAuthToken.
static const char kIssueAuthTokenFormat[]; static const char kIssueAuthTokenFormat[];
// The format of the POST body to get OAuth2 auth code from auth token.
static const char kClientLoginToOAuth2BodyFormat[];
// The format of the POST body to get OAuth2 token pair from auth code.
static const char kOAuth2CodeToTokenPairBodyFormat[];
// The format of the POST body for GetUserInfo. // The format of the POST body for GetUserInfo.
static const char kGetUserInfoFormat[]; static const char kGetUserInfoFormat[];
// The format of the POST body for TokenAuth. // The format of the POST body for TokenAuth.
...@@ -144,16 +132,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -144,16 +132,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
static const char kCaptchaUrlParam[]; static const char kCaptchaUrlParam[];
static const char kCaptchaTokenParam[]; static const char kCaptchaTokenParam[];
// Constants for request/response for OAuth2 requests.
static const char kAuthHeaderFormat[];
static const char kClientLoginToOAuth2CookiePartSecure[];
static const char kClientLoginToOAuth2CookiePartHttpOnly[];
static const char kClientLoginToOAuth2CookiePartCodePrefix[];
static const int kClientLoginToOAuth2CookiePartCodePrefixLength;
static const char kOAuth2RefreshTokenKey[];
static const char kOAuth2AccessTokenKey[];
static const char kOAuth2ExpiresInKey[];
// Process the results of a ClientLogin fetch. // Process the results of a ClientLogin fetch.
void OnClientLoginFetched(const std::string& data, void OnClientLoginFetched(const std::string& data,
const net::URLRequestStatus& status, const net::URLRequestStatus& status,
...@@ -163,15 +141,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -163,15 +141,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
const net::URLRequestStatus& status, const net::URLRequestStatus& status,
int response_code); int response_code);
void OnClientLoginToOAuth2Fetched(const std::string& data,
const net::ResponseCookies& cookies,
const net::URLRequestStatus& status,
int response_code);
void OnOAuth2TokenPairFetched(const std::string& data,
const net::URLRequestStatus& status,
int response_code);
void OnGetUserInfoFetched(const std::string& data, void OnGetUserInfoFetched(const std::string& data,
const net::URLRequestStatus& status, const net::URLRequestStatus& status,
int response_code); int response_code);
...@@ -196,20 +165,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -196,20 +165,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
std::string* captcha_url, std::string* captcha_url,
std::string* captcha_token); std::string* captcha_token);
// Parse ClientLogin to OAuth2 response.
static bool ParseClientLoginToOAuth2Response(
const net::ResponseCookies& cookies,
std::string* auth_code);
// Parse OAuth2 token pairresponse.
static bool ParseOAuth2TokenPairResponse(const std::string& data,
std::string* refresh_token,
std::string* access_token,
int* expires_in_secs);
static bool ParseClientLoginToOAuth2Cookie(const std::string& cookie,
std::string* auth_code);
// Is this a special case Gaia error for TwoFactor auth? // Is this a special case Gaia error for TwoFactor auth?
static bool IsSecondFactorSuccess(const std::string& alleged_error); static bool IsSecondFactorSuccess(const std::string& alleged_error);
...@@ -227,10 +182,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -227,10 +182,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
static std::string MakeIssueAuthTokenBody(const std::string& sid, static std::string MakeIssueAuthTokenBody(const std::string& sid,
const std::string& lsid, const std::string& lsid,
const char* const service); const char* const service);
// Create body to get OAuth2 auth code.
static std::string MakeGetAuthCodeBody();
// Given auth code, create body to get OAuth2 token pair.
static std::string MakeGetTokenPairBody(const std::string& auth_code);
// Supply the lsid returned from ClientLogin in order to fetch // Supply the lsid returned from ClientLogin in order to fetch
// user information. // user information.
static std::string MakeGetUserInfoBody(const std::string& lsid); static std::string MakeGetUserInfoBody(const std::string& lsid);
...@@ -245,17 +196,12 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -245,17 +196,12 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
const std::string& continue_url, const std::string& continue_url,
const std::string& source); const std::string& source);
static std::string MakeGetAuthCodeHeader(const std::string& auth_token);
void StartOAuth2TokenPairFetch(const std::string& auth_code);
// Create a fetcher useable for making any Gaia request. // Create a fetcher useable for making any Gaia request.
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 GURL& gaia_gurl, const GURL& gaia_gurl,
bool use_cookies, bool send_cookies,
content::URLFetcherDelegate* delegate); content::URLFetcherDelegate* delegate);
// From a URLFetcher result, generate an appropriate error. // From a URLFetcher result, generate an appropriate error.
...@@ -271,8 +217,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -271,8 +217,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
std::string source_; std::string source_;
const GURL client_login_gurl_; const GURL client_login_gurl_;
const GURL issue_auth_token_gurl_; const GURL issue_auth_token_gurl_;
const GURL client_login_to_oauth2_gurl_;
const GURL oauth2_token_gurl_;
const GURL get_user_info_gurl_; const GURL get_user_info_gurl_;
const GURL token_auth_gurl_; const GURL token_auth_gurl_;
const GURL merge_session_gurl_; const GURL merge_session_gurl_;
...@@ -294,9 +238,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate { ...@@ -294,9 +238,6 @@ class GaiaAuthFetcher : public content::URLFetcherDelegate {
FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckNormalErrorCode); FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckNormalErrorCode);
FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckTwoFactorResponse); FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckTwoFactorResponse);
FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, LoginNetFailure); FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, LoginNetFailure);
FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest,
ParseClientLoginToOAuth2Response);
FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ParseOAuth2TokenPairResponse);
DISALLOW_COPY_AND_ASSIGN(GaiaAuthFetcher); DISALLOW_COPY_AND_ASSIGN(GaiaAuthFetcher);
}; };
......
...@@ -28,42 +28,6 @@ ...@@ -28,42 +28,6 @@
using ::testing::_; using ::testing::_;
namespace {
static const char kGetAuthCodeValidCookie[] =
"oauth_code=test-code; Path=/test; Secure; HttpOnly";
static const char kGetAuthCodeCookieNoSecure[] =
"oauth_code=test-code; Path=/test; HttpOnly";
static const char kGetAuthCodeCookieNoHttpOnly[] =
"oauth_code=test-code; Path=/test; Secure";
static const char kGetAuthCodeCookieNoOAuthCode[] =
"Path=/test; Secure; HttpOnly";
static const char kGetTokenPairValidResponse[] =
"{"
" \"refresh_token\": \"rt1\","
" \"access_token\": \"at1\","
" \"expires_in\": 3600,"
" \"token_type\": \"Bearer\""
"}";
static const char kGetTokenPairResponseNoRefreshToken[] =
"{"
" \"access_token\": \"at1\","
" \"expires_in\": 3600,"
" \"token_type\": \"Bearer\""
"}";
static const char kGetTokenPairResponseNoAccessToken[] =
"{"
" \"refresh_token\": \"rt1\","
" \"expires_in\": 3600,"
" \"token_type\": \"Bearer\""
"}";
static const char kGetTokenPairResponseNoExpiresIn[] =
"{"
" \"refresh_token\": \"rt1\","
" \"access_token\": \"at1\","
" \"token_type\": \"Bearer\""
"}";
} // namespace
MockFetcher::MockFetcher(bool success, MockFetcher::MockFetcher(bool success,
const GURL& url, const GURL& url,
const std::string& results, const std::string& results,
...@@ -112,9 +76,6 @@ class GaiaAuthFetcherTest : public testing::Test { ...@@ -112,9 +76,6 @@ class GaiaAuthFetcherTest : public testing::Test {
: client_login_source_(GaiaUrls::GetInstance()->client_login_url()), : client_login_source_(GaiaUrls::GetInstance()->client_login_url()),
issue_auth_token_source_( issue_auth_token_source_(
GaiaUrls::GetInstance()->issue_auth_token_url()), GaiaUrls::GetInstance()->issue_auth_token_url()),
client_login_to_oauth2_source_(
GaiaUrls::GetInstance()->client_login_to_oauth2_url()),
oauth2_token_source_(GaiaUrls::GetInstance()->oauth2_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()) {} merge_session_source_(GaiaUrls::GetInstance()->merge_session_url()) {}
...@@ -159,8 +120,6 @@ class GaiaAuthFetcherTest : public testing::Test { ...@@ -159,8 +120,6 @@ class GaiaAuthFetcherTest : public testing::Test {
net::ResponseCookies cookies_; net::ResponseCookies cookies_;
GURL client_login_source_; GURL client_login_source_;
GURL issue_auth_token_source_; GURL issue_auth_token_source_;
GURL client_login_to_oauth2_source_;
GURL oauth2_token_source_;
GURL token_auth_source_; GURL token_auth_source_;
GURL merge_session_source_; GURL merge_session_source_;
TestingProfile profile_; TestingProfile profile_;
...@@ -176,18 +135,12 @@ class MockGaiaConsumer : public GaiaAuthConsumer { ...@@ -176,18 +135,12 @@ class MockGaiaConsumer : public GaiaAuthConsumer {
MOCK_METHOD1(OnClientLoginSuccess, void(const ClientLoginResult& result)); MOCK_METHOD1(OnClientLoginSuccess, void(const ClientLoginResult& result));
MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service, MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service,
const std::string& token)); const std::string& token));
MOCK_METHOD3(OnOAuthLoginTokenSuccess,
void(const std::string& refresh_token,
const std::string& access_token,
int expires_in_secs));
MOCK_METHOD1(OnTokenAuthSuccess, void(const std::string& data)); MOCK_METHOD1(OnTokenAuthSuccess, void(const std::string& data));
MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data)); MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
MOCK_METHOD1(OnClientLoginFailure, MOCK_METHOD1(OnClientLoginFailure,
void(const GoogleServiceAuthError& error)); void(const GoogleServiceAuthError& error));
MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service, MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service,
const GoogleServiceAuthError& error)); const GoogleServiceAuthError& error));
MOCK_METHOD1(OnOAuthLoginTokenFailure,
void(const GoogleServiceAuthError& error));
MOCK_METHOD1(OnTokenAuthFailure, void(const GoogleServiceAuthError& error)); MOCK_METHOD1(OnTokenAuthFailure, void(const GoogleServiceAuthError& error));
MOCK_METHOD1(OnMergeSessionFailure, void( MOCK_METHOD1(OnMergeSessionFailure, void(
const GoogleServiceAuthError& error)); const GoogleServiceAuthError& error));
...@@ -570,92 +523,6 @@ TEST_F(GaiaAuthFetcherTest, FullTokenFailure) { ...@@ -570,92 +523,6 @@ TEST_F(GaiaAuthFetcherTest, FullTokenFailure) {
EXPECT_FALSE(auth.HasPendingFetch()); EXPECT_FALSE(auth.HasPendingFetch());
} }
TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) {
MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnOAuthLoginTokenSuccess("rt1", "at1", 3600))
.Times(1);
TestingProfile profile;
TestURLFetcherFactory factory;
GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.StartOAuthLoginTokenFetch("lso_token");
net::ResponseCookies cookies;
cookies.push_back(kGetAuthCodeValidCookie);
EXPECT_TRUE(auth.HasPendingFetch());
MockFetcher mock_fetcher1(
client_login_to_oauth2_source_,
net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
RC_REQUEST_OK, cookies, "",
content::URLFetcher::POST, &auth);
auth.OnURLFetchComplete(&mock_fetcher1);
EXPECT_TRUE(auth.HasPendingFetch());
MockFetcher mock_fetcher2(
oauth2_token_source_,
net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
RC_REQUEST_OK, cookies_, kGetTokenPairValidResponse,
content::URLFetcher::POST, &auth);
auth.OnURLFetchComplete(&mock_fetcher2);
EXPECT_FALSE(auth.HasPendingFetch());
}
TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) {
MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnOAuthLoginTokenFailure(_))
.Times(1);
TestingProfile profile;
TestURLFetcherFactory factory;
GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.StartOAuthLoginTokenFetch("lso_token");
net::ResponseCookies cookies;
cookies.push_back(kGetAuthCodeCookieNoSecure);
EXPECT_TRUE(auth.HasPendingFetch());
MockFetcher mock_fetcher(
client_login_to_oauth2_source_,
net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
RC_REQUEST_OK, cookies, "",
content::URLFetcher::POST, &auth);
auth.OnURLFetchComplete(&mock_fetcher);
EXPECT_FALSE(auth.HasPendingFetch());
}
TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) {
MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnOAuthLoginTokenFailure(_))
.Times(1);
TestingProfile profile;
TestURLFetcherFactory factory;
GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.StartOAuthLoginTokenFetch("lso_token");
net::ResponseCookies cookies;
cookies.push_back(kGetAuthCodeValidCookie);
EXPECT_TRUE(auth.HasPendingFetch());
MockFetcher mock_fetcher1(
client_login_to_oauth2_source_,
net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
RC_REQUEST_OK, cookies, "",
content::URLFetcher::POST, &auth);
auth.OnURLFetchComplete(&mock_fetcher1);
EXPECT_TRUE(auth.HasPendingFetch());
MockFetcher mock_fetcher2(
oauth2_token_source_,
net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
RC_REQUEST_OK, cookies_, kGetTokenPairResponseNoRefreshToken,
content::URLFetcher::POST, &auth);
auth.OnURLFetchComplete(&mock_fetcher2);
EXPECT_FALSE(auth.HasPendingFetch());
}
TEST_F(GaiaAuthFetcherTest, TokenAuthSuccess) { TEST_F(GaiaAuthFetcherTest, TokenAuthSuccess) {
MockGaiaConsumer consumer; MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnTokenAuthSuccess("<html></html>")) EXPECT_CALL(consumer, OnTokenAuthSuccess("<html></html>"))
...@@ -772,95 +639,3 @@ TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) { ...@@ -772,95 +639,3 @@ TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) {
auth.OnURLFetchComplete(test_fetcher); auth.OnURLFetchComplete(test_fetcher);
EXPECT_FALSE(auth.HasPendingFetch()); EXPECT_FALSE(auth.HasPendingFetch());
} }
TEST_F(GaiaAuthFetcherTest, ParseClientLoginToOAuth2Response) {
{ // No cookies.
std::string auth_code;
net::ResponseCookies cookies;
EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
cookies, &auth_code));
EXPECT_EQ("", auth_code);
}
{ // Few cookies, nothing appropriate.
std::string auth_code;
net::ResponseCookies cookies;
cookies.push_back(kGetAuthCodeCookieNoSecure);
cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
cookies, &auth_code));
EXPECT_EQ("", auth_code);
}
{ // Few cookies, one of them is valid.
std::string auth_code;
net::ResponseCookies cookies;
cookies.push_back(kGetAuthCodeCookieNoSecure);
cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
cookies.push_back(kGetAuthCodeValidCookie);
EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
cookies, &auth_code));
EXPECT_EQ("test-code", auth_code);
}
{ // Single valid cookie (like in real responses).
std::string auth_code;
net::ResponseCookies cookies;
cookies.push_back(kGetAuthCodeValidCookie);
EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
cookies, &auth_code));
EXPECT_EQ("test-code", auth_code);
}
}
TEST_F(GaiaAuthFetcherTest, ParseOAuth2TokenPairResponse) {
{ // No data.
std::string rt;
std::string at;
int exp = -1;
EXPECT_FALSE(GaiaAuthFetcher::ParseOAuth2TokenPairResponse(
"", &rt, &at, &exp));
EXPECT_EQ("", rt);
EXPECT_EQ("", at);
EXPECT_EQ(-1, exp);
}
{ // No refresh token.
std::string rt;
std::string at;
int exp = -1;
EXPECT_FALSE(GaiaAuthFetcher::ParseOAuth2TokenPairResponse(
kGetTokenPairResponseNoRefreshToken, &rt, &at, &exp));
EXPECT_EQ("", rt);
EXPECT_EQ("", at);
EXPECT_EQ(-1, exp);
}
{ // No access token.
std::string rt;
std::string at;
int exp = -1;
EXPECT_FALSE(GaiaAuthFetcher::ParseOAuth2TokenPairResponse(
kGetTokenPairResponseNoAccessToken, &rt, &at, &exp));
EXPECT_EQ("", rt);
EXPECT_EQ("", at);
EXPECT_EQ(-1, exp);
}
{ // No expiration.
std::string rt;
std::string at;
int exp = -1;
EXPECT_FALSE(GaiaAuthFetcher::ParseOAuth2TokenPairResponse(
kGetTokenPairResponseNoExpiresIn, &rt, &at, &exp));
EXPECT_EQ("", rt);
EXPECT_EQ("", at);
EXPECT_EQ(-1, exp);
}
{ // Valid response.
std::string rt;
std::string at;
int exp = -1;
EXPECT_TRUE(GaiaAuthFetcher::ParseOAuth2TokenPairResponse(
kGetTokenPairValidResponse, &rt, &at, &exp));
EXPECT_EQ("rt1", rt);
EXPECT_EQ("at1", at);
EXPECT_EQ(3600, exp);
}
}
...@@ -44,10 +44,8 @@ const char kLSOService[] = "lso"; ...@@ -44,10 +44,8 @@ const char kLSOService[] = "lso";
// Used to mint uber auth tokens when needed. // Used to mint uber auth tokens when needed.
const char kGaiaSid[] = "sid"; const char kGaiaSid[] = "sid";
const char kGaiaLsid[] = "lsid"; const char kGaiaLsid[] = "lsid";
const char kGaiaOAuthToken[] = "oauthToken"; extern const char kGaiaOAuthToken[] = "oauthToken";
const char kGaiaOAuthSecret[] = "oauthSecret"; extern const char kGaiaOAuthSecret[] = "oauthSecret";
const char kGaiaOAuthDuration[] = "3600"; extern const char kGaiaOAuthDuration[] = "3600";
const char kGaiaOAuth2LoginRefreshToken[] = "oauth2LoginRefreshToken";
const char kGaiaOAuth2LoginAccessToken[] = "oauth2LoginAccessToken";
} // namespace GaiaConstants } // namespace GaiaConstants
...@@ -33,8 +33,6 @@ extern const char kGaiaLsid[]; ...@@ -33,8 +33,6 @@ extern const char kGaiaLsid[];
extern const char kGaiaOAuthToken[]; extern const char kGaiaOAuthToken[];
extern const char kGaiaOAuthSecret[]; extern const char kGaiaOAuthSecret[];
extern const char kGaiaOAuthDuration[]; extern const char kGaiaOAuthDuration[];
extern const char kGaiaOAuth2LoginRefreshToken[];
extern const char kGaiaOAuth2LoginAccessToken[];
} // namespace GaiaConstants } // namespace GaiaConstants
......
...@@ -24,20 +24,6 @@ const char kOAuthWrapBridgeUrlSuffix[] = "/accounts/OAuthWrapBridge"; ...@@ -24,20 +24,6 @@ const char kOAuthWrapBridgeUrlSuffix[] = "/accounts/OAuthWrapBridge";
const char kOAuth1LoginUrlSuffix[] = "/accounts/OAuthLogin"; const char kOAuth1LoginUrlSuffix[] = "/accounts/OAuthLogin";
const char kOAuthRevokeTokenUrlSuffix[] = "/accounts/AuthSubRevokeToken"; const char kOAuthRevokeTokenUrlSuffix[] = "/accounts/AuthSubRevokeToken";
// OAuth2 client id for Google Chrome which is registered as an
// installed application.
static const char kOAuth2ChromeClientId[] =
"77185425430.apps.googleusercontent.com";
// For an installed application, client secret is not really a secret since
// it is expected to be embeeded in the application.
// See documentation at
// http://code.google.com/apis/accounts/docs/OAuth2InstalledApp.html
static const char kOAuth2ChromeClientSecret[] =
"OTJgUOQcT7lO7GsGZq2G4IlT";
const char kClientLoginToOAuth2Url[] =
"https://accounts.google.com/o/oauth2/programmatic_auth";
const char kOAuth2TokenUrl[] =
"https://accounts.google.com/o/oauth2/token";
} // namespacce } // namespacce
GaiaUrls* GaiaUrls::GetInstance() { GaiaUrls* GaiaUrls::GetInstance() {
...@@ -75,11 +61,6 @@ GaiaUrls::GaiaUrls() { ...@@ -75,11 +61,6 @@ GaiaUrls::GaiaUrls() {
oauth_user_info_url_ = "https://www.googleapis.com/oauth2/v1/userinfo"; oauth_user_info_url_ = "https://www.googleapis.com/oauth2/v1/userinfo";
oauth_wrap_bridge_user_info_scope_ = oauth_wrap_bridge_user_info_scope_ =
"https://www.googleapis.com/auth/userinfo.email"; "https://www.googleapis.com/auth/userinfo.email";
oauth2_chrome_client_id_ = kOAuth2ChromeClientId;
oauth2_chrome_client_secret_ = kOAuth2ChromeClientSecret;
client_login_to_oauth2_url_ = kClientLoginToOAuth2Url;
oauth2_token_url_ = kOAuth2TokenUrl;
} }
GaiaUrls::~GaiaUrls() { GaiaUrls::~GaiaUrls() {
...@@ -144,19 +125,3 @@ const std::string& GaiaUrls::oauth1_login_scope() { ...@@ -144,19 +125,3 @@ const std::string& GaiaUrls::oauth1_login_scope() {
const std::string& GaiaUrls::oauth_wrap_bridge_user_info_scope() { const std::string& GaiaUrls::oauth_wrap_bridge_user_info_scope() {
return oauth_wrap_bridge_user_info_scope_; return oauth_wrap_bridge_user_info_scope_;
} }
const std::string& GaiaUrls::oauth2_chrome_client_id() {
return oauth2_chrome_client_id_;
}
const std::string& GaiaUrls::oauth2_chrome_client_secret() {
return oauth2_chrome_client_secret_;
}
const std::string& GaiaUrls::client_login_to_oauth2_url() {
return client_login_to_oauth2_url_;
}
const std::string& GaiaUrls::oauth2_token_url() {
return oauth2_token_url_;
}
...@@ -34,11 +34,6 @@ class GaiaUrls { ...@@ -34,11 +34,6 @@ class GaiaUrls {
const std::string& oauth1_login_scope(); const std::string& oauth1_login_scope();
const std::string& oauth_wrap_bridge_user_info_scope(); const std::string& oauth_wrap_bridge_user_info_scope();
const std::string& oauth2_chrome_client_id();
const std::string& oauth2_chrome_client_secret();
const std::string& client_login_to_oauth2_url();
const std::string& oauth2_token_url();
private: private:
GaiaUrls(); GaiaUrls();
~GaiaUrls(); ~GaiaUrls();
...@@ -63,11 +58,6 @@ class GaiaUrls { ...@@ -63,11 +58,6 @@ class GaiaUrls {
std::string oauth1_login_scope_; std::string oauth1_login_scope_;
std::string oauth_wrap_bridge_user_info_scope_; std::string oauth_wrap_bridge_user_info_scope_;
std::string oauth2_chrome_client_id_;
std::string oauth2_chrome_client_secret_;
std::string client_login_to_oauth2_url_;
std::string oauth2_token_url_;
DISALLOW_COPY_AND_ASSIGN(GaiaUrls); DISALLOW_COPY_AND_ASSIGN(GaiaUrls);
}; };
......
...@@ -78,9 +78,6 @@ class GoogleServiceAuthError { ...@@ -78,9 +78,6 @@ class GoogleServiceAuthError {
// The user has provided a HOSTED account, when this service requires // The user has provided a HOSTED account, when this service requires
// a GOOGLE account. // a GOOGLE account.
HOSTED_NOT_ALLOWED = 10, HOSTED_NOT_ALLOWED = 10,
// Response format was unexpected.
UNEXPECTED_RESPONSE = 11,
}; };
// Additional data for CAPTCHA_REQUIRED errors. // Additional data for CAPTCHA_REQUIRED errors.
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_COMMON_NET_GAIA_OAUTH2_ACCESS_TOKEN_CONSUMER_H_
#define CHROME_COMMON_NET_GAIA_OAUTH2_ACCESS_TOKEN_CONSUMER_H_
#pragma once
#include <string>
class GoogleServiceAuthError;
// An interface that defines the callbacks for consumers to which
// OAuth2AccessTokenFetcher can return results.
class OAuth2AccessTokenConsumer {
public:
virtual ~OAuth2AccessTokenConsumer() {}
virtual void OnGetTokenSuccess(const std::string& access_token) {}
virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) {}
};
#endif // CHROME_COMMON_NET_GAIA_OAUTH2_ACCESS_TOKEN_CONSUMER_H_
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/net/gaia/oauth2_access_token_fetcher.h"
#include <algorithm>
#include <string>
#include "base/json/json_reader.h"
#include "base/stringprintf.h"
#include "base/values.h"
#include "chrome/common/net/gaia/gaia_urls.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
#include "chrome/common/net/http_return.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h"
using content::URLFetcher;
using content::URLFetcherDelegate;
using net::ResponseCookies;
using net::URLRequestContextGetter;
using net::URLRequestStatus;
namespace {
static const char kGetAccessTokenBodyFormat[] =
"client_id=%s&"
"client_secret=%s"
"grant_type=refresh_token&"
"refresh_token=%s";
static const char kAccessTokenKey[] = "access_token";
static bool GetStringFromDictionary(const DictionaryValue* dict,
const std::string& key,
std::string* value) {
Value* json_value;
if (!dict->Get(key, &json_value))
return false;
if (json_value->GetType() != base::Value::TYPE_STRING)
return false;
StringValue* json_str_value = static_cast<StringValue*>(json_value);
json_str_value->GetAsString(value);
return true;
}
static GoogleServiceAuthError CreateAuthError(URLRequestStatus status) {
CHECK(!status.is_success());
if (status.status() == URLRequestStatus::CANCELED) {
return GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
} else {
DLOG(WARNING) << "Could not reach Google Accounts servers: errno "
<< status.error();
return GoogleServiceAuthError::FromConnectionError(status.error());
}
}
static URLFetcher* CreateFetcher(URLRequestContextGetter* getter,
const GURL& url,
const std::string& body,
URLFetcherDelegate* delegate) {
bool empty_body = body.empty();
URLFetcher* result = URLFetcher::Create(
0, url,
empty_body ? URLFetcher::GET : URLFetcher::POST,
delegate);
result->SetRequestContext(getter);
result->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES);
if (!empty_body)
result->SetUploadData("application/x-www-form-urlencoded", body);
return result;
}
} // namespace
OAuth2AccessTokenFetcher::OAuth2AccessTokenFetcher(
OAuth2AccessTokenConsumer* consumer,
URLRequestContextGetter* getter,
const std::string& source)
: consumer_(consumer),
getter_(getter),
source_(source),
state_(INITIAL) { }
OAuth2AccessTokenFetcher::~OAuth2AccessTokenFetcher() { }
void OAuth2AccessTokenFetcher::CancelRequest() {
fetcher_.reset();
}
void OAuth2AccessTokenFetcher::Start(const std::string& refresh_token) {
refresh_token_ = refresh_token;
StartGetAccessToken();
}
void OAuth2AccessTokenFetcher::StartGetAccessToken() {
CHECK_EQ(INITIAL, state_);
state_ = GET_ACCESS_TOKEN_STARTED;
fetcher_.reset(CreateFetcher(
getter_,
MakeGetAccessTokenUrl(),
MakeGetAccessTokenBody(refresh_token_),
this));
fetcher_->Start(); // OnURLFetchComplete will be called.
}
void OAuth2AccessTokenFetcher::EndGetAccessToken(const URLFetcher* source) {
CHECK_EQ(GET_ACCESS_TOKEN_STARTED, state_);
state_ = GET_ACCESS_TOKEN_DONE;
URLRequestStatus status = source->GetStatus();
if (!status.is_success()) {
ReportFailure(CreateAuthError(status));
return;
}
if (source->GetResponseCode() != RC_REQUEST_OK) {
ReportFailure(GoogleServiceAuthError(
GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
return;
}
// The request was successfully fetched and it returned OK.
// Parse out the access token.
std::string access_token;
if (!ParseGetAccessTokenResponse(source, &access_token)) {
ReportFailure(GoogleServiceAuthError(
GoogleServiceAuthError::UNEXPECTED_RESPONSE));
return;
}
ReportSuccess(access_token);
}
void OAuth2AccessTokenFetcher::ReportSuccess(const std::string& access_token) {
consumer_->OnGetTokenSuccess(access_token);
}
void OAuth2AccessTokenFetcher::ReportFailure(GoogleServiceAuthError error) {
state_ = ERROR_STATE;
consumer_->OnGetTokenFailure(error);
}
void OAuth2AccessTokenFetcher::OnURLFetchComplete(const URLFetcher* source) {
CHECK(source);
CHECK(state_ == GET_ACCESS_TOKEN_STARTED);
EndGetAccessToken(source);
}
// static
GURL OAuth2AccessTokenFetcher::MakeGetAccessTokenUrl() {
return GURL(GaiaUrls::GetInstance()->oauth2_token_url());
}
// static
std::string OAuth2AccessTokenFetcher::MakeGetAccessTokenBody(
const std::string& refresh_token) {
return StringPrintf(
kGetAccessTokenBodyFormat,
net::EscapeUrlEncodedData(
GaiaUrls::GetInstance()->oauth2_chrome_client_id(), true).c_str(),
net::EscapeUrlEncodedData(
GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
true).c_str(),
net::EscapeUrlEncodedData(refresh_token, true).c_str());
}
// static
bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
const URLFetcher* source,
std::string* access_token) {
CHECK(source);
CHECK(access_token);
std::string data;
source->GetResponseAsString(&data);
base::JSONReader reader;
scoped_ptr<base::Value> value(reader.Read(data, false));
if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY)
return false;
DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
return GetStringFromDictionary(dict, kAccessTokenKey, access_token);
}
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_COMMON_NET_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_H_
#define CHROME_COMMON_NET_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_H_
#pragma once
#include <string>
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/common/net/gaia/oauth2_access_token_consumer.h"
#include "content/public/common/url_fetcher.h"
#include "content/public/common/url_fetcher_delegate.h"
#include "googleurl/src/gurl.h"
class OAuth2AccessTokenFetcherTest;
namespace net {
class URLRequestContextGetter;
class URLRequestStatus;
}
// Abstracts the details to get OAuth2 access token token from
// OAuth2 refresh token.
//
// This class should be used on a single thread, but it can be whichever thread
// that you like.
// Also, do not reuse the same instance. Once Start() is called, the instance
// should not be reused.
//
// Usage:
// * Create an instance with a consumer.
// * Call Start()
// * The consumer passed in the constructor will be called on the same
// thread Start was called with the results.
//
// This class can handle one request at a time. To parallelize requests,
// create multiple instances.
class OAuth2AccessTokenFetcher : public content::URLFetcherDelegate {
public:
OAuth2AccessTokenFetcher(OAuth2AccessTokenConsumer* consumer,
net::URLRequestContextGetter* getter,
const std::string& source);
virtual ~OAuth2AccessTokenFetcher();
void Start(const std::string& refresh_token);
void CancelRequest();
// Implementation of content::URLFetcherDelegate
virtual void OnURLFetchComplete(const content::URLFetcher* source) OVERRIDE;
private:
enum State {
INITIAL,
GET_ACCESS_TOKEN_STARTED,
GET_ACCESS_TOKEN_DONE,
ERROR_STATE,
};
// Helper methods for the flow.
void StartGetAccessToken();
void EndGetAccessToken(const content::URLFetcher* source);
// Helper mehtods for reporting back results.
void ReportSuccess(const std::string& access_token);
void ReportFailure(GoogleServiceAuthError error);
// Other helpers.
static GURL MakeGetAccessTokenUrl();
static std::string MakeGetAccessTokenBody(const std::string& refresh_token);
static bool ParseGetAccessTokenResponse(const content::URLFetcher* source,
std::string* access_token);
// State that is set during construction.
OAuth2AccessTokenConsumer* const consumer_;
net::URLRequestContextGetter* const getter_;
std::string source_;
State state_;
// While a fetch is in progress.
scoped_ptr<content::URLFetcher> fetcher_;
std::string refresh_token_;
friend class OAuth2AccessTokenFetcherTest;
FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherTest,
ParseGetAccessTokenResponse);
DISALLOW_COPY_AND_ASSIGN(OAuth2AccessTokenFetcher);
};
#endif // CHROME_COMMON_NET_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_H_
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// A complete set of unit tests for OAuth2AccessTokenFetcher.
#include <string>
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "chrome/common/net/gaia/gaia_urls.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
#include "chrome/common/net/http_return.h"
#include "chrome/common/net/gaia/oauth2_access_token_consumer.h"
#include "chrome/common/net/gaia/oauth2_access_token_fetcher.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/common/url_fetcher.h"
#include "content/public/common/url_fetcher_delegate.h"
#include "content/public/common/url_fetcher_factory.h"
#include "content/test/test_browser_thread.h"
#include "content/test/test_url_fetcher_factory.h"
#include "googleurl/src/gurl.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_status.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using content::BrowserThread;
using content::URLFetcher;
using content::URLFetcherDelegate;
using content::URLFetcherFactory;
using net::ResponseCookies;
using net::URLRequestStatus;
using testing::_;
using testing::Return;
namespace {
static const char kValidTokenResponse[] =
"{"
" \"access_token\": \"at1\","
" \"expires_in\": 3600,"
" \"token_type\": \"Bearer\""
"}";
static const char kTokenResponseNoAccessToken[] =
"{"
" \"expires_in\": 3600,"
" \"token_type\": \"Bearer\""
"}";
}
class MockUrlFetcherFactory : public ScopedURLFetcherFactory,
public URLFetcherFactory {
public:
MockUrlFetcherFactory()
: ScopedURLFetcherFactory(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
}
virtual ~MockUrlFetcherFactory() {}
MOCK_METHOD4(
CreateURLFetcher,
URLFetcher* (int id,
const GURL& url,
URLFetcher::RequestType request_type,
URLFetcherDelegate* d));
};
class MockOAuth2AccessTokenConsumer : public OAuth2AccessTokenConsumer {
public:
MockOAuth2AccessTokenConsumer() {}
~MockOAuth2AccessTokenConsumer() {}
MOCK_METHOD1(OnGetTokenSuccess, void(const std::string& access_token));
MOCK_METHOD1(OnGetTokenFailure,
void(const GoogleServiceAuthError& error));
};
class OAuth2AccessTokenFetcherTest : public testing::Test {
public:
OAuth2AccessTokenFetcherTest()
: ui_thread_(BrowserThread::UI, &message_loop_),
fetcher_(&consumer_, profile_.GetRequestContext(), "test") {
}
virtual ~OAuth2AccessTokenFetcherTest() { }
virtual TestURLFetcher* SetupGetAccessToken(
bool fetch_succeeds, int response_code, const std::string& body) {
GURL url(GaiaUrls::GetInstance()->oauth2_token_url());
TestURLFetcher* url_fetcher = new TestURLFetcher(0, url, &fetcher_);
URLRequestStatus::Status status =
fetch_succeeds ? URLRequestStatus::SUCCESS : URLRequestStatus::FAILED;
url_fetcher->set_status(URLRequestStatus(status, 0));
if (response_code != 0)
url_fetcher->set_response_code(response_code);
if (!body.empty())
url_fetcher->SetResponseString(body);
EXPECT_CALL(factory_, CreateURLFetcher(_, url, _, _))
.WillOnce(Return(url_fetcher));
return url_fetcher;
}
protected:
MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
MockUrlFetcherFactory factory_;
MockOAuth2AccessTokenConsumer consumer_;
TestingProfile profile_;
OAuth2AccessTokenFetcher fetcher_;
};
TEST_F(OAuth2AccessTokenFetcherTest, GetAccessTokenRequestFailure) {
TestURLFetcher* url_fetcher = SetupGetAccessToken(false, 0, "");
EXPECT_CALL(consumer_, OnGetTokenFailure(_)).Times(1);
fetcher_.Start("refresh_token");
fetcher_.OnURLFetchComplete(url_fetcher);
}
TEST_F(OAuth2AccessTokenFetcherTest, GetAccessTokenResponseCodeFailure) {
TestURLFetcher* url_fetcher = SetupGetAccessToken(true, RC_FORBIDDEN, "");
EXPECT_CALL(consumer_, OnGetTokenFailure(_)).Times(1);
fetcher_.Start("refresh_token");
fetcher_.OnURLFetchComplete(url_fetcher);
}
TEST_F(OAuth2AccessTokenFetcherTest, GetAccessTokenResponseNoAccessToken) {
TestURLFetcher* url_fetcher = SetupGetAccessToken(
true, RC_REQUEST_OK, kTokenResponseNoAccessToken);
EXPECT_CALL(consumer_, OnGetTokenFailure(_)).Times(1);
fetcher_.Start("refresh_token");
fetcher_.OnURLFetchComplete(url_fetcher);
}
TEST_F(OAuth2AccessTokenFetcherTest, Success) {
TestURLFetcher* url_fetcher = SetupGetAccessToken(
true, RC_REQUEST_OK, kValidTokenResponse);
EXPECT_CALL(consumer_, OnGetTokenSuccess("at1")).Times(1);
fetcher_.Start("refresh_token");
fetcher_.OnURLFetchComplete(url_fetcher);
}
TEST_F(OAuth2AccessTokenFetcherTest, ParseGetAccessTokenResponse) {
{ // No body.
TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
std::string at;
EXPECT_FALSE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
&url_fetcher, &at));
EXPECT_TRUE(at.empty());
}
{ // Bad json.
TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
url_fetcher.SetResponseString("foo");
std::string at;
EXPECT_FALSE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
&url_fetcher, &at));
EXPECT_TRUE(at.empty());
}
{ // Valid json: access token missing.
TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
url_fetcher.SetResponseString(kTokenResponseNoAccessToken);
std::string at;
EXPECT_FALSE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
&url_fetcher, &at));
EXPECT_TRUE(at.empty());
}
{ // Valid json: all good.
TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
url_fetcher.SetResponseString(kValidTokenResponse);
std::string at;
EXPECT_TRUE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
&url_fetcher, &at));
EXPECT_EQ("at1", at);
}
}
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