diff options
-rw-r--r-- | chrome/browser/sync/test/integration/sync_test.cc | 11 | ||||
-rw-r--r-- | google_apis/gaia/gaia_auth_fetcher.cc | 218 | ||||
-rw-r--r-- | google_apis/gaia/gaia_auth_fetcher.h | 53 | ||||
-rw-r--r-- | google_apis/gaia/gaia_auth_fetcher_unittest.cc | 230 | ||||
-rw-r--r-- | google_apis/gaia/gaia_constants.cc | 39 | ||||
-rw-r--r-- | google_apis/gaia/gaia_constants.h | 13 | ||||
-rw-r--r-- | google_apis/gaia/gaia_urls.cc | 5 | ||||
-rw-r--r-- | google_apis/gaia/gaia_urls.h | 2 | ||||
-rw-r--r-- | google_apis/gaia/google_service_auth_error.cc | 43 | ||||
-rw-r--r-- | google_apis/gaia/google_service_auth_error.h | 20 | ||||
-rw-r--r-- | google_apis/gaia/google_service_auth_error_unittest.cc | 69 |
11 files changed, 2 insertions, 701 deletions
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index d2facba..cb5fa55 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc @@ -462,17 +462,6 @@ void SyncTest::SetupMockGaiaResponses() { "}", true); fake_factory_->SetFakeResponse( - GaiaUrls::GetInstance()->client_oauth_url(), - "{" - " \"oauth2\": {" - " \"refresh_token\": \"rt1\"," - " \"access_token\": \"at1\"," - " \"expires_in\": 3600," - " \"token_type\": \"Bearer\"" - " }" - "}", - true); - fake_factory_->SetFakeResponse( GaiaUrls::GetInstance()->oauth1_login_url(), "SID=sid\nLSID=lsid\nAuth=auth_token", true); diff --git a/google_apis/gaia/gaia_auth_fetcher.cc b/google_apis/gaia/gaia_auth_fetcher.cc index 15aa78a..c8391af 100644 --- a/google_apis/gaia/gaia_auth_fetcher.cc +++ b/google_apis/gaia/gaia_auth_fetcher.cc @@ -135,13 +135,6 @@ const char GaiaAuthFetcher::kCaptchaUrlParam[] = "CaptchaUrl"; const char GaiaAuthFetcher::kCaptchaTokenParam[] = "CaptchaToken"; // static -const char GaiaAuthFetcher::kNeedsAdditional[] = "NeedsAdditional"; -// static -const char GaiaAuthFetcher::kCaptcha[] = "Captcha"; -// static -const char GaiaAuthFetcher::kTwoFactor[] = "TwoStep"; - -// static const char GaiaAuthFetcher::kCookiePersistence[] = "true"; // static // TODO(johnnyg): When hosted accounts are supported by sync, @@ -188,7 +181,6 @@ GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), uberauth_token_gurl_(base::StringPrintf(kUberAuthTokenURLFormat, GaiaUrls::GetInstance()->oauth1_login_url().c_str(), source.c_str())), - client_oauth_gurl_(GaiaUrls::GetInstance()->client_oauth_url()), oauth_login_gurl_(GaiaUrls::GetInstance()->oauth1_login_url()), client_login_to_oauth2_gurl_( GaiaUrls::GetInstance()->client_login_to_oauth2_url()), @@ -396,66 +388,6 @@ void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, } // static -std::string GaiaAuthFetcher::MakeClientOAuthBody( - const std::string& username, - const std::string& password, - const std::vector<std::string>& scopes, - const std::string& persistent_id, - const std::string& friendly_name, - const std::string& locale) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); - dict->SetString(GaiaConstants::kClientOAuthEmailKey, username); - dict->SetString(GaiaConstants::kClientOAuthPasswordKey, password); - - scoped_ptr<base::ListValue> scope_list(new base::ListValue); - for (size_t i = 0; i < scopes.size(); ++i) - scope_list->Append(base::Value::CreateStringValue(scopes[i])); - dict->Set(GaiaConstants::kClientOAuthScopesKey, scope_list.release()); - - dict->SetString(GaiaConstants::kClientOAuthOAuth2ClientIdKey, - GaiaUrls::GetInstance()->oauth2_chrome_client_id()); - // crbug.com/129600: use a less generic friendly name. - dict->SetString(GaiaConstants::kClientOAuthFriendlyDeviceNameKey, - friendly_name); - - scoped_ptr<base::ListValue> accepts_challenge_list(new base::ListValue); - accepts_challenge_list->Append(base::Value::CreateStringValue(kCaptcha)); - accepts_challenge_list->Append(base::Value::CreateStringValue(kTwoFactor)); - dict->Set(GaiaConstants::kClientOAuthAcceptsChallengesKey, - accepts_challenge_list.release()); - - dict->SetString(GaiaConstants::kClientOAuthLocaleKey, locale); - // Chrome presently does not not support a web-fallback for ClientOAuth, - // but need to hardcode an arbitrary one here since the endpoint expects it. - dict->SetString(GaiaConstants::kClientOAuthFallbackNameKey, "GetOAuth2Token"); - - std::string json_string; - base::JSONWriter::Write(dict.get(), &json_string); - return json_string; -} - -// static -std::string GaiaAuthFetcher::MakeClientOAuthChallengeResponseBody( - const std::string& name, - const std::string& token, - const std::string& solution) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); - std::string field_name = name == kTwoFactor ? "otp" : "solution"; - - scoped_ptr<base::DictionaryValue> challenge_reply(new base::DictionaryValue); - challenge_reply->SetString(GaiaConstants::kClientOAuthNameKey, name); - challenge_reply->SetString(GaiaConstants::kClientOAuthChallengeTokenKey, - token); - challenge_reply->SetString(field_name, solution); - dict->Set(GaiaConstants::kClientOAuthchallengeReplyKey, - challenge_reply.release()); - - std::string json_string; - base::JSONWriter::Write(dict.get(), &json_string); - return json_string; -} - -// static std::string GaiaAuthFetcher::MakeOAuthLoginBody(const std::string& service, const std::string& source) { std::string encoded_service = net::EscapeUrlEncodedData(service, true); @@ -528,71 +460,6 @@ bool GaiaAuthFetcher::ParseClientLoginToOAuth2Cookie(const std::string& cookie, return false; } -// static -GoogleServiceAuthError -GaiaAuthFetcher::GenerateClientOAuthError(const std::string& data, - const net::URLRequestStatus& status) { - scoped_ptr<base::Value> value(base::JSONReader::Read(data)); - if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY) - return GenerateAuthError(data, status); - DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); - - std::string cause; - if (!dict->GetStringWithoutPathExpansion("cause", &cause)) - return GoogleServiceAuthError::FromClientOAuthError(data); - - if (cause != kNeedsAdditional) - return GoogleServiceAuthError::FromClientOAuthError(data); - - DictionaryValue* challenge; - if (!dict->GetDictionaryWithoutPathExpansion("challenge", &challenge)) - return GoogleServiceAuthError::FromClientOAuthError(data); - - std::string name; - if (!challenge->GetStringWithoutPathExpansion("name", &name)) - return GoogleServiceAuthError::FromClientOAuthError(data); - - if (name == kCaptcha) { - std::string token; - std::string audio_url; - std::string image_url; - int image_width; - int image_height; - if (!challenge->GetStringWithoutPathExpansion("challenge_token", &token) || - !challenge->GetStringWithoutPathExpansion("audio_url", &audio_url) || - !challenge->GetStringWithoutPathExpansion("image_url", &image_url) || - !challenge->GetIntegerWithoutPathExpansion("image_width", - &image_width) || - !challenge->GetIntegerWithoutPathExpansion("image_height", - &image_height)) { - return GoogleServiceAuthError::FromClientOAuthError(data); - } - return GoogleServiceAuthError::FromCaptchaChallenge(token, GURL(audio_url), - GURL(image_url), - image_width, - image_height); - } else if (name == kTwoFactor) { - std::string token; - std::string prompt_text; - std::string alternate_text; - int field_length; - - // The protocol doc says these are required, but in practice they are not - // returned. So only a missing challenge token will cause an error here. - challenge->GetStringWithoutPathExpansion("prompt_text", &prompt_text); - challenge->GetStringWithoutPathExpansion("alternate_text", &alternate_text); - challenge->GetIntegerWithoutPathExpansion("field_length", &field_length); - if (!challenge->GetStringWithoutPathExpansion("challenge_token", &token)) - return GoogleServiceAuthError::FromClientOAuthError(data); - - return GoogleServiceAuthError::FromSecondFactorChallenge(token, prompt_text, - alternate_text, - field_length); - } - - return GoogleServiceAuthError::FromClientOAuthError(data); -} - void GaiaAuthFetcher::StartClientLogin( const std::string& username, const std::string& password, @@ -774,54 +641,6 @@ void GaiaAuthFetcher::StartTokenFetchForUberAuthExchange( fetcher_->Start(); } -void GaiaAuthFetcher::StartClientOAuth(const std::string& username, - const std::string& password, - const std::vector<std::string>& scopes, - const std::string& persistent_id, - const std::string& locale) { - DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; - - request_body_ = MakeClientOAuthBody(username, password, scopes, persistent_id, - source_, locale); - fetcher_.reset(CreateGaiaFetcher(getter_, - request_body_, - std::string(), - client_oauth_gurl_, - kLoadFlagsIgnoreCookies, - this)); - fetch_pending_ = true; - fetcher_->Start(); -} - -void GaiaAuthFetcher::StartClientOAuthChallengeResponse( - GoogleServiceAuthError::State type, - const std::string& token, - const std::string& solution) { - DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; - - std::string name; - switch (type) { - case GoogleServiceAuthError::CAPTCHA_REQUIRED: - name = kCaptcha; - break; - case GoogleServiceAuthError::TWO_FACTOR: - name = kTwoFactor; - break; - default: - NOTREACHED(); - } - - request_body_ = MakeClientOAuthChallengeResponseBody(name, token, solution); - fetcher_.reset(CreateGaiaFetcher(getter_, - request_body_, - std::string(), - client_oauth_gurl_, - kLoadFlagsIgnoreCookies, - this)); - fetch_pending_ = true; - fetcher_->Start(); -} - void GaiaAuthFetcher::StartOAuthLogin(const std::string& access_token, const std::string& service) { DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; @@ -1061,41 +880,6 @@ void GaiaAuthFetcher::OnUberAuthTokenFetch(const std::string& data, } } -void GaiaAuthFetcher::OnClientOAuthFetched(const std::string& data, - const net::URLRequestStatus& status, - int response_code) { - std::string refresh_token; - std::string access_token; - int expires_in_secs = 0; - - bool success = false; - if (status.is_success() && response_code == net::HTTP_OK) { - scoped_ptr<base::Value> value(base::JSONReader::Read(data)); - if (value.get() && value->GetType() == base::Value::TYPE_DICTIONARY) { - DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); - DictionaryValue* dict_oauth2; - if (dict->GetDictionaryWithoutPathExpansion("oauth2", &dict_oauth2)) { - success = ExtractOAuth2TokenPairResponse(dict_oauth2, &refresh_token, - &access_token, - &expires_in_secs); - } - } - } - - // TODO(rogerta): for now this reuses the OnOAuthLoginTokenXXX callbacks - // since the data is exactly the same. This ignores the optional - // persistent_id data in the response, which we may need to handle. - // If we do, we'll need to modify ExtractOAuth2TokenPairResponse() to parse - // the optional data and declare new consumer callbacks to take it. - if (success) { - consumer_->OnClientOAuthSuccess( - GaiaAuthConsumer::ClientOAuthResult(refresh_token, access_token, - expires_in_secs)); - } else { - consumer_->OnClientOAuthFailure(GenerateClientOAuthError(data, status)); - } -} - void GaiaAuthFetcher::OnOAuthLoginFetched(const std::string& data, const net::URLRequestStatus& status, int response_code) { @@ -1147,8 +931,6 @@ void GaiaAuthFetcher::OnURLFetchComplete(const net::URLFetcher* source) { OnMergeSessionFetched(data, status, response_code); } else if (url == uberauth_token_gurl_) { OnUberAuthTokenFetch(data, status, response_code); - } else if (url == client_oauth_gurl_) { - OnClientOAuthFetched(data, status, response_code); } else if (url == oauth_login_gurl_) { OnOAuthLoginFetched(data, status, response_code); } else if (url == oauth2_revoke_gurl_) { diff --git a/google_apis/gaia/gaia_auth_fetcher.h b/google_apis/gaia/gaia_auth_fetcher.h index bcd1116..84cc3e6 100644 --- a/google_apis/gaia/gaia_auth_fetcher.h +++ b/google_apis/gaia/gaia_auth_fetcher.h @@ -147,38 +147,6 @@ class GaiaAuthFetcher : public net::URLFetcherDelegate { // called on the consumer on the original thread. void StartTokenFetchForUberAuthExchange(const std::string& access_token); - // Start a request to obtain an OAuth2 token for the account identified by - // |username| and |password|. |scopes| is a list of oauth scopes that - // indicate the access permerssions to assign to the returned token. - // |persistent_id| is an optional client identifier used to identify this - // particular chrome instances, which may reduce the chance of a challenge. - // |locale| will be used to format messages to be presented to the user in - // challenges, if needed. - // - // If the request cannot complete due to a challenge, the - // GoogleServiceAuthError will indicate the type of challenge required: - // either CAPTCHA_REQUIRED or TWO_FACTOR. - // - // Either OnClientOAuthSuccess or OnClientOAuthFailure will be - // called on the consumer on the original thread. - void StartClientOAuth(const std::string& username, - const std::string& password, - const std::vector<std::string>& scopes, - const std::string& persistent_id, - const std::string& locale); - - // Start a challenge response to obtain an OAuth2 token. This method is - // called after a challenge response is issued from a previous call to - // StartClientOAuth(). The |type| and |token| arguments come from the - // error response to StartClientOAuth(), while the |solution| argument - // represents the answer from the user for the partocular challenge. - // - // Either OnClientOAuthSuccess or OnClientOAuthFailure will be - // called on the consumer on the original thread. - void StartClientOAuthChallengeResponse(GoogleServiceAuthError::State type, - const std::string& token, - const std::string& solution); - // Start a request to exchange an OAuthLogin-scoped oauth2 access token for a // ClientLogin-style service tokens. The response to this request is the // same as the response to a ClientLogin request, except that captcha @@ -297,10 +265,6 @@ class GaiaAuthFetcher : public net::URLFetcherDelegate { const net::URLRequestStatus& status, int response_code); - void OnClientOAuthFetched(const std::string& data, - const net::URLRequestStatus& status, - int response_code); - void OnOAuthLoginFetched(const std::string& data, const net::URLRequestStatus& status, int response_code); @@ -325,10 +289,6 @@ class GaiaAuthFetcher : public net::URLFetcherDelegate { static bool ParseClientLoginToOAuth2Cookie(const std::string& cookie, std::string* auth_code); - static GoogleServiceAuthError GenerateClientOAuthError( - const std::string& data, - const net::URLRequestStatus& status); - // Is this a special case Gaia error for TwoFactor auth? static bool IsSecondFactorSuccess(const std::string& alleged_error); @@ -363,18 +323,6 @@ class GaiaAuthFetcher : public net::URLFetcherDelegate { static std::string MakeGetAuthCodeHeader(const std::string& auth_token); - static std::string MakeClientOAuthBody(const std::string& username, - const std::string& password, - const std::vector<std::string>& scopes, - const std::string& persistent_id, - const std::string& friendly_name, - const std::string& locale); - - static std::string MakeClientOAuthChallengeResponseBody( - const std::string& name, - const std::string& token, - const std::string& solution); - static std::string MakeOAuthLoginBody(const std::string& service, const std::string& source); @@ -410,7 +358,6 @@ class GaiaAuthFetcher : public net::URLFetcherDelegate { const GURL get_user_info_gurl_; const GURL merge_session_gurl_; const GURL uberauth_token_gurl_; - const GURL client_oauth_gurl_; const GURL oauth_login_gurl_; // While a fetch is going on: diff --git a/google_apis/gaia/gaia_auth_fetcher_unittest.cc b/google_apis/gaia/gaia_auth_fetcher_unittest.cc index 47b6d15..c9fa1ef1 100644 --- a/google_apis/gaia/gaia_auth_fetcher_unittest.cc +++ b/google_apis/gaia/gaia_auth_fetcher_unittest.cc @@ -57,29 +57,6 @@ static const char kClientOAuthValidResponse[] = " }" "}"; -static void ExpectCaptchaChallenge(const GoogleServiceAuthError& error) { - // Make sure this is a captcha server challange. - EXPECT_EQ(GoogleServiceAuthError::CAPTCHA_REQUIRED, error.state()); - EXPECT_EQ("challengetokenblob", error.captcha().token); - EXPECT_EQ("http://www.audio.com/", error.captcha().audio_url.spec()); - EXPECT_EQ("http://www.image.com/", error.captcha().image_url.spec()); - EXPECT_EQ(640, error.captcha().image_width); - EXPECT_EQ(480, error.captcha().image_height); -} - -static void ExpectBadAuth(const GoogleServiceAuthError& error) { - EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error.state()); -} - -static void ExpectTwoFactorChallenge(const GoogleServiceAuthError& error) { - // Make sure this is a captcha server challange. - EXPECT_EQ(GoogleServiceAuthError::TWO_FACTOR, error.state()); - EXPECT_EQ("challengetokenblob", error.second_factor().token); - EXPECT_EQ("prompt_text", error.second_factor().prompt_text); - EXPECT_EQ("alternate_text", error.second_factor().alternate_text); - EXPECT_EQ(10, error.second_factor().field_length); -} - } // namespace MockFetcher::MockFetcher(bool success, @@ -138,7 +115,6 @@ class GaiaAuthFetcherTest : public testing::Test { uberauth_token_source_(base::StringPrintf( "%s?source=&issueuberauth=1", GaiaUrls::GetInstance()->oauth1_login_url().c_str())), - client_oauth_source_(GaiaUrls::GetInstance()->client_oauth_url()), oauth_login_gurl_(GaiaUrls::GetInstance()->oauth1_login_url()) {} void RunParsingTest(const std::string& data, @@ -187,7 +163,6 @@ class GaiaAuthFetcherTest : public testing::Test { GURL token_auth_source_; GURL merge_session_source_; GURL uberauth_token_source_; - GURL client_oauth_source_; GURL oauth_login_gurl_; TestingProfile profile_; protected: @@ -814,211 +789,6 @@ TEST_F(GaiaAuthFetcherTest, ParseClientLoginToOAuth2Response) { } } -TEST_F(GaiaAuthFetcherTest, ClientOAuthSuccess) { - MockURLFetcherFactory<MockFetcher> factory; - factory.set_results(kClientOAuthValidResponse); - - MockGaiaConsumer consumer; - EXPECT_CALL(consumer, OnClientOAuthSuccess( - GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1); - - GaiaAuthFetcher auth(&consumer, "tests", profile_.GetRequestContext()); - std::vector<std::string> scopes; - scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope()); - scopes.push_back("https://some.other.scope.com"); - auth.StartClientOAuth("username", "password", scopes, std::string(), "en"); - - std::string expected_text = base::StringPrintf( - "{" - "\"email\": \"username\"," - "\"password\": \"password\"," - "\"scopes\": [\"https://www.google.com/accounts/OAuthLogin\"," - " \"https://some.other.scope.com\"]," - "\"oauth2_client_id\": \"%s\"," - "\"friendly_device_name\": \"tests\"," - "\"accepts_challenges\": [\"Captcha\", \"TwoStep\"]," - "\"locale\": \"en\"," - "\"fallback\": { \"name\": \"GetOAuth2Token\" }" - "}", - google_apis::GetOAuth2ClientID(google_apis::CLIENT_MAIN).c_str()); - - scoped_ptr<base::Value> actual(base::JSONReader::Read(auth.request_body_)); - scoped_ptr<base::Value> expected(base::JSONReader::Read(expected_text)); - EXPECT_TRUE(expected->Equals(actual.get())); -} - -TEST_F(GaiaAuthFetcherTest, ClientOAuthWithQuote) { - MockURLFetcherFactory<MockFetcher> factory; - factory.set_results(kClientOAuthValidResponse); - - MockGaiaConsumer consumer; - EXPECT_CALL(consumer, OnClientOAuthSuccess( - GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1); - - GaiaAuthFetcher auth(&consumer, "te\"sts", profile_.GetRequestContext()); - std::vector<std::string> scopes; - scopes.push_back("https://some.\"other.scope.com"); - auth.StartClientOAuth( - "user\"name", "pass\"word", scopes, std::string(), "e\"n"); - - std::string expected_text = base::StringPrintf( - "{" - "\"email\": \"user\\\"name\"," - "\"password\": \"pass\\\"word\"," - "\"scopes\": [\"https://some.\\\"other.scope.com\"]," - "\"oauth2_client_id\": \"%s\"," - "\"friendly_device_name\": \"te\\\"sts\"," - "\"accepts_challenges\": [\"Captcha\", \"TwoStep\"]," - "\"locale\": \"e\\\"n\"," - "\"fallback\": { \"name\": \"GetOAuth2Token\" }" - "}", - google_apis::GetOAuth2ClientID(google_apis::CLIENT_MAIN).c_str()); - scoped_ptr<base::Value> actual(base::JSONReader::Read(auth.request_body_)); - scoped_ptr<base::Value> expected(base::JSONReader::Read(expected_text)); - EXPECT_TRUE(expected->Equals(actual.get())); -} - -TEST_F(GaiaAuthFetcherTest, ClientOAuthBadAuth) { - MockURLFetcherFactory<MockFetcher> factory; - factory.set_success(false); - factory.set_results("{" - " \"cause\" : \"BadAuthentication\"," - " \"fallback\" : {" - " \"name\" : \"Terminating\"," - " \"url\" : \"https://www.terminating.com\"" - " }" - "}"); - - MockGaiaConsumer consumer; - EXPECT_CALL(consumer, OnClientOAuthFailure(_)) - .WillOnce(Invoke(ExpectBadAuth)); - - GaiaAuthFetcher auth(&consumer, "tests", profile_.GetRequestContext()); - std::vector<std::string> scopes; - scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope()); - auth.StartClientOAuth("username", "password", scopes, std::string(), "en"); -} - -TEST_F(GaiaAuthFetcherTest, ClientOAuthCaptchaChallenge) { - MockURLFetcherFactory<MockFetcher> factory; - factory.set_success(false); - factory.set_results("{" - " \"cause\" : \"NeedsAdditional\"," - " \"fallback\" : {" - " \"name\" : \"Terminating\"," - " \"url\" : \"https://www.terminating.com\"" - " }," - " \"challenge\" : {" - " \"name\" : \"Captcha\"," - " \"image_url\" : \"http://www.image.com/\"," - " \"image_width\" : 640," - " \"image_height\" : 480," - " \"audio_url\" : \"http://www.audio.com/\"," - " \"challenge_token\" : \"challengetokenblob\"" - " }" - "}"); - - MockGaiaConsumer consumer; - EXPECT_CALL(consumer, OnClientOAuthFailure(_)) - .WillOnce(Invoke(ExpectCaptchaChallenge)); - - GaiaAuthFetcher auth(&consumer, "tests", profile_.GetRequestContext()); - std::vector<std::string> scopes; - scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope()); - auth.StartClientOAuth("username", "password", scopes, std::string(), "en"); -} - -TEST_F(GaiaAuthFetcherTest, ClientOAuthTwoFactorChallenge) { - MockURLFetcherFactory<MockFetcher> factory; - factory.set_success(false); - factory.set_results("{" - " \"cause\" : \"NeedsAdditional\"," - " \"fallback\" : {" - " \"name\" : \"Terminating\"," - " \"url\" : \"https://www.terminating.com\"" - " }," - " \"challenge\" : {" - " \"name\" : \"TwoStep\"," - " \"prompt_text\" : \"prompt_text\"," - " \"alternate_text\" : \"alternate_text\"," - " \"challenge_token\" : \"challengetokenblob\"," - " \"field_length\" : 10" - " }" - "}"); - - MockGaiaConsumer consumer; - EXPECT_CALL(consumer, OnClientOAuthFailure(_)) - .WillOnce(Invoke(ExpectTwoFactorChallenge)); - - GaiaAuthFetcher auth(&consumer, "tests", profile_.GetRequestContext()); - std::vector<std::string> scopes; - scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope()); - auth.StartClientOAuth("username", "password", scopes, std::string(), "en"); -} - -TEST_F(GaiaAuthFetcherTest, ClientOAuthChallengeSuccess) { - MockURLFetcherFactory<MockFetcher> factory; - factory.set_results(kClientOAuthValidResponse); - - MockGaiaConsumer consumer; - EXPECT_CALL(consumer, OnClientOAuthSuccess( - GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(2); - - GaiaAuthFetcher auth1(&consumer, std::string(), profile_.GetRequestContext()); - auth1.StartClientOAuthChallengeResponse(GoogleServiceAuthError::TWO_FACTOR, - "token", "mysolution"); - - scoped_ptr<base::Value> actual1(base::JSONReader::Read(auth1.request_body_)); - scoped_ptr<base::Value> expected1(base::JSONReader::Read( - "{" - " \"challenge_reply\" : {" - " \"name\" : \"TwoStep\"," - " \"challenge_token\" : \"token\"," - " \"otp\" : \"mysolution\"" - " }" - "}")); - EXPECT_TRUE(expected1->Equals(actual1.get())); - - GaiaAuthFetcher auth2(&consumer, "tests", profile_.GetRequestContext()); - auth2.StartClientOAuthChallengeResponse( - GoogleServiceAuthError::CAPTCHA_REQUIRED, "token", "mysolution"); - - scoped_ptr<base::Value> actual2(base::JSONReader::Read(auth2.request_body_)); - scoped_ptr<base::Value> expected2(base::JSONReader::Read( - "{" - " \"challenge_reply\" : {" - " \"name\" : \"Captcha\"," - " \"challenge_token\" : \"token\"," - " \"solution\" : \"mysolution\"" - " }" - "}")); - EXPECT_TRUE(expected2->Equals(actual2.get())); -} - -TEST_F(GaiaAuthFetcherTest, ClientOAuthChallengeQuote) { - MockURLFetcherFactory<MockFetcher> factory; - factory.set_results(kClientOAuthValidResponse); - - MockGaiaConsumer consumer; - EXPECT_CALL(consumer, OnClientOAuthSuccess( - GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1); - - GaiaAuthFetcher auth(&consumer, std::string(), profile_.GetRequestContext()); - auth.StartClientOAuthChallengeResponse(GoogleServiceAuthError::TWO_FACTOR, - "to\"ken", "my\"solution"); - - scoped_ptr<base::Value> actual(base::JSONReader::Read(auth.request_body_)); - scoped_ptr<base::Value> expected(base::JSONReader::Read( - "{" - " \"challenge_reply\" : {" - " \"name\" : \"TwoStep\"," - " \"challenge_token\" : \"to\\\"ken\"," - " \"otp\" : \"my\\\"solution\"" - " }" - "}")); - EXPECT_TRUE(expected->Equals(actual.get())); -} - TEST_F(GaiaAuthFetcherTest, StartOAuthLogin) { // OAuthLogin returns the same as the ClientLogin endpoint, minus CAPTCHA // responses. diff --git a/google_apis/gaia/gaia_constants.cc b/google_apis/gaia/gaia_constants.cc index 0dd5236..4ac9ea4 100644 --- a/google_apis/gaia/gaia_constants.cc +++ b/google_apis/gaia/gaia_constants.cc @@ -48,44 +48,7 @@ const char kObfuscatedGaiaId[] = "obfuscatedGaiaId"; // the ClientOAuth endpoint protocol. The comment above each constant explains // what value is associated with that key. -// Canonical email and password of the account to sign in. +// Canonical email of the account to sign in. const char kClientOAuthEmailKey[] = "email"; -const char kClientOAuthPasswordKey[] = "password"; - -// Scopes required for the returned oauth2 token. For GaiaAuthFetcher, the -// value is the OAuthLogin scope. -const char kClientOAuthScopesKey[] = "scopes"; - -// Chrome's client id from the API console. -const char kClientOAuthOAuth2ClientIdKey[] = "oauth2_client_id"; - -// A friendly name to describe this instance of chrome to the user. -const char kClientOAuthFriendlyDeviceNameKey[] = "friendly_device_name"; - -// A list of challenge types that chrome accepts. At a minimum this must -// include Captcha. To support OTPs should also include TwoFactor. -const char kClientOAuthAcceptsChallengesKey[] = "accepts_challenges"; - -// The locale of the browser, so that ClientOAuth can return localized error -// messages. -const char kClientOAuthLocaleKey[] = "locale"; - -// The name of the web-based fallback method to use if ClientOAuth decides it -// cannot continue otherwise. Note that this name has a dot because its in -// sub dictionary. -const char kClientOAuthFallbackNameKey[] = "fallback.name"; - -// The following three key names are used with ClientOAuth challenge responses. - -// The type of response. Must match the name given in the response to the -// original ClientOAuth request and is a subset of the challenge types listed -// in kClientOAuthAcceptsChallengesKey from that original request. -const char kClientOAuthNameKey[] = "name"; - -// The challenge token received in the original ClientOAuth request. -const char kClientOAuthChallengeTokenKey[] = "challenge_token"; - -// The dictionary that contains the challenge response. -const char kClientOAuthchallengeReplyKey[] = "challenge_reply"; } // namespace GaiaConstants diff --git a/google_apis/gaia/gaia_constants.h b/google_apis/gaia/gaia_constants.h index 625ab5b..503db3a1 100644 --- a/google_apis/gaia/gaia_constants.h +++ b/google_apis/gaia/gaia_constants.h @@ -33,19 +33,8 @@ extern const char kGaiaOAuth2LoginRefreshToken[]; // Used to construct a channel ID for push messaging. extern const char kObfuscatedGaiaId[]; -// Used to build ClientOAuth requests. These are the names of keys used in -// the json dictionaries that are sent in the protocol. +// Used by wallet sign in helper. extern const char kClientOAuthEmailKey[]; -extern const char kClientOAuthPasswordKey[]; -extern const char kClientOAuthScopesKey[]; -extern const char kClientOAuthOAuth2ClientIdKey[]; -extern const char kClientOAuthFriendlyDeviceNameKey[]; -extern const char kClientOAuthAcceptsChallengesKey[]; -extern const char kClientOAuthLocaleKey[]; -extern const char kClientOAuthFallbackNameKey[]; -extern const char kClientOAuthNameKey[]; -extern const char kClientOAuthChallengeTokenKey[]; -extern const char kClientOAuthchallengeReplyKey[]; } // namespace GaiaConstants diff --git a/google_apis/gaia/gaia_urls.cc b/google_apis/gaia/gaia_urls.cc index 543bd88..f5734c7 100644 --- a/google_apis/gaia/gaia_urls.cc +++ b/google_apis/gaia/gaia_urls.cc @@ -111,7 +111,6 @@ GaiaUrls::GaiaUrls() { oauth_wrap_bridge_url_ = gaia_url_base + kOAuthWrapBridgeUrlSuffix; oauth_revoke_token_url_ = gaia_url_base + kOAuthRevokeTokenUrlSuffix; oauth1_login_url_ = gaia_url_base + kOAuth1LoginUrlSuffix; - client_oauth_url_ = gaia_url_base + kClientOAuthUrlSuffix; // URLs from accounts.google.com (LSO). get_oauth_token_url_ = lso_origin_url_ + kGetOAuthTokenUrlSuffix; @@ -218,10 +217,6 @@ const std::string& GaiaUrls::oauth_wrap_bridge_user_info_scope() { return oauth_wrap_bridge_user_info_scope_; } -const std::string& GaiaUrls::client_oauth_url() { - return client_oauth_url_; -} - const std::string& GaiaUrls::oauth2_chrome_client_id() { return oauth2_chrome_client_id_; } diff --git a/google_apis/gaia/gaia_urls.h b/google_apis/gaia/gaia_urls.h index 5a5cb11..3fd19bc 100644 --- a/google_apis/gaia/gaia_urls.h +++ b/google_apis/gaia/gaia_urls.h @@ -34,7 +34,6 @@ class GaiaUrls { const std::string& oauth1_login_scope(); const std::string& oauth_wrap_bridge_user_info_scope(); - const std::string& client_oauth_url(); const std::string& oauth2_chrome_client_id(); const std::string& oauth2_chrome_client_secret(); @@ -72,7 +71,6 @@ class GaiaUrls { std::string oauth1_login_scope_; std::string oauth_wrap_bridge_user_info_scope_; - std::string client_oauth_url_; std::string oauth2_chrome_client_id_; std::string oauth2_chrome_client_secret_; diff --git a/google_apis/gaia/google_service_auth_error.cc b/google_apis/gaia/google_service_auth_error.cc index 96fc063..e777b10 100644 --- a/google_apis/gaia/google_service_auth_error.cc +++ b/google_apis/gaia/google_service_auth_error.cc @@ -96,49 +96,6 @@ GoogleServiceAuthError GoogleServiceAuthError::FromClientLoginCaptchaChallenge( captcha_image_url, captcha_unlock_url, 0, 0); } -// static -GoogleServiceAuthError GoogleServiceAuthError::FromCaptchaChallenge( - const std::string& captcha_token, - const GURL& captcha_audio_url, - const GURL& captcha_image_url, - int image_width, - int image_height) { - return GoogleServiceAuthError(CAPTCHA_REQUIRED, captcha_token, - captcha_audio_url, captcha_image_url, - GURL(), image_width, image_height); -} - -// static -GoogleServiceAuthError GoogleServiceAuthError::FromSecondFactorChallenge( - const std::string& captcha_token, - const std::string& prompt_text, - const std::string& alternate_text, - int field_length) { - return GoogleServiceAuthError(TWO_FACTOR, captcha_token, prompt_text, - alternate_text, field_length); -} - -// static -GoogleServiceAuthError GoogleServiceAuthError::FromClientOAuthError( - const std::string& data) { - scoped_ptr<base::Value> value(base::JSONReader::Read(data)); - if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY) - return GoogleServiceAuthError(CONNECTION_FAILED, 0); - - DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); - - std::string cause; - if (!dict->GetStringWithoutPathExpansion("cause", &cause)) - return GoogleServiceAuthError(CONNECTION_FAILED, 0); - - // The explanation field is optional. - std::string explanation; - if (!dict->GetStringWithoutPathExpansion("explanation", &explanation)) - explanation.clear(); - - return GoogleServiceAuthError(explanation); -} - GoogleServiceAuthError GoogleServiceAuthError::AuthErrorNone() { return GoogleServiceAuthError(NONE); } diff --git a/google_apis/gaia/google_service_auth_error.h b/google_apis/gaia/google_service_auth_error.h index 29f83f9..0ac0974 100644 --- a/google_apis/gaia/google_service_auth_error.h +++ b/google_apis/gaia/google_service_auth_error.h @@ -145,26 +145,6 @@ class GoogleServiceAuthError { const GURL& captcha_image_url, const GURL& captcha_unlock_url); - // Construct a CAPTCHA_REQUIRED error with CAPTCHA challenge data from the - // ClientOAuth endpoint. - static GoogleServiceAuthError FromCaptchaChallenge( - const std::string& captcha_token, - const GURL& captcha_audio_url, - const GURL& captcha_image_url, - int image_width, - int image_height); - - // Construct a TWO_FACTOR error with second-factor challenge data. - static GoogleServiceAuthError FromSecondFactorChallenge( - const std::string& captcha_token, - const std::string& prompt_text, - const std::string& alternate_text, - int field_length); - - // Construct an INVALID_GAIA_CREDENTIALS error from a ClientOAuth response. - // |data| is the JSON response from the server explaning the error. - static GoogleServiceAuthError FromClientOAuthError(const std::string& data); - // Provided for convenience for clients needing to reset an instance to NONE. // (avoids err_ = GoogleServiceAuthError(GoogleServiceAuthError::NONE), due // to explicit class and State enum relation. Note: shouldn't be inlined! diff --git a/google_apis/gaia/google_service_auth_error_unittest.cc b/google_apis/gaia/google_service_auth_error_unittest.cc index 15155b6..d1f920a 100644 --- a/google_apis/gaia/google_service_auth_error_unittest.cc +++ b/google_apis/gaia/google_service_auth_error_unittest.cc @@ -52,73 +52,4 @@ TEST_F(GoogleServiceAuthErrorTest, ConnectionFailed) { ExpectDictStringValue("net::OK", *value, "networkError"); } -TEST_F(GoogleServiceAuthErrorTest, CaptchaChallenge) { - GoogleServiceAuthError error( - GoogleServiceAuthError::FromClientLoginCaptchaChallenge( - "captcha_token", GURL("http://www.google.com"), - GURL("http://www.bing.com"))); - scoped_ptr<DictionaryValue> value(error.ToValue()); - EXPECT_EQ(2u, value->size()); - ExpectDictStringValue("CAPTCHA_REQUIRED", *value, "state"); - DictionaryValue* captcha_value = NULL; - EXPECT_TRUE(value->GetDictionary("captcha", &captcha_value)); - ASSERT_TRUE(captcha_value); - ExpectDictStringValue("captcha_token", *captcha_value, "token"); - ExpectDictStringValue(std::string(), *captcha_value, "audioUrl"); - ExpectDictStringValue("http://www.google.com/", *captcha_value, "imageUrl"); - ExpectDictStringValue("http://www.bing.com/", *captcha_value, "unlockUrl"); - ExpectDictIntegerValue(0, *captcha_value, "imageWidth"); - ExpectDictIntegerValue(0, *captcha_value, "imageHeight"); -} - -TEST_F(GoogleServiceAuthErrorTest, CaptchaChallenge2) { - GoogleServiceAuthError error( - GoogleServiceAuthError::FromCaptchaChallenge( - "captcha_token", GURL("http://www.audio.com"), - GURL("http://www.image.com"), 320, 200)); - scoped_ptr<DictionaryValue> value(error.ToValue()); - EXPECT_EQ(2u, value->size()); - ExpectDictStringValue("CAPTCHA_REQUIRED", *value, "state"); - DictionaryValue* captcha_value = NULL; - EXPECT_TRUE(value->GetDictionary("captcha", &captcha_value)); - ASSERT_TRUE(captcha_value); - ExpectDictStringValue("captcha_token", *captcha_value, "token"); - ExpectDictStringValue("http://www.audio.com/", *captcha_value, "audioUrl"); - ExpectDictStringValue("http://www.image.com/", *captcha_value, "imageUrl"); - ExpectDictIntegerValue(320, *captcha_value, "imageWidth"); - ExpectDictIntegerValue(200, *captcha_value, "imageHeight"); -} - -TEST_F(GoogleServiceAuthErrorTest, TwoFactorChallenge) { - GoogleServiceAuthError error( - GoogleServiceAuthError::FromSecondFactorChallenge( - "two_factor_token", "prompt_text", "alternate_text", 10)); - scoped_ptr<DictionaryValue> value(error.ToValue()); - EXPECT_EQ(2u, value->size()); - ExpectDictStringValue("TWO_FACTOR", *value, "state"); - DictionaryValue* two_factor_value = NULL; - EXPECT_TRUE(value->GetDictionary("two_factor", &two_factor_value)); - ASSERT_TRUE(two_factor_value); - ExpectDictStringValue("two_factor_token", *two_factor_value, "token"); - ExpectDictStringValue("prompt_text", *two_factor_value, "promptText"); - ExpectDictStringValue("alternate_text", *two_factor_value, "alternateText"); - ExpectDictIntegerValue(10, *two_factor_value, "fieldLength"); -} - -TEST_F(GoogleServiceAuthErrorTest, ClientOAuthError) { - // Test that a malformed/incomplete ClientOAuth response generates - // a connection problem error. - GoogleServiceAuthError error1( - GoogleServiceAuthError::FromClientOAuthError("{}")); - EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error1.state()); - - // Test that a well formed ClientOAuth response generates an invalid - // credentials error with the given error message. - GoogleServiceAuthError error2( - GoogleServiceAuthError::FromClientOAuthError( - "{\"cause\":\"foo\",\"explanation\":\"error_message\"}")); - EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error2.state()); - EXPECT_EQ("error_message", error2.error_message()); -} - } // namespace |