gaia_auth_fetcher_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4// 5// A complete set of unit tests for GaiaAuthFetcher. 6// Originally ported from GoogleAuthenticator tests. 7 8#include <string> 9 10#include "base/json/json_reader.h" 11#include "base/message_loop.h" 12#include "base/stringprintf.h" 13#include "base/values.h" 14#include "chrome/test/base/testing_profile.h" 15#include "google_apis/gaia/gaia_auth_consumer.h" 16#include "google_apis/gaia/gaia_auth_fetcher.h" 17#include "google_apis/gaia/gaia_urls.h" 18#include "google_apis/gaia/google_service_auth_error.h" 19#include "google_apis/gaia/mock_url_fetcher_factory.h" 20#include "google_apis/google_api_keys.h" 21#include "googleurl/src/gurl.h" 22#include "net/base/load_flags.h" 23#include "net/base/net_errors.h" 24#include "net/http/http_status_code.h" 25#include "net/url_request/test_url_fetcher_factory.h" 26#include "net/url_request/url_fetcher_delegate.h" 27#include "net/url_request/url_request_status.h" 28#include "testing/gmock/include/gmock/gmock.h" 29#include "testing/gtest/include/gtest/gtest.h" 30 31using ::testing::_; 32using ::testing::Invoke; 33 34namespace { 35static const char kGetAuthCodeValidCookie[] = 36 "oauth_code=test-code; Path=/test; Secure; HttpOnly"; 37static const char kGetAuthCodeCookieNoSecure[] = 38 "oauth_code=test-code; Path=/test; HttpOnly"; 39static const char kGetAuthCodeCookieNoHttpOnly[] = 40 "oauth_code=test-code; Path=/test; Secure"; 41static const char kGetAuthCodeCookieNoOAuthCode[] = 42 "Path=/test; Secure; HttpOnly"; 43static const char kGetTokenPairValidResponse[] = 44 "{" 45 " \"refresh_token\": \"rt1\"," 46 " \"access_token\": \"at1\"," 47 " \"expires_in\": 3600," 48 " \"token_type\": \"Bearer\"" 49 "}"; 50static const char kClientOAuthValidResponse[] = 51 "{" 52 " \"oauth2\": {" 53 " \"refresh_token\": \"rt1\"," 54 " \"access_token\": \"at1\"," 55 " \"expires_in\": 3600," 56 " \"token_type\": \"Bearer\"" 57 " }" 58 "}"; 59 60static void ExpectCaptchaChallenge(const GoogleServiceAuthError& error) { 61 // Make sure this is a captcha server challange. 62 EXPECT_EQ(GoogleServiceAuthError::CAPTCHA_REQUIRED, error.state()); 63 EXPECT_EQ("challengetokenblob", error.captcha().token); 64 EXPECT_EQ("http://www.audio.com/", error.captcha().audio_url.spec()); 65 EXPECT_EQ("http://www.image.com/", error.captcha().image_url.spec()); 66 EXPECT_EQ(640, error.captcha().image_width); 67 EXPECT_EQ(480, error.captcha().image_height); 68} 69 70static void ExpectBadAuth(const GoogleServiceAuthError& error) { 71 EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error.state()); 72} 73 74static void ExpectTwoFactorChallenge(const GoogleServiceAuthError& error) { 75 // Make sure this is a captcha server challange. 76 EXPECT_EQ(GoogleServiceAuthError::TWO_FACTOR, error.state()); 77 EXPECT_EQ("challengetokenblob", error.second_factor().token); 78 EXPECT_EQ("prompt_text", error.second_factor().prompt_text); 79 EXPECT_EQ("alternate_text", error.second_factor().alternate_text); 80 EXPECT_EQ(10, error.second_factor().field_length); 81} 82 83} // namespace 84 85MockFetcher::MockFetcher(bool success, 86 const GURL& url, 87 const std::string& results, 88 net::URLFetcher::RequestType request_type, 89 net::URLFetcherDelegate* d) 90 : TestURLFetcher(0, url, d) { 91 set_url(url); 92 net::URLRequestStatus::Status code; 93 94 if (success) { 95 set_response_code(net::HTTP_OK); 96 code = net::URLRequestStatus::SUCCESS; 97 } else { 98 set_response_code(net::HTTP_FORBIDDEN); 99 code = net::URLRequestStatus::FAILED; 100 } 101 102 set_status(net::URLRequestStatus(code, 0)); 103 SetResponseString(results); 104} 105 106MockFetcher::MockFetcher(const GURL& url, 107 const net::URLRequestStatus& status, 108 int response_code, 109 const net::ResponseCookies& cookies, 110 const std::string& results, 111 net::URLFetcher::RequestType request_type, 112 net::URLFetcherDelegate* d) 113 : TestURLFetcher(0, url, d) { 114 set_url(url); 115 set_status(status); 116 set_response_code(response_code); 117 set_cookies(cookies); 118 SetResponseString(results); 119} 120 121MockFetcher::~MockFetcher() {} 122 123void MockFetcher::Start() { 124 delegate()->OnURLFetchComplete(this); 125} 126 127class GaiaAuthFetcherTest : public testing::Test { 128 public: 129 GaiaAuthFetcherTest() 130 : client_login_source_(GaiaUrls::GetInstance()->client_login_url()), 131 issue_auth_token_source_( 132 GaiaUrls::GetInstance()->issue_auth_token_url()), 133 client_login_to_oauth2_source_( 134 GaiaUrls::GetInstance()->client_login_to_oauth2_url()), 135 oauth2_token_source_(GaiaUrls::GetInstance()->oauth2_token_url()), 136 token_auth_source_(GaiaUrls::GetInstance()->token_auth_url()), 137 merge_session_source_(GaiaUrls::GetInstance()->merge_session_url()), 138 uberauth_token_source_(base::StringPrintf( 139 "%s?source=&issueuberauth=1", 140 GaiaUrls::GetInstance()->oauth1_login_url().c_str())), 141 client_oauth_source_(GaiaUrls::GetInstance()->client_oauth_url()), 142 oauth_login_gurl_(GaiaUrls::GetInstance()->oauth1_login_url()) {} 143 144 void RunParsingTest(const std::string& data, 145 const std::string& sid, 146 const std::string& lsid, 147 const std::string& token) { 148 std::string out_sid; 149 std::string out_lsid; 150 std::string out_token; 151 152 GaiaAuthFetcher::ParseClientLoginResponse(data, 153 &out_sid, 154 &out_lsid, 155 &out_token); 156 EXPECT_EQ(lsid, out_lsid); 157 EXPECT_EQ(sid, out_sid); 158 EXPECT_EQ(token, out_token); 159 } 160 161 void RunErrorParsingTest(const std::string& data, 162 const std::string& error, 163 const std::string& error_url, 164 const std::string& captcha_url, 165 const std::string& captcha_token) { 166 std::string out_error; 167 std::string out_error_url; 168 std::string out_captcha_url; 169 std::string out_captcha_token; 170 171 GaiaAuthFetcher::ParseClientLoginFailure(data, 172 &out_error, 173 &out_error_url, 174 &out_captcha_url, 175 &out_captcha_token); 176 EXPECT_EQ(error, out_error); 177 EXPECT_EQ(error_url, out_error_url); 178 EXPECT_EQ(captcha_url, out_captcha_url); 179 EXPECT_EQ(captcha_token, out_captcha_token); 180 } 181 182 net::ResponseCookies cookies_; 183 GURL client_login_source_; 184 GURL issue_auth_token_source_; 185 GURL client_login_to_oauth2_source_; 186 GURL oauth2_token_source_; 187 GURL token_auth_source_; 188 GURL merge_session_source_; 189 GURL uberauth_token_source_; 190 GURL client_oauth_source_; 191 GURL oauth_login_gurl_; 192 TestingProfile profile_; 193 protected: 194 MessageLoop message_loop_; 195}; 196 197class MockGaiaConsumer : public GaiaAuthConsumer { 198 public: 199 MockGaiaConsumer() {} 200 ~MockGaiaConsumer() {} 201 202 MOCK_METHOD1(OnClientLoginSuccess, void(const ClientLoginResult& result)); 203 MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service, 204 const std::string& token)); 205 MOCK_METHOD1(OnClientOAuthSuccess, 206 void(const GaiaAuthConsumer::ClientOAuthResult& result)); 207 MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data)); 208 MOCK_METHOD1(OnUberAuthTokenSuccess, void(const std::string& data)); 209 MOCK_METHOD1(OnClientLoginFailure, 210 void(const GoogleServiceAuthError& error)); 211 MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service, 212 const GoogleServiceAuthError& error)); 213 MOCK_METHOD1(OnClientOAuthFailure, 214 void(const GoogleServiceAuthError& error)); 215 MOCK_METHOD1(OnMergeSessionFailure, void( 216 const GoogleServiceAuthError& error)); 217 MOCK_METHOD1(OnUberAuthTokenFailure, void( 218 const GoogleServiceAuthError& error)); 219}; 220 221#if defined(OS_WIN) 222#define MAYBE_ErrorComparator DISABLED_ErrorComparator 223#else 224#define MAYBE_ErrorComparator ErrorComparator 225#endif 226 227TEST_F(GaiaAuthFetcherTest, MAYBE_ErrorComparator) { 228 GoogleServiceAuthError expected_error = 229 GoogleServiceAuthError::FromConnectionError(-101); 230 231 GoogleServiceAuthError matching_error = 232 GoogleServiceAuthError::FromConnectionError(-101); 233 234 EXPECT_TRUE(expected_error == matching_error); 235 236 expected_error = GoogleServiceAuthError::FromConnectionError(6); 237 238 EXPECT_FALSE(expected_error == matching_error); 239 240 expected_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE); 241 242 EXPECT_FALSE(expected_error == matching_error); 243 244 matching_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE); 245 246 EXPECT_TRUE(expected_error == matching_error); 247} 248 249TEST_F(GaiaAuthFetcherTest, LoginNetFailure) { 250 int error_no = net::ERR_CONNECTION_RESET; 251 net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no); 252 253 GoogleServiceAuthError expected_error = 254 GoogleServiceAuthError::FromConnectionError(error_no); 255 256 MockGaiaConsumer consumer; 257 EXPECT_CALL(consumer, OnClientLoginFailure(expected_error)) 258 .Times(1); 259 260 GaiaAuthFetcher auth(&consumer, std::string(), 261 profile_.GetRequestContext()); 262 263 MockFetcher mock_fetcher( 264 client_login_source_, status, 0, net::ResponseCookies(), std::string(), 265 net::URLFetcher::GET, &auth); 266 auth.OnURLFetchComplete(&mock_fetcher); 267} 268 269TEST_F(GaiaAuthFetcherTest, TokenNetFailure) { 270 int error_no = net::ERR_CONNECTION_RESET; 271 net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no); 272 273 GoogleServiceAuthError expected_error = 274 GoogleServiceAuthError::FromConnectionError(error_no); 275 276 MockGaiaConsumer consumer; 277 EXPECT_CALL(consumer, OnIssueAuthTokenFailure(_, expected_error)) 278 .Times(1); 279 280 GaiaAuthFetcher auth(&consumer, std::string(), 281 profile_.GetRequestContext()); 282 283 MockFetcher mock_fetcher( 284 issue_auth_token_source_, status, 0, cookies_, std::string(), 285 net::URLFetcher::GET, &auth); 286 auth.OnURLFetchComplete(&mock_fetcher); 287} 288 289 290TEST_F(GaiaAuthFetcherTest, LoginDenied) { 291 std::string data("Error=BadAuthentication"); 292 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 293 294 GoogleServiceAuthError expected_error( 295 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); 296 297 MockGaiaConsumer consumer; 298 EXPECT_CALL(consumer, OnClientLoginFailure(expected_error)) 299 .Times(1); 300 301 GaiaAuthFetcher auth(&consumer, std::string(), 302 profile_.GetRequestContext()); 303 304 MockFetcher mock_fetcher( 305 client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, data, 306 net::URLFetcher::GET, &auth); 307 auth.OnURLFetchComplete(&mock_fetcher); 308} 309 310TEST_F(GaiaAuthFetcherTest, ParseRequest) { 311 RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth\n", "sid", "lsid", "auth"); 312 RunParsingTest("LSID=lsid\nSID=sid\nAuth=auth\n", "sid", "lsid", "auth"); 313 RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth", "sid", "lsid", "auth"); 314 RunParsingTest("SID=sid\nAuth=auth\n", "sid", "", "auth"); 315 RunParsingTest("LSID=lsid\nAuth=auth\n", "", "lsid", "auth"); 316 RunParsingTest("\nAuth=auth\n", "", "", "auth"); 317 RunParsingTest("SID=sid", "sid", "", ""); 318} 319 320TEST_F(GaiaAuthFetcherTest, ParseErrorRequest) { 321 RunErrorParsingTest("Url=U\n" 322 "Error=E\n" 323 "CaptchaToken=T\n" 324 "CaptchaUrl=C\n", "E", "U", "C", "T"); 325 RunErrorParsingTest("CaptchaToken=T\n" 326 "Error=E\n" 327 "Url=U\n" 328 "CaptchaUrl=C\n", "E", "U", "C", "T"); 329 RunErrorParsingTest("\n\n\nCaptchaToken=T\n" 330 "\nError=E\n" 331 "\nUrl=U\n" 332 "CaptchaUrl=C\n", "E", "U", "C", "T"); 333} 334 335 336TEST_F(GaiaAuthFetcherTest, OnlineLogin) { 337 std::string data("SID=sid\nLSID=lsid\nAuth=auth\n"); 338 339 GaiaAuthConsumer::ClientLoginResult result; 340 result.lsid = "lsid"; 341 result.sid = "sid"; 342 result.token = "auth"; 343 result.data = data; 344 345 MockGaiaConsumer consumer; 346 EXPECT_CALL(consumer, OnClientLoginSuccess(result)) 347 .Times(1); 348 349 GaiaAuthFetcher auth(&consumer, std::string(), 350 profile_.GetRequestContext()); 351 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 352 MockFetcher mock_fetcher( 353 client_login_source_, status, net::HTTP_OK, cookies_, data, 354 net::URLFetcher::GET, &auth); 355 auth.OnURLFetchComplete(&mock_fetcher); 356} 357 358TEST_F(GaiaAuthFetcherTest, WorkingIssueAuthToken) { 359 MockGaiaConsumer consumer; 360 EXPECT_CALL(consumer, OnIssueAuthTokenSuccess(_, "token")) 361 .Times(1); 362 363 GaiaAuthFetcher auth(&consumer, std::string(), 364 profile_.GetRequestContext()); 365 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 366 MockFetcher mock_fetcher( 367 issue_auth_token_source_, status, net::HTTP_OK, cookies_, "token", 368 net::URLFetcher::GET, &auth); 369 auth.OnURLFetchComplete(&mock_fetcher); 370} 371 372TEST_F(GaiaAuthFetcherTest, CheckTwoFactorResponse) { 373 std::string response = 374 base::StringPrintf("Error=BadAuthentication\n%s\n", 375 GaiaAuthFetcher::kSecondFactor); 376 EXPECT_TRUE(GaiaAuthFetcher::IsSecondFactorSuccess(response)); 377} 378 379TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) { 380 std::string response = "Error=BadAuthentication\n"; 381 EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response)); 382} 383 384TEST_F(GaiaAuthFetcherTest, TwoFactorLogin) { 385 std::string response = base::StringPrintf("Error=BadAuthentication\n%s\n", 386 GaiaAuthFetcher::kSecondFactor); 387 388 GoogleServiceAuthError error = 389 GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR); 390 391 MockGaiaConsumer consumer; 392 EXPECT_CALL(consumer, OnClientLoginFailure(error)) 393 .Times(1); 394 395 GaiaAuthFetcher auth(&consumer, std::string(), 396 profile_.GetRequestContext()); 397 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 398 MockFetcher mock_fetcher( 399 client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, response, 400 net::URLFetcher::GET, &auth); 401 auth.OnURLFetchComplete(&mock_fetcher); 402} 403 404TEST_F(GaiaAuthFetcherTest, CaptchaParse) { 405 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 406 std::string data = "Url=http://www.google.com/login/captcha\n" 407 "Error=CaptchaRequired\n" 408 "CaptchaToken=CCTOKEN\n" 409 "CaptchaUrl=Captcha?ctoken=CCTOKEN\n"; 410 GoogleServiceAuthError error = 411 GaiaAuthFetcher::GenerateAuthError(data, status); 412 413 std::string token = "CCTOKEN"; 414 GURL image_url("http://accounts.google.com/Captcha?ctoken=CCTOKEN"); 415 GURL unlock_url("http://www.google.com/login/captcha"); 416 417 EXPECT_EQ(error.state(), GoogleServiceAuthError::CAPTCHA_REQUIRED); 418 EXPECT_EQ(error.captcha().token, token); 419 EXPECT_EQ(error.captcha().image_url, image_url); 420 EXPECT_EQ(error.captcha().unlock_url, unlock_url); 421} 422 423TEST_F(GaiaAuthFetcherTest, AccountDeletedError) { 424 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 425 std::string data = "Error=AccountDeleted\n"; 426 GoogleServiceAuthError error = 427 GaiaAuthFetcher::GenerateAuthError(data, status); 428 EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED); 429} 430 431TEST_F(GaiaAuthFetcherTest, AccountDisabledError) { 432 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 433 std::string data = "Error=AccountDisabled\n"; 434 GoogleServiceAuthError error = 435 GaiaAuthFetcher::GenerateAuthError(data, status); 436 EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED); 437} 438 439TEST_F(GaiaAuthFetcherTest,BadAuthenticationError) { 440 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 441 std::string data = "Error=BadAuthentication\n"; 442 GoogleServiceAuthError error = 443 GaiaAuthFetcher::GenerateAuthError(data, status); 444 EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); 445} 446 447TEST_F(GaiaAuthFetcherTest,IncomprehensibleError) { 448 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 449 std::string data = "Error=Gobbledygook\n"; 450 GoogleServiceAuthError error = 451 GaiaAuthFetcher::GenerateAuthError(data, status); 452 EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE); 453} 454 455TEST_F(GaiaAuthFetcherTest,ServiceUnavailableError) { 456 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 457 std::string data = "Error=ServiceUnavailable\n"; 458 GoogleServiceAuthError error = 459 GaiaAuthFetcher::GenerateOAuthLoginError(data, status); 460 EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE); 461} 462 463TEST_F(GaiaAuthFetcherTest, OAuthAccountDeletedError) { 464 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 465 std::string data = "Error=adel\n"; 466 GoogleServiceAuthError error = 467 GaiaAuthFetcher::GenerateOAuthLoginError(data, status); 468 EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED); 469} 470 471TEST_F(GaiaAuthFetcherTest, OAuthAccountDisabledError) { 472 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 473 std::string data = "Error=adis\n"; 474 GoogleServiceAuthError error = 475 GaiaAuthFetcher::GenerateOAuthLoginError(data, status); 476 EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED); 477} 478 479TEST_F(GaiaAuthFetcherTest, OAuthBadAuthenticationError) { 480 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 481 std::string data = "Error=badauth\n"; 482 GoogleServiceAuthError error = 483 GaiaAuthFetcher::GenerateOAuthLoginError(data, status); 484 EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); 485} 486 487TEST_F(GaiaAuthFetcherTest, OAuthServiceUnavailableError) { 488 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 489 std::string data = "Error=ire\n"; 490 GoogleServiceAuthError error = 491 GaiaAuthFetcher::GenerateOAuthLoginError(data, status); 492 EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE); 493} 494 495TEST_F(GaiaAuthFetcherTest, FullLogin) { 496 MockGaiaConsumer consumer; 497 EXPECT_CALL(consumer, OnClientLoginSuccess(_)) 498 .Times(1); 499 500 MockURLFetcherFactory<MockFetcher> factory; 501 502 GaiaAuthFetcher auth(&consumer, std::string(), 503 profile_.GetRequestContext()); 504 auth.StartClientLogin("username", 505 "password", 506 "service", 507 std::string(), 508 std::string(), 509 GaiaAuthFetcher::HostedAccountsAllowed); 510} 511 512TEST_F(GaiaAuthFetcherTest, FullLoginFailure) { 513 MockGaiaConsumer consumer; 514 EXPECT_CALL(consumer, OnClientLoginFailure(_)) 515 .Times(1); 516 517 MockURLFetcherFactory<MockFetcher> factory; 518 factory.set_success(false); 519 520 GaiaAuthFetcher auth(&consumer, std::string(), 521 profile_.GetRequestContext()); 522 auth.StartClientLogin("username", 523 "password", 524 "service", 525 std::string(), 526 std::string(), 527 GaiaAuthFetcher::HostedAccountsAllowed); 528} 529 530TEST_F(GaiaAuthFetcherTest, ClientFetchPending) { 531 MockGaiaConsumer consumer; 532 EXPECT_CALL(consumer, OnClientLoginSuccess(_)) 533 .Times(1); 534 535 net::TestURLFetcherFactory factory; 536 537 GaiaAuthFetcher auth(&consumer, std::string(), 538 profile_.GetRequestContext()); 539 auth.StartClientLogin("username", 540 "password", 541 "service", 542 std::string(), 543 std::string(), 544 GaiaAuthFetcher::HostedAccountsAllowed); 545 546 EXPECT_TRUE(auth.HasPendingFetch()); 547 MockFetcher mock_fetcher( 548 client_login_source_, 549 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 550 net::HTTP_OK, cookies_, "SID=sid\nLSID=lsid\nAuth=auth\n", 551 net::URLFetcher::GET, &auth); 552 auth.OnURLFetchComplete(&mock_fetcher); 553 EXPECT_FALSE(auth.HasPendingFetch()); 554} 555 556TEST_F(GaiaAuthFetcherTest, FullTokenSuccess) { 557 MockGaiaConsumer consumer; 558 EXPECT_CALL(consumer, OnIssueAuthTokenSuccess("service", "token")) 559 .Times(1); 560 561 net::TestURLFetcherFactory factory; 562 GaiaAuthFetcher auth(&consumer, std::string(), 563 profile_.GetRequestContext()); 564 auth.StartIssueAuthToken("sid", "lsid", "service"); 565 566 EXPECT_TRUE(auth.HasPendingFetch()); 567 MockFetcher mock_fetcher( 568 issue_auth_token_source_, 569 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 570 net::HTTP_OK, cookies_, "token", 571 net::URLFetcher::GET, &auth); 572 auth.OnURLFetchComplete(&mock_fetcher); 573 EXPECT_FALSE(auth.HasPendingFetch()); 574} 575 576TEST_F(GaiaAuthFetcherTest, FullTokenFailure) { 577 MockGaiaConsumer consumer; 578 EXPECT_CALL(consumer, OnIssueAuthTokenFailure("service", _)) 579 .Times(1); 580 581 net::TestURLFetcherFactory factory; 582 583 GaiaAuthFetcher auth(&consumer, std::string(), 584 profile_.GetRequestContext()); 585 auth.StartIssueAuthToken("sid", "lsid", "service"); 586 587 EXPECT_TRUE(auth.HasPendingFetch()); 588 MockFetcher mock_fetcher( 589 issue_auth_token_source_, 590 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 591 net::HTTP_FORBIDDEN, cookies_, "", net::URLFetcher::GET, &auth); 592 auth.OnURLFetchComplete(&mock_fetcher); 593 EXPECT_FALSE(auth.HasPendingFetch()); 594} 595 596TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) { 597 MockGaiaConsumer consumer; 598 EXPECT_CALL(consumer, OnClientOAuthSuccess( 599 GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1); 600 601 net::TestURLFetcherFactory factory; 602 GaiaAuthFetcher auth(&consumer, std::string(), 603 profile_.GetRequestContext()); 604 auth.StartLsoForOAuthLoginTokenExchange("lso_token"); 605 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); 606 EXPECT_TRUE(NULL != fetcher); 607 EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES, 608 fetcher->GetLoadFlags()); 609 610 net::ResponseCookies cookies; 611 cookies.push_back(kGetAuthCodeValidCookie); 612 EXPECT_TRUE(auth.HasPendingFetch()); 613 MockFetcher mock_fetcher1( 614 client_login_to_oauth2_source_, 615 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 616 net::HTTP_OK, cookies, "", 617 net::URLFetcher::POST, &auth); 618 auth.OnURLFetchComplete(&mock_fetcher1); 619 EXPECT_TRUE(auth.HasPendingFetch()); 620 MockFetcher mock_fetcher2( 621 oauth2_token_source_, 622 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 623 net::HTTP_OK, cookies_, kGetTokenPairValidResponse, 624 net::URLFetcher::POST, &auth); 625 auth.OnURLFetchComplete(&mock_fetcher2); 626 EXPECT_FALSE(auth.HasPendingFetch()); 627} 628 629TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies) { 630 MockGaiaConsumer consumer; 631 net::TestURLFetcherFactory factory; 632 GaiaAuthFetcher auth(&consumer, std::string(), 633 profile_.GetRequestContext()); 634 auth.StartCookieForOAuthLoginTokenExchange("0"); 635 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); 636 EXPECT_TRUE(NULL != fetcher); 637 EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags()); 638} 639 640TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) { 641 MockGaiaConsumer consumer; 642 EXPECT_CALL(consumer, OnClientOAuthFailure(_)) 643 .Times(1); 644 645 net::TestURLFetcherFactory factory; 646 GaiaAuthFetcher auth(&consumer, std::string(), 647 profile_.GetRequestContext()); 648 auth.StartLsoForOAuthLoginTokenExchange("lso_token"); 649 650 net::ResponseCookies cookies; 651 EXPECT_TRUE(auth.HasPendingFetch()); 652 MockFetcher mock_fetcher( 653 client_login_to_oauth2_source_, 654 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 655 net::HTTP_FORBIDDEN, cookies, "", 656 net::URLFetcher::POST, &auth); 657 auth.OnURLFetchComplete(&mock_fetcher); 658 EXPECT_FALSE(auth.HasPendingFetch()); 659} 660 661TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) { 662 MockGaiaConsumer consumer; 663 EXPECT_CALL(consumer, OnClientOAuthFailure(_)) 664 .Times(1); 665 666 net::TestURLFetcherFactory factory; 667 GaiaAuthFetcher auth(&consumer, std::string(), 668 profile_.GetRequestContext()); 669 auth.StartLsoForOAuthLoginTokenExchange("lso_token"); 670 671 net::ResponseCookies cookies; 672 cookies.push_back(kGetAuthCodeValidCookie); 673 EXPECT_TRUE(auth.HasPendingFetch()); 674 MockFetcher mock_fetcher1( 675 client_login_to_oauth2_source_, 676 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 677 net::HTTP_OK, cookies, "", 678 net::URLFetcher::POST, &auth); 679 auth.OnURLFetchComplete(&mock_fetcher1); 680 EXPECT_TRUE(auth.HasPendingFetch()); 681 MockFetcher mock_fetcher2( 682 oauth2_token_source_, 683 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 684 net::HTTP_FORBIDDEN, cookies_, "", 685 net::URLFetcher::POST, &auth); 686 auth.OnURLFetchComplete(&mock_fetcher2); 687 EXPECT_FALSE(auth.HasPendingFetch()); 688} 689 690TEST_F(GaiaAuthFetcherTest, MergeSessionSuccess) { 691 MockGaiaConsumer consumer; 692 EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>")) 693 .Times(1); 694 695 net::TestURLFetcherFactory factory; 696 697 GaiaAuthFetcher auth(&consumer, std::string(), 698 profile_.GetRequestContext()); 699 auth.StartMergeSession("myubertoken"); 700 701 EXPECT_TRUE(auth.HasPendingFetch()); 702 MockFetcher mock_fetcher( 703 merge_session_source_, 704 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 705 net::HTTP_OK, cookies_, "<html></html>", net::URLFetcher::GET, 706 &auth); 707 auth.OnURLFetchComplete(&mock_fetcher); 708 EXPECT_FALSE(auth.HasPendingFetch()); 709} 710 711TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) { 712 MockGaiaConsumer consumer; 713 EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>")) 714 .Times(1); 715 716 net::TestURLFetcherFactory factory; 717 718 GaiaAuthFetcher auth(&consumer, std::string(), 719 profile_.GetRequestContext()); 720 auth.StartMergeSession("myubertoken"); 721 722 // Make sure the fetcher created has the expected flags. Set its url() 723 // properties to reflect a redirect. 724 net::TestURLFetcher* test_fetcher = factory.GetFetcherByID(0); 725 EXPECT_TRUE(test_fetcher != NULL); 726 EXPECT_TRUE(test_fetcher->GetLoadFlags() == net::LOAD_NORMAL); 727 EXPECT_TRUE(auth.HasPendingFetch()); 728 729 GURL final_url("http://www.google.com/CheckCookie"); 730 test_fetcher->set_url(final_url); 731 test_fetcher->set_status( 732 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0)); 733 test_fetcher->set_response_code(net::HTTP_OK); 734 test_fetcher->set_cookies(cookies_); 735 test_fetcher->SetResponseString("<html></html>"); 736 737 auth.OnURLFetchComplete(test_fetcher); 738 EXPECT_FALSE(auth.HasPendingFetch()); 739} 740 741TEST_F(GaiaAuthFetcherTest, UberAuthTokenSuccess) { 742 MockGaiaConsumer consumer; 743 EXPECT_CALL(consumer, OnUberAuthTokenSuccess("uberToken")) 744 .Times(1); 745 746 net::TestURLFetcherFactory factory; 747 748 GaiaAuthFetcher auth(&consumer, std::string(), 749 profile_.GetRequestContext()); 750 auth.StartTokenFetchForUberAuthExchange("myAccessToken"); 751 752 EXPECT_TRUE(auth.HasPendingFetch()); 753 MockFetcher mock_fetcher( 754 uberauth_token_source_, 755 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), 756 net::HTTP_OK, cookies_, "uberToken", net::URLFetcher::POST, 757 &auth); 758 auth.OnURLFetchComplete(&mock_fetcher); 759 EXPECT_FALSE(auth.HasPendingFetch()); 760} 761 762TEST_F(GaiaAuthFetcherTest, ParseClientLoginToOAuth2Response) { 763 { // No cookies. 764 std::string auth_code; 765 net::ResponseCookies cookies; 766 EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response( 767 cookies, &auth_code)); 768 EXPECT_EQ("", auth_code); 769 } 770 { // Few cookies, nothing appropriate. 771 std::string auth_code; 772 net::ResponseCookies cookies; 773 cookies.push_back(kGetAuthCodeCookieNoSecure); 774 cookies.push_back(kGetAuthCodeCookieNoHttpOnly); 775 cookies.push_back(kGetAuthCodeCookieNoOAuthCode); 776 EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response( 777 cookies, &auth_code)); 778 EXPECT_EQ("", auth_code); 779 } 780 { // Few cookies, one of them is valid. 781 std::string auth_code; 782 net::ResponseCookies cookies; 783 cookies.push_back(kGetAuthCodeCookieNoSecure); 784 cookies.push_back(kGetAuthCodeCookieNoHttpOnly); 785 cookies.push_back(kGetAuthCodeCookieNoOAuthCode); 786 cookies.push_back(kGetAuthCodeValidCookie); 787 EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response( 788 cookies, &auth_code)); 789 EXPECT_EQ("test-code", auth_code); 790 } 791 { // Single valid cookie (like in real responses). 792 std::string auth_code; 793 net::ResponseCookies cookies; 794 cookies.push_back(kGetAuthCodeValidCookie); 795 EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response( 796 cookies, &auth_code)); 797 EXPECT_EQ("test-code", auth_code); 798 } 799} 800 801TEST_F(GaiaAuthFetcherTest, ClientOAuthSuccess) { 802 MockURLFetcherFactory<MockFetcher> factory; 803 factory.set_results(kClientOAuthValidResponse); 804 805 MockGaiaConsumer consumer; 806 EXPECT_CALL(consumer, OnClientOAuthSuccess( 807 GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1); 808 809 GaiaAuthFetcher auth(&consumer, "tests", profile_.GetRequestContext()); 810 std::vector<std::string> scopes; 811 scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope()); 812 scopes.push_back("https://some.other.scope.com"); 813 auth.StartClientOAuth("username", "password", scopes, "", "en"); 814 815 std::string expected_text = base::StringPrintf( 816 "{" 817 "\"email\": \"username\"," 818 "\"password\": \"password\"," 819 "\"scopes\": [\"https://www.google.com/accounts/OAuthLogin\"," 820 " \"https://some.other.scope.com\"]," 821 "\"oauth2_client_id\": \"%s\"," 822 "\"friendly_device_name\": \"tests\"," 823 "\"accepts_challenges\": [\"Captcha\", \"TwoStep\"]," 824 "\"locale\": \"en\"," 825 "\"fallback\": { \"name\": \"GetOAuth2Token\" }" 826 "}", 827 google_apis::GetOAuth2ClientID(google_apis::CLIENT_MAIN).c_str()); 828 829 scoped_ptr<base::Value> actual(base::JSONReader::Read(auth.request_body_)); 830 scoped_ptr<base::Value> expected(base::JSONReader::Read(expected_text)); 831 EXPECT_TRUE(expected->Equals(actual.get())); 832} 833 834TEST_F(GaiaAuthFetcherTest, ClientOAuthWithQuote) { 835 MockURLFetcherFactory<MockFetcher> factory; 836 factory.set_results(kClientOAuthValidResponse); 837 838 MockGaiaConsumer consumer; 839 EXPECT_CALL(consumer, OnClientOAuthSuccess( 840 GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1); 841 842 GaiaAuthFetcher auth(&consumer, "te\"sts", profile_.GetRequestContext()); 843 std::vector<std::string> scopes; 844 scopes.push_back("https://some.\"other.scope.com"); 845 auth.StartClientOAuth("user\"name", "pass\"word", scopes, "", "e\"n"); 846 847 std::string expected_text = base::StringPrintf( 848 "{" 849 "\"email\": \"user\\\"name\"," 850 "\"password\": \"pass\\\"word\"," 851 "\"scopes\": [\"https://some.\\\"other.scope.com\"]," 852 "\"oauth2_client_id\": \"%s\"," 853 "\"friendly_device_name\": \"te\\\"sts\"," 854 "\"accepts_challenges\": [\"Captcha\", \"TwoStep\"]," 855 "\"locale\": \"e\\\"n\"," 856 "\"fallback\": { \"name\": \"GetOAuth2Token\" }" 857 "}", 858 google_apis::GetOAuth2ClientID(google_apis::CLIENT_MAIN).c_str()); 859 scoped_ptr<base::Value> actual(base::JSONReader::Read(auth.request_body_)); 860 scoped_ptr<base::Value> expected(base::JSONReader::Read(expected_text)); 861 EXPECT_TRUE(expected->Equals(actual.get())); 862} 863 864TEST_F(GaiaAuthFetcherTest, ClientOAuthBadAuth) { 865 MockURLFetcherFactory<MockFetcher> factory; 866 factory.set_success(false); 867 factory.set_results("{" 868 " \"cause\" : \"BadAuthentication\"," 869 " \"fallback\" : {" 870 " \"name\" : \"Terminating\"," 871 " \"url\" : \"https://www.terminating.com\"" 872 " }" 873 "}"); 874 875 MockGaiaConsumer consumer; 876 EXPECT_CALL(consumer, OnClientOAuthFailure(_)) 877 .WillOnce(Invoke(ExpectBadAuth)); 878 879 GaiaAuthFetcher auth(&consumer, "tests", profile_.GetRequestContext()); 880 std::vector<std::string> scopes; 881 scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope()); 882 auth.StartClientOAuth("username", "password", scopes, "", "en"); 883} 884 885TEST_F(GaiaAuthFetcherTest, ClientOAuthCaptchaChallenge) { 886 MockURLFetcherFactory<MockFetcher> factory; 887 factory.set_success(false); 888 factory.set_results("{" 889 " \"cause\" : \"NeedsAdditional\"," 890 " \"fallback\" : {" 891 " \"name\" : \"Terminating\"," 892 " \"url\" : \"https://www.terminating.com\"" 893 " }," 894 " \"challenge\" : {" 895 " \"name\" : \"Captcha\"," 896 " \"image_url\" : \"http://www.image.com/\"," 897 " \"image_width\" : 640," 898 " \"image_height\" : 480," 899 " \"audio_url\" : \"http://www.audio.com/\"," 900 " \"challenge_token\" : \"challengetokenblob\"" 901 " }" 902 "}"); 903 904 MockGaiaConsumer consumer; 905 EXPECT_CALL(consumer, OnClientOAuthFailure(_)) 906 .WillOnce(Invoke(ExpectCaptchaChallenge)); 907 908 GaiaAuthFetcher auth(&consumer, "tests", profile_.GetRequestContext()); 909 std::vector<std::string> scopes; 910 scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope()); 911 auth.StartClientOAuth("username", "password", scopes, "", "en"); 912} 913 914TEST_F(GaiaAuthFetcherTest, ClientOAuthTwoFactorChallenge) { 915 MockURLFetcherFactory<MockFetcher> factory; 916 factory.set_success(false); 917 factory.set_results("{" 918 " \"cause\" : \"NeedsAdditional\"," 919 " \"fallback\" : {" 920 " \"name\" : \"Terminating\"," 921 " \"url\" : \"https://www.terminating.com\"" 922 " }," 923 " \"challenge\" : {" 924 " \"name\" : \"TwoStep\"," 925 " \"prompt_text\" : \"prompt_text\"," 926 " \"alternate_text\" : \"alternate_text\"," 927 " \"challenge_token\" : \"challengetokenblob\"," 928 " \"field_length\" : 10" 929 " }" 930 "}"); 931 932 MockGaiaConsumer consumer; 933 EXPECT_CALL(consumer, OnClientOAuthFailure(_)) 934 .WillOnce(Invoke(ExpectTwoFactorChallenge)); 935 936 GaiaAuthFetcher auth(&consumer, "tests", profile_.GetRequestContext()); 937 std::vector<std::string> scopes; 938 scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope()); 939 auth.StartClientOAuth("username", "password", scopes, "", "en"); 940} 941 942TEST_F(GaiaAuthFetcherTest, ClientOAuthChallengeSuccess) { 943 MockURLFetcherFactory<MockFetcher> factory; 944 factory.set_results(kClientOAuthValidResponse); 945 946 MockGaiaConsumer consumer; 947 EXPECT_CALL(consumer, OnClientOAuthSuccess( 948 GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(2); 949 950 GaiaAuthFetcher auth1(&consumer, std::string(), profile_.GetRequestContext()); 951 auth1.StartClientOAuthChallengeResponse(GoogleServiceAuthError::TWO_FACTOR, 952 "token", "mysolution"); 953 954 scoped_ptr<base::Value> actual1(base::JSONReader::Read(auth1.request_body_)); 955 scoped_ptr<base::Value> expected1(base::JSONReader::Read( 956 "{" 957 " \"challenge_reply\" : {" 958 " \"name\" : \"TwoStep\"," 959 " \"challenge_token\" : \"token\"," 960 " \"otp\" : \"mysolution\"" 961 " }" 962 "}")); 963 EXPECT_TRUE(expected1->Equals(actual1.get())); 964 965 GaiaAuthFetcher auth2(&consumer, "tests", profile_.GetRequestContext()); 966 auth2.StartClientOAuthChallengeResponse( 967 GoogleServiceAuthError::CAPTCHA_REQUIRED, "token", "mysolution"); 968 969 scoped_ptr<base::Value> actual2(base::JSONReader::Read(auth2.request_body_)); 970 scoped_ptr<base::Value> expected2(base::JSONReader::Read( 971 "{" 972 " \"challenge_reply\" : {" 973 " \"name\" : \"Captcha\"," 974 " \"challenge_token\" : \"token\"," 975 " \"solution\" : \"mysolution\"" 976 " }" 977 "}")); 978 EXPECT_TRUE(expected2->Equals(actual2.get())); 979} 980 981TEST_F(GaiaAuthFetcherTest, ClientOAuthChallengeQuote) { 982 MockURLFetcherFactory<MockFetcher> factory; 983 factory.set_results(kClientOAuthValidResponse); 984 985 MockGaiaConsumer consumer; 986 EXPECT_CALL(consumer, OnClientOAuthSuccess( 987 GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1); 988 989 GaiaAuthFetcher auth(&consumer, std::string(), profile_.GetRequestContext()); 990 auth.StartClientOAuthChallengeResponse(GoogleServiceAuthError::TWO_FACTOR, 991 "to\"ken", "my\"solution"); 992 993 scoped_ptr<base::Value> actual(base::JSONReader::Read(auth.request_body_)); 994 scoped_ptr<base::Value> expected(base::JSONReader::Read( 995 "{" 996 " \"challenge_reply\" : {" 997 " \"name\" : \"TwoStep\"," 998 " \"challenge_token\" : \"to\\\"ken\"," 999 " \"otp\" : \"my\\\"solution\"" 1000 " }" 1001 "}")); 1002 EXPECT_TRUE(expected->Equals(actual.get())); 1003} 1004 1005TEST_F(GaiaAuthFetcherTest, StartOAuthLogin) { 1006 // OAuthLogin returns the same as the ClientLogin endpoint, minus CAPTCHA 1007 // responses. 1008 std::string data("SID=sid\nLSID=lsid\nAuth=auth\n"); 1009 1010 GaiaAuthConsumer::ClientLoginResult result; 1011 result.lsid = "lsid"; 1012 result.sid = "sid"; 1013 result.token = "auth"; 1014 result.data = data; 1015 1016 MockGaiaConsumer consumer; 1017 EXPECT_CALL(consumer, OnClientLoginSuccess(result)) 1018 .Times(1); 1019 1020 GaiaAuthFetcher auth(&consumer, std::string(), 1021 profile_.GetRequestContext()); 1022 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 1023 MockFetcher mock_fetcher( 1024 oauth_login_gurl_, status, net::HTTP_OK, cookies_, data, 1025 net::URLFetcher::GET, &auth); 1026 auth.OnURLFetchComplete(&mock_fetcher); 1027} 1028