• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/strings/stringprintf.h"
12 #include "base/values.h"
13 #include "google_apis/gaia/gaia_auth_consumer.h"
14 #include "google_apis/gaia/gaia_auth_fetcher.h"
15 #include "google_apis/gaia/gaia_urls.h"
16 #include "google_apis/gaia/google_service_auth_error.h"
17 #include "google_apis/gaia/mock_url_fetcher_factory.h"
18 #include "google_apis/google_api_keys.h"
19 #include "net/base/load_flags.h"
20 #include "net/base/net_errors.h"
21 #include "net/http/http_status_code.h"
22 #include "net/url_request/test_url_fetcher_factory.h"
23 #include "net/url_request/url_fetcher_delegate.h"
24 #include "net/url_request/url_request_status.h"
25 #include "net/url_request/url_request_test_util.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "url/gurl.h"
29 
30 using ::testing::Invoke;
31 using ::testing::_;
32 
33 const char kGetAuthCodeValidCookie[] =
34     "oauth_code=test-code; Path=/test; Secure; HttpOnly";
35 const char kGetAuthCodeCookieNoSecure[] =
36     "oauth_code=test-code; Path=/test; HttpOnly";
37 const char kGetAuthCodeCookieNoHttpOnly[] =
38     "oauth_code=test-code; Path=/test; Secure";
39 const char kGetAuthCodeCookieNoOAuthCode[] =
40     "Path=/test; Secure; HttpOnly";
41 const char kGetTokenPairValidResponse[] =
42     "{"
43     "  \"refresh_token\": \"rt1\","
44     "  \"access_token\": \"at1\","
45     "  \"expires_in\": 3600,"
46     "  \"token_type\": \"Bearer\""
47     "}";
48 
MockFetcher(bool success,const GURL & url,const std::string & results,net::URLFetcher::RequestType request_type,net::URLFetcherDelegate * d)49 MockFetcher::MockFetcher(bool success,
50                          const GURL& url,
51                          const std::string& results,
52                          net::URLFetcher::RequestType request_type,
53                          net::URLFetcherDelegate* d)
54     : TestURLFetcher(0, url, d) {
55   set_url(url);
56   net::URLRequestStatus::Status code;
57 
58   if (success) {
59     set_response_code(net::HTTP_OK);
60     code = net::URLRequestStatus::SUCCESS;
61   } else {
62     set_response_code(net::HTTP_FORBIDDEN);
63     code = net::URLRequestStatus::FAILED;
64   }
65 
66   set_status(net::URLRequestStatus(code, 0));
67   SetResponseString(results);
68 }
69 
MockFetcher(const GURL & url,const net::URLRequestStatus & status,int response_code,const net::ResponseCookies & cookies,const std::string & results,net::URLFetcher::RequestType request_type,net::URLFetcherDelegate * d)70 MockFetcher::MockFetcher(const GURL& url,
71                          const net::URLRequestStatus& status,
72                          int response_code,
73                          const net::ResponseCookies& cookies,
74                          const std::string& results,
75                          net::URLFetcher::RequestType request_type,
76                          net::URLFetcherDelegate* d)
77     : TestURLFetcher(0, url, d) {
78   set_url(url);
79   set_status(status);
80   set_response_code(response_code);
81   set_cookies(cookies);
82   SetResponseString(results);
83 }
84 
~MockFetcher()85 MockFetcher::~MockFetcher() {}
86 
Start()87 void MockFetcher::Start() {
88   delegate()->OnURLFetchComplete(this);
89 }
90 
91 class GaiaAuthFetcherTest : public testing::Test {
92  protected:
GaiaAuthFetcherTest()93   GaiaAuthFetcherTest()
94       : client_login_source_(GaiaUrls::GetInstance()->client_login_url()),
95         issue_auth_token_source_(
96             GaiaUrls::GetInstance()->issue_auth_token_url()),
97         client_login_to_oauth2_source_(
98             GaiaUrls::GetInstance()->client_login_to_oauth2_url()),
99         oauth2_token_source_(GaiaUrls::GetInstance()->oauth2_token_url()),
100         token_auth_source_(GaiaUrls::GetInstance()->token_auth_url()),
101         merge_session_source_(GaiaUrls::GetInstance()->merge_session_url()),
102         uberauth_token_source_(
103             GaiaUrls::GetInstance()->oauth1_login_url().Resolve(
104                 "?source=&issueuberauth=1")),
105         oauth_login_gurl_(GaiaUrls::GetInstance()->oauth1_login_url()) {}
106 
RunParsingTest(const std::string & data,const std::string & sid,const std::string & lsid,const std::string & token)107   void RunParsingTest(const std::string& data,
108                       const std::string& sid,
109                       const std::string& lsid,
110                       const std::string& token) {
111     std::string out_sid;
112     std::string out_lsid;
113     std::string out_token;
114 
115     GaiaAuthFetcher::ParseClientLoginResponse(data,
116                                               &out_sid,
117                                               &out_lsid,
118                                               &out_token);
119     EXPECT_EQ(lsid, out_lsid);
120     EXPECT_EQ(sid, out_sid);
121     EXPECT_EQ(token, out_token);
122   }
123 
RunErrorParsingTest(const std::string & data,const std::string & error,const std::string & error_url,const std::string & captcha_url,const std::string & captcha_token)124   void RunErrorParsingTest(const std::string& data,
125                            const std::string& error,
126                            const std::string& error_url,
127                            const std::string& captcha_url,
128                            const std::string& captcha_token) {
129     std::string out_error;
130     std::string out_error_url;
131     std::string out_captcha_url;
132     std::string out_captcha_token;
133 
134     GaiaAuthFetcher::ParseClientLoginFailure(data,
135                                              &out_error,
136                                              &out_error_url,
137                                              &out_captcha_url,
138                                              &out_captcha_token);
139     EXPECT_EQ(error, out_error);
140     EXPECT_EQ(error_url, out_error_url);
141     EXPECT_EQ(captcha_url, out_captcha_url);
142     EXPECT_EQ(captcha_token, out_captcha_token);
143   }
144 
145   net::ResponseCookies cookies_;
146   GURL client_login_source_;
147   GURL issue_auth_token_source_;
148   GURL client_login_to_oauth2_source_;
149   GURL oauth2_token_source_;
150   GURL token_auth_source_;
151   GURL merge_session_source_;
152   GURL uberauth_token_source_;
153   GURL oauth_login_gurl_;
154 
155  protected:
GetRequestContext()156   net::TestURLRequestContextGetter* GetRequestContext() {
157     if (!request_context_getter_) {
158       request_context_getter_ = new net::TestURLRequestContextGetter(
159           message_loop_.message_loop_proxy());
160     }
161     return request_context_getter_;
162   }
163 
164   base::MessageLoop message_loop_;
165   scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
166 };
167 
168 class MockGaiaConsumer : public GaiaAuthConsumer {
169  public:
MockGaiaConsumer()170   MockGaiaConsumer() {}
~MockGaiaConsumer()171   ~MockGaiaConsumer() {}
172 
173   MOCK_METHOD1(OnClientLoginSuccess, void(const ClientLoginResult& result));
174   MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service,
175       const std::string& token));
176   MOCK_METHOD1(OnClientOAuthSuccess,
177                void(const GaiaAuthConsumer::ClientOAuthResult& result));
178   MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
179   MOCK_METHOD1(OnUberAuthTokenSuccess, void(const std::string& data));
180   MOCK_METHOD1(OnClientLoginFailure,
181       void(const GoogleServiceAuthError& error));
182   MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service,
183       const GoogleServiceAuthError& error));
184   MOCK_METHOD1(OnClientOAuthFailure,
185       void(const GoogleServiceAuthError& error));
186   MOCK_METHOD1(OnMergeSessionFailure, void(
187       const GoogleServiceAuthError& error));
188   MOCK_METHOD1(OnUberAuthTokenFailure, void(
189       const GoogleServiceAuthError& error));
190   MOCK_METHOD1(OnListAccountsSuccess, void(const std::string& data));
191 };
192 
193 #if defined(OS_WIN)
194 #define MAYBE_ErrorComparator DISABLED_ErrorComparator
195 #else
196 #define MAYBE_ErrorComparator ErrorComparator
197 #endif
198 
TEST_F(GaiaAuthFetcherTest,MAYBE_ErrorComparator)199 TEST_F(GaiaAuthFetcherTest, MAYBE_ErrorComparator) {
200   GoogleServiceAuthError expected_error =
201       GoogleServiceAuthError::FromConnectionError(-101);
202 
203   GoogleServiceAuthError matching_error =
204       GoogleServiceAuthError::FromConnectionError(-101);
205 
206   EXPECT_TRUE(expected_error == matching_error);
207 
208   expected_error = GoogleServiceAuthError::FromConnectionError(6);
209 
210   EXPECT_FALSE(expected_error == matching_error);
211 
212   expected_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
213 
214   EXPECT_FALSE(expected_error == matching_error);
215 
216   matching_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
217 
218   EXPECT_TRUE(expected_error == matching_error);
219 }
220 
TEST_F(GaiaAuthFetcherTest,LoginNetFailure)221 TEST_F(GaiaAuthFetcherTest, LoginNetFailure) {
222   int error_no = net::ERR_CONNECTION_RESET;
223   net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
224 
225   GoogleServiceAuthError expected_error =
226       GoogleServiceAuthError::FromConnectionError(error_no);
227 
228   MockGaiaConsumer consumer;
229   EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
230       .Times(1);
231 
232   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
233 
234   MockFetcher mock_fetcher(
235       client_login_source_, status, 0, net::ResponseCookies(), std::string(),
236       net::URLFetcher::GET, &auth);
237   auth.OnURLFetchComplete(&mock_fetcher);
238 }
239 
TEST_F(GaiaAuthFetcherTest,TokenNetFailure)240 TEST_F(GaiaAuthFetcherTest, TokenNetFailure) {
241   int error_no = net::ERR_CONNECTION_RESET;
242   net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
243 
244   GoogleServiceAuthError expected_error =
245       GoogleServiceAuthError::FromConnectionError(error_no);
246 
247   MockGaiaConsumer consumer;
248   EXPECT_CALL(consumer, OnIssueAuthTokenFailure(_, expected_error))
249       .Times(1);
250 
251   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
252 
253   MockFetcher mock_fetcher(
254       issue_auth_token_source_, status, 0, cookies_, std::string(),
255       net::URLFetcher::GET, &auth);
256   auth.OnURLFetchComplete(&mock_fetcher);
257 }
258 
259 
TEST_F(GaiaAuthFetcherTest,LoginDenied)260 TEST_F(GaiaAuthFetcherTest, LoginDenied) {
261   std::string data("Error=BadAuthentication");
262   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
263 
264   GoogleServiceAuthError expected_error(
265       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
266 
267   MockGaiaConsumer consumer;
268   EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
269       .Times(1);
270 
271   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
272 
273   MockFetcher mock_fetcher(
274       client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, data,
275       net::URLFetcher::GET, &auth);
276   auth.OnURLFetchComplete(&mock_fetcher);
277 }
278 
TEST_F(GaiaAuthFetcherTest,ParseRequest)279 TEST_F(GaiaAuthFetcherTest, ParseRequest) {
280   RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth\n", "sid", "lsid", "auth");
281   RunParsingTest("LSID=lsid\nSID=sid\nAuth=auth\n", "sid", "lsid", "auth");
282   RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth", "sid", "lsid", "auth");
283   RunParsingTest("SID=sid\nAuth=auth\n", "sid", std::string(), "auth");
284   RunParsingTest("LSID=lsid\nAuth=auth\n", std::string(), "lsid", "auth");
285   RunParsingTest("\nAuth=auth\n", std::string(), std::string(), "auth");
286   RunParsingTest("SID=sid", "sid", std::string(), std::string());
287 }
288 
TEST_F(GaiaAuthFetcherTest,ParseErrorRequest)289 TEST_F(GaiaAuthFetcherTest, ParseErrorRequest) {
290   RunErrorParsingTest("Url=U\n"
291                       "Error=E\n"
292                       "CaptchaToken=T\n"
293                       "CaptchaUrl=C\n", "E", "U", "C", "T");
294   RunErrorParsingTest("CaptchaToken=T\n"
295                       "Error=E\n"
296                       "Url=U\n"
297                       "CaptchaUrl=C\n", "E", "U", "C", "T");
298   RunErrorParsingTest("\n\n\nCaptchaToken=T\n"
299                       "\nError=E\n"
300                       "\nUrl=U\n"
301                       "CaptchaUrl=C\n", "E", "U", "C", "T");
302 }
303 
304 
TEST_F(GaiaAuthFetcherTest,OnlineLogin)305 TEST_F(GaiaAuthFetcherTest, OnlineLogin) {
306   std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
307 
308   GaiaAuthConsumer::ClientLoginResult result;
309   result.lsid = "lsid";
310   result.sid = "sid";
311   result.token = "auth";
312   result.data = data;
313 
314   MockGaiaConsumer consumer;
315   EXPECT_CALL(consumer, OnClientLoginSuccess(result))
316       .Times(1);
317 
318   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
319   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
320   MockFetcher mock_fetcher(
321       client_login_source_, status, net::HTTP_OK, cookies_, data,
322       net::URLFetcher::GET, &auth);
323   auth.OnURLFetchComplete(&mock_fetcher);
324 }
325 
TEST_F(GaiaAuthFetcherTest,WorkingIssueAuthToken)326 TEST_F(GaiaAuthFetcherTest, WorkingIssueAuthToken) {
327   MockGaiaConsumer consumer;
328   EXPECT_CALL(consumer, OnIssueAuthTokenSuccess(_, "token"))
329       .Times(1);
330 
331   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
332   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
333   MockFetcher mock_fetcher(
334       issue_auth_token_source_, status, net::HTTP_OK, cookies_, "token",
335       net::URLFetcher::GET, &auth);
336   auth.OnURLFetchComplete(&mock_fetcher);
337 }
338 
TEST_F(GaiaAuthFetcherTest,CheckTwoFactorResponse)339 TEST_F(GaiaAuthFetcherTest, CheckTwoFactorResponse) {
340   std::string response =
341       base::StringPrintf("Error=BadAuthentication\n%s\n",
342                          GaiaAuthFetcher::kSecondFactor);
343   EXPECT_TRUE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
344 }
345 
TEST_F(GaiaAuthFetcherTest,CheckNormalErrorCode)346 TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
347   std::string response = "Error=BadAuthentication\n";
348   EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
349 }
350 
TEST_F(GaiaAuthFetcherTest,TwoFactorLogin)351 TEST_F(GaiaAuthFetcherTest, TwoFactorLogin) {
352   std::string response = base::StringPrintf("Error=BadAuthentication\n%s\n",
353       GaiaAuthFetcher::kSecondFactor);
354 
355   GoogleServiceAuthError error =
356       GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR);
357 
358   MockGaiaConsumer consumer;
359   EXPECT_CALL(consumer, OnClientLoginFailure(error))
360       .Times(1);
361 
362   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
363   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
364   MockFetcher mock_fetcher(
365       client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, response,
366       net::URLFetcher::GET, &auth);
367   auth.OnURLFetchComplete(&mock_fetcher);
368 }
369 
TEST_F(GaiaAuthFetcherTest,CaptchaParse)370 TEST_F(GaiaAuthFetcherTest, CaptchaParse) {
371   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
372   std::string data = "Url=http://www.google.com/login/captcha\n"
373                      "Error=CaptchaRequired\n"
374                      "CaptchaToken=CCTOKEN\n"
375                      "CaptchaUrl=Captcha?ctoken=CCTOKEN\n";
376   GoogleServiceAuthError error =
377       GaiaAuthFetcher::GenerateAuthError(data, status);
378 
379   std::string token = "CCTOKEN";
380   GURL image_url("http://accounts.google.com/Captcha?ctoken=CCTOKEN");
381   GURL unlock_url("http://www.google.com/login/captcha");
382 
383   EXPECT_EQ(error.state(), GoogleServiceAuthError::CAPTCHA_REQUIRED);
384   EXPECT_EQ(error.captcha().token, token);
385   EXPECT_EQ(error.captcha().image_url, image_url);
386   EXPECT_EQ(error.captcha().unlock_url, unlock_url);
387 }
388 
TEST_F(GaiaAuthFetcherTest,AccountDeletedError)389 TEST_F(GaiaAuthFetcherTest, AccountDeletedError) {
390   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
391   std::string data = "Error=AccountDeleted\n";
392   GoogleServiceAuthError error =
393       GaiaAuthFetcher::GenerateAuthError(data, status);
394   EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
395 }
396 
TEST_F(GaiaAuthFetcherTest,AccountDisabledError)397 TEST_F(GaiaAuthFetcherTest, AccountDisabledError) {
398   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
399   std::string data = "Error=AccountDisabled\n";
400   GoogleServiceAuthError error =
401       GaiaAuthFetcher::GenerateAuthError(data, status);
402   EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
403 }
404 
TEST_F(GaiaAuthFetcherTest,BadAuthenticationError)405 TEST_F(GaiaAuthFetcherTest, BadAuthenticationError) {
406   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
407   std::string data = "Error=BadAuthentication\n";
408   GoogleServiceAuthError error =
409       GaiaAuthFetcher::GenerateAuthError(data, status);
410   EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
411 }
412 
TEST_F(GaiaAuthFetcherTest,IncomprehensibleError)413 TEST_F(GaiaAuthFetcherTest, IncomprehensibleError) {
414   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
415   std::string data = "Error=Gobbledygook\n";
416   GoogleServiceAuthError error =
417       GaiaAuthFetcher::GenerateAuthError(data, status);
418   EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
419 }
420 
TEST_F(GaiaAuthFetcherTest,ServiceUnavailableError)421 TEST_F(GaiaAuthFetcherTest, ServiceUnavailableError) {
422   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
423   std::string data = "Error=ServiceUnavailable\n";
424   GoogleServiceAuthError error =
425       GaiaAuthFetcher::GenerateAuthError(data, status);
426   EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
427 }
428 
TEST_F(GaiaAuthFetcherTest,FullLogin)429 TEST_F(GaiaAuthFetcherTest, FullLogin) {
430   MockGaiaConsumer consumer;
431   EXPECT_CALL(consumer, OnClientLoginSuccess(_))
432       .Times(1);
433 
434   MockURLFetcherFactory<MockFetcher> factory;
435 
436   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
437   auth.StartClientLogin("username",
438                         "password",
439                         "service",
440                         std::string(),
441                         std::string(),
442                         GaiaAuthFetcher::HostedAccountsAllowed);
443 }
444 
TEST_F(GaiaAuthFetcherTest,FullLoginFailure)445 TEST_F(GaiaAuthFetcherTest, FullLoginFailure) {
446   MockGaiaConsumer consumer;
447   EXPECT_CALL(consumer, OnClientLoginFailure(_))
448       .Times(1);
449 
450   MockURLFetcherFactory<MockFetcher> factory;
451   factory.set_success(false);
452 
453   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
454   auth.StartClientLogin("username",
455                         "password",
456                         "service",
457                         std::string(),
458                         std::string(),
459                         GaiaAuthFetcher::HostedAccountsAllowed);
460 }
461 
TEST_F(GaiaAuthFetcherTest,ClientFetchPending)462 TEST_F(GaiaAuthFetcherTest, ClientFetchPending) {
463   MockGaiaConsumer consumer;
464   EXPECT_CALL(consumer, OnClientLoginSuccess(_))
465       .Times(1);
466 
467   net::TestURLFetcherFactory factory;
468 
469   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
470   auth.StartClientLogin("username",
471                         "password",
472                         "service",
473                         std::string(),
474                         std::string(),
475                         GaiaAuthFetcher::HostedAccountsAllowed);
476 
477   EXPECT_TRUE(auth.HasPendingFetch());
478   MockFetcher mock_fetcher(
479       client_login_source_,
480       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
481       net::HTTP_OK, cookies_, "SID=sid\nLSID=lsid\nAuth=auth\n",
482       net::URLFetcher::GET, &auth);
483   auth.OnURLFetchComplete(&mock_fetcher);
484   EXPECT_FALSE(auth.HasPendingFetch());
485 }
486 
TEST_F(GaiaAuthFetcherTest,FullTokenSuccess)487 TEST_F(GaiaAuthFetcherTest, FullTokenSuccess) {
488   MockGaiaConsumer consumer;
489   EXPECT_CALL(consumer, OnIssueAuthTokenSuccess("service", "token"))
490       .Times(1);
491 
492   net::TestURLFetcherFactory factory;
493   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
494   auth.StartIssueAuthToken("sid", "lsid", "service");
495 
496   EXPECT_TRUE(auth.HasPendingFetch());
497   MockFetcher mock_fetcher(
498       issue_auth_token_source_,
499       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
500       net::HTTP_OK, cookies_, "token",
501       net::URLFetcher::GET, &auth);
502   auth.OnURLFetchComplete(&mock_fetcher);
503   EXPECT_FALSE(auth.HasPendingFetch());
504 }
505 
TEST_F(GaiaAuthFetcherTest,FullTokenFailure)506 TEST_F(GaiaAuthFetcherTest, FullTokenFailure) {
507   MockGaiaConsumer consumer;
508   EXPECT_CALL(consumer, OnIssueAuthTokenFailure("service", _))
509       .Times(1);
510 
511   net::TestURLFetcherFactory factory;
512 
513   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
514   auth.StartIssueAuthToken("sid", "lsid", "service");
515 
516   EXPECT_TRUE(auth.HasPendingFetch());
517   MockFetcher mock_fetcher(
518       issue_auth_token_source_,
519       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
520       net::HTTP_FORBIDDEN,
521       cookies_,
522       std::string(),
523       net::URLFetcher::GET,
524       &auth);
525   auth.OnURLFetchComplete(&mock_fetcher);
526   EXPECT_FALSE(auth.HasPendingFetch());
527 }
528 
TEST_F(GaiaAuthFetcherTest,OAuthLoginTokenSuccess)529 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) {
530   MockGaiaConsumer consumer;
531   EXPECT_CALL(consumer, OnClientOAuthSuccess(
532       GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1);
533 
534   net::TestURLFetcherFactory factory;
535   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
536   auth.StartLsoForOAuthLoginTokenExchange("lso_token");
537   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
538   EXPECT_TRUE(NULL != fetcher);
539   EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES,
540             fetcher->GetLoadFlags());
541 
542   net::ResponseCookies cookies;
543   cookies.push_back(kGetAuthCodeValidCookie);
544   EXPECT_TRUE(auth.HasPendingFetch());
545   MockFetcher mock_fetcher1(
546       client_login_to_oauth2_source_,
547       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
548       net::HTTP_OK,
549       cookies,
550       std::string(),
551       net::URLFetcher::POST,
552       &auth);
553   auth.OnURLFetchComplete(&mock_fetcher1);
554   EXPECT_TRUE(auth.HasPendingFetch());
555   MockFetcher mock_fetcher2(
556       oauth2_token_source_,
557       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
558       net::HTTP_OK, cookies_, kGetTokenPairValidResponse,
559       net::URLFetcher::POST, &auth);
560   auth.OnURLFetchComplete(&mock_fetcher2);
561   EXPECT_FALSE(auth.HasPendingFetch());
562 }
563 
TEST_F(GaiaAuthFetcherTest,OAuthLoginTokenWithCookies)564 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies) {
565   MockGaiaConsumer consumer;
566   net::TestURLFetcherFactory factory;
567   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
568   auth.StartCookieForOAuthLoginTokenExchange("0");
569   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
570   EXPECT_TRUE(NULL != fetcher);
571   EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
572   EXPECT_FALSE(EndsWith(fetcher->upload_data(), "device_type=chrome", true));
573 }
574 
TEST_F(GaiaAuthFetcherTest,OAuthLoginTokenWithCookies_DeviceId)575 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies_DeviceId) {
576   MockGaiaConsumer consumer;
577   net::TestURLFetcherFactory factory;
578   std::string expected_device_id("ABCDE-12345");
579   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
580   auth.StartCookieForOAuthLoginTokenExchangeWithDeviceId("0",
581                                                          expected_device_id);
582   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
583   EXPECT_TRUE(NULL != fetcher);
584   EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
585   EXPECT_TRUE(EndsWith(fetcher->upload_data(), "device_type=chrome", true));
586   net::HttpRequestHeaders extra_request_headers;
587   fetcher->GetExtraRequestHeaders(&extra_request_headers);
588   std::string device_id;
589   EXPECT_TRUE(extra_request_headers.GetHeader("X-Device-ID", &device_id));
590   EXPECT_EQ(device_id, expected_device_id);
591 }
592 
TEST_F(GaiaAuthFetcherTest,OAuthLoginTokenClientLoginToOAuth2Failure)593 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) {
594   MockGaiaConsumer consumer;
595   EXPECT_CALL(consumer, OnClientOAuthFailure(_))
596       .Times(1);
597 
598   net::TestURLFetcherFactory factory;
599   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
600   auth.StartLsoForOAuthLoginTokenExchange("lso_token");
601 
602   net::ResponseCookies cookies;
603   EXPECT_TRUE(auth.HasPendingFetch());
604   MockFetcher mock_fetcher(
605       client_login_to_oauth2_source_,
606       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
607       net::HTTP_FORBIDDEN,
608       cookies,
609       std::string(),
610       net::URLFetcher::POST,
611       &auth);
612   auth.OnURLFetchComplete(&mock_fetcher);
613   EXPECT_FALSE(auth.HasPendingFetch());
614 }
615 
TEST_F(GaiaAuthFetcherTest,OAuthLoginTokenOAuth2TokenPairFailure)616 TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) {
617   MockGaiaConsumer consumer;
618   EXPECT_CALL(consumer, OnClientOAuthFailure(_))
619       .Times(1);
620 
621   net::TestURLFetcherFactory factory;
622   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
623   auth.StartLsoForOAuthLoginTokenExchange("lso_token");
624 
625   net::ResponseCookies cookies;
626   cookies.push_back(kGetAuthCodeValidCookie);
627   EXPECT_TRUE(auth.HasPendingFetch());
628   MockFetcher mock_fetcher1(
629       client_login_to_oauth2_source_,
630       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
631       net::HTTP_OK,
632       cookies,
633       std::string(),
634       net::URLFetcher::POST,
635       &auth);
636   auth.OnURLFetchComplete(&mock_fetcher1);
637   EXPECT_TRUE(auth.HasPendingFetch());
638   MockFetcher mock_fetcher2(
639       oauth2_token_source_,
640       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
641       net::HTTP_FORBIDDEN,
642       cookies_,
643       std::string(),
644       net::URLFetcher::POST,
645       &auth);
646   auth.OnURLFetchComplete(&mock_fetcher2);
647   EXPECT_FALSE(auth.HasPendingFetch());
648 }
649 
TEST_F(GaiaAuthFetcherTest,MergeSessionSuccess)650 TEST_F(GaiaAuthFetcherTest, MergeSessionSuccess) {
651   MockGaiaConsumer consumer;
652   EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
653       .Times(1);
654 
655   net::TestURLFetcherFactory factory;
656 
657   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
658   auth.StartMergeSession("myubertoken");
659 
660   EXPECT_TRUE(auth.HasPendingFetch());
661   MockFetcher mock_fetcher(
662       merge_session_source_,
663       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
664       net::HTTP_OK, cookies_, "<html></html>", net::URLFetcher::GET,
665       &auth);
666   auth.OnURLFetchComplete(&mock_fetcher);
667   EXPECT_FALSE(auth.HasPendingFetch());
668 }
669 
TEST_F(GaiaAuthFetcherTest,MergeSessionSuccessRedirect)670 TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) {
671   MockGaiaConsumer consumer;
672   EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
673       .Times(1);
674 
675   net::TestURLFetcherFactory factory;
676 
677   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
678   auth.StartMergeSession("myubertoken");
679 
680   // Make sure the fetcher created has the expected flags.  Set its url()
681   // properties to reflect a redirect.
682   net::TestURLFetcher* test_fetcher = factory.GetFetcherByID(0);
683   EXPECT_TRUE(test_fetcher != NULL);
684   EXPECT_TRUE(test_fetcher->GetLoadFlags() == net::LOAD_NORMAL);
685   EXPECT_TRUE(auth.HasPendingFetch());
686 
687   GURL final_url("http://www.google.com/CheckCookie");
688   test_fetcher->set_url(final_url);
689   test_fetcher->set_status(
690       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
691   test_fetcher->set_response_code(net::HTTP_OK);
692   test_fetcher->set_cookies(cookies_);
693   test_fetcher->SetResponseString("<html></html>");
694 
695   auth.OnURLFetchComplete(test_fetcher);
696   EXPECT_FALSE(auth.HasPendingFetch());
697 }
698 
TEST_F(GaiaAuthFetcherTest,UberAuthTokenSuccess)699 TEST_F(GaiaAuthFetcherTest, UberAuthTokenSuccess) {
700   MockGaiaConsumer consumer;
701   EXPECT_CALL(consumer, OnUberAuthTokenSuccess("uberToken"))
702       .Times(1);
703 
704   net::TestURLFetcherFactory factory;
705 
706   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
707   auth.StartTokenFetchForUberAuthExchange("myAccessToken");
708 
709   EXPECT_TRUE(auth.HasPendingFetch());
710   MockFetcher mock_fetcher(
711       uberauth_token_source_,
712       net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
713       net::HTTP_OK, cookies_, "uberToken", net::URLFetcher::POST,
714       &auth);
715   auth.OnURLFetchComplete(&mock_fetcher);
716   EXPECT_FALSE(auth.HasPendingFetch());
717 }
718 
TEST_F(GaiaAuthFetcherTest,ParseClientLoginToOAuth2Response)719 TEST_F(GaiaAuthFetcherTest, ParseClientLoginToOAuth2Response) {
720   {  // No cookies.
721     std::string auth_code;
722     net::ResponseCookies cookies;
723     EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
724         cookies, &auth_code));
725     EXPECT_EQ("", auth_code);
726   }
727   {  // Few cookies, nothing appropriate.
728     std::string auth_code;
729     net::ResponseCookies cookies;
730     cookies.push_back(kGetAuthCodeCookieNoSecure);
731     cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
732     cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
733     EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
734         cookies, &auth_code));
735     EXPECT_EQ("", auth_code);
736   }
737   {  // Few cookies, one of them is valid.
738     std::string auth_code;
739     net::ResponseCookies cookies;
740     cookies.push_back(kGetAuthCodeCookieNoSecure);
741     cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
742     cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
743     cookies.push_back(kGetAuthCodeValidCookie);
744     EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
745         cookies, &auth_code));
746     EXPECT_EQ("test-code", auth_code);
747   }
748   {  // Single valid cookie (like in real responses).
749     std::string auth_code;
750     net::ResponseCookies cookies;
751     cookies.push_back(kGetAuthCodeValidCookie);
752     EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
753         cookies, &auth_code));
754     EXPECT_EQ("test-code", auth_code);
755   }
756 }
757 
TEST_F(GaiaAuthFetcherTest,StartOAuthLogin)758 TEST_F(GaiaAuthFetcherTest, StartOAuthLogin) {
759   // OAuthLogin returns the same as the ClientLogin endpoint, minus CAPTCHA
760   // responses.
761   std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
762 
763   GaiaAuthConsumer::ClientLoginResult result;
764   result.lsid = "lsid";
765   result.sid = "sid";
766   result.token = "auth";
767   result.data = data;
768 
769   MockGaiaConsumer consumer;
770   EXPECT_CALL(consumer, OnClientLoginSuccess(result))
771       .Times(1);
772 
773   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
774   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
775   MockFetcher mock_fetcher(
776       oauth_login_gurl_, status, net::HTTP_OK, cookies_, data,
777       net::URLFetcher::GET, &auth);
778   auth.OnURLFetchComplete(&mock_fetcher);
779 }
780 
TEST_F(GaiaAuthFetcherTest,ListAccounts)781 TEST_F(GaiaAuthFetcherTest, ListAccounts) {
782   std::string data("[\"gaia.l.a.r\", ["
783       "[\"gaia.l.a\", 1, \"First Last\", \"user@gmail.com\", "
784       "\"//googleusercontent.com/A/B/C/D/photo.jpg\", 1, 1, 0]]]");
785   MockGaiaConsumer consumer;
786   EXPECT_CALL(consumer, OnListAccountsSuccess(data)).Times(1);
787 
788   GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
789   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
790   MockFetcher mock_fetcher(GaiaUrls::GetInstance()->list_accounts_url(),
791       status, net::HTTP_OK, cookies_, data, net::URLFetcher::GET, &auth);
792   auth.OnURLFetchComplete(&mock_fetcher);
793 }
794