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