gaia_auth_fetcher_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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
30using ::testing::Invoke;
31using ::testing::_;
32
33const char kGetAuthCodeValidCookie[] =
34    "oauth_code=test-code; Path=/test; Secure; HttpOnly";
35const char kGetAuthCodeCookieNoSecure[] =
36    "oauth_code=test-code; Path=/test; HttpOnly";
37const char kGetAuthCodeCookieNoHttpOnly[] =
38    "oauth_code=test-code; Path=/test; Secure";
39const char kGetAuthCodeCookieNoOAuthCode[] =
40    "Path=/test; Secure; HttpOnly";
41const char kGetTokenPairValidResponse[] =
42    "{"
43    "  \"refresh_token\": \"rt1\","
44    "  \"access_token\": \"at1\","
45    "  \"expires_in\": 3600,"
46    "  \"token_type\": \"Bearer\""
47    "}";
48
49MockFetcher::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
70MockFetcher::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
85MockFetcher::~MockFetcher() {}
86
87void MockFetcher::Start() {
88  delegate()->OnURLFetchComplete(this);
89}
90
91class GaiaAuthFetcherTest : public testing::Test {
92 protected:
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
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
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:
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
168class MockGaiaConsumer : public GaiaAuthConsumer {
169 public:
170  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(OnClientOAuthCodeSuccess,
179               void(const std::string& result));
180  MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
181  MOCK_METHOD1(OnUberAuthTokenSuccess, void(const std::string& data));
182  MOCK_METHOD1(OnClientLoginFailure,
183      void(const GoogleServiceAuthError& error));
184  MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service,
185      const GoogleServiceAuthError& error));
186  MOCK_METHOD1(OnClientOAuthFailure,
187      void(const GoogleServiceAuthError& error));
188  MOCK_METHOD1(OnClientOAuthCodeFailure,
189      void(const GoogleServiceAuthError& error));
190  MOCK_METHOD1(OnMergeSessionFailure, void(
191      const GoogleServiceAuthError& error));
192  MOCK_METHOD1(OnUberAuthTokenFailure, void(
193      const GoogleServiceAuthError& error));
194  MOCK_METHOD1(OnListAccountsSuccess, void(const std::string& data));
195};
196
197#if defined(OS_WIN)
198#define MAYBE_ErrorComparator DISABLED_ErrorComparator
199#else
200#define MAYBE_ErrorComparator ErrorComparator
201#endif
202
203TEST_F(GaiaAuthFetcherTest, MAYBE_ErrorComparator) {
204  GoogleServiceAuthError expected_error =
205      GoogleServiceAuthError::FromConnectionError(-101);
206
207  GoogleServiceAuthError matching_error =
208      GoogleServiceAuthError::FromConnectionError(-101);
209
210  EXPECT_TRUE(expected_error == matching_error);
211
212  expected_error = GoogleServiceAuthError::FromConnectionError(6);
213
214  EXPECT_FALSE(expected_error == matching_error);
215
216  expected_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
217
218  EXPECT_FALSE(expected_error == matching_error);
219
220  matching_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
221
222  EXPECT_TRUE(expected_error == matching_error);
223}
224
225TEST_F(GaiaAuthFetcherTest, LoginNetFailure) {
226  int error_no = net::ERR_CONNECTION_RESET;
227  net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
228
229  GoogleServiceAuthError expected_error =
230      GoogleServiceAuthError::FromConnectionError(error_no);
231
232  MockGaiaConsumer consumer;
233  EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
234      .Times(1);
235
236  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
237
238  MockFetcher mock_fetcher(
239      client_login_source_, status, 0, net::ResponseCookies(), std::string(),
240      net::URLFetcher::GET, &auth);
241  auth.OnURLFetchComplete(&mock_fetcher);
242}
243
244TEST_F(GaiaAuthFetcherTest, TokenNetFailure) {
245  int error_no = net::ERR_CONNECTION_RESET;
246  net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
247
248  GoogleServiceAuthError expected_error =
249      GoogleServiceAuthError::FromConnectionError(error_no);
250
251  MockGaiaConsumer consumer;
252  EXPECT_CALL(consumer, OnIssueAuthTokenFailure(_, expected_error))
253      .Times(1);
254
255  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
256
257  MockFetcher mock_fetcher(
258      issue_auth_token_source_, status, 0, cookies_, std::string(),
259      net::URLFetcher::GET, &auth);
260  auth.OnURLFetchComplete(&mock_fetcher);
261}
262
263
264TEST_F(GaiaAuthFetcherTest, LoginDenied) {
265  std::string data("Error=BadAuthentication");
266  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
267
268  GoogleServiceAuthError expected_error(
269      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
270
271  MockGaiaConsumer consumer;
272  EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
273      .Times(1);
274
275  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
276
277  MockFetcher mock_fetcher(
278      client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, data,
279      net::URLFetcher::GET, &auth);
280  auth.OnURLFetchComplete(&mock_fetcher);
281}
282
283TEST_F(GaiaAuthFetcherTest, ParseRequest) {
284  RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth\n", "sid", "lsid", "auth");
285  RunParsingTest("LSID=lsid\nSID=sid\nAuth=auth\n", "sid", "lsid", "auth");
286  RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth", "sid", "lsid", "auth");
287  RunParsingTest("SID=sid\nAuth=auth\n", "sid", std::string(), "auth");
288  RunParsingTest("LSID=lsid\nAuth=auth\n", std::string(), "lsid", "auth");
289  RunParsingTest("\nAuth=auth\n", std::string(), std::string(), "auth");
290  RunParsingTest("SID=sid", "sid", std::string(), std::string());
291}
292
293TEST_F(GaiaAuthFetcherTest, ParseErrorRequest) {
294  RunErrorParsingTest("Url=U\n"
295                      "Error=E\n"
296                      "CaptchaToken=T\n"
297                      "CaptchaUrl=C\n", "E", "U", "C", "T");
298  RunErrorParsingTest("CaptchaToken=T\n"
299                      "Error=E\n"
300                      "Url=U\n"
301                      "CaptchaUrl=C\n", "E", "U", "C", "T");
302  RunErrorParsingTest("\n\n\nCaptchaToken=T\n"
303                      "\nError=E\n"
304                      "\nUrl=U\n"
305                      "CaptchaUrl=C\n", "E", "U", "C", "T");
306}
307
308
309TEST_F(GaiaAuthFetcherTest, OnlineLogin) {
310  std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
311
312  GaiaAuthConsumer::ClientLoginResult result;
313  result.lsid = "lsid";
314  result.sid = "sid";
315  result.token = "auth";
316  result.data = data;
317
318  MockGaiaConsumer consumer;
319  EXPECT_CALL(consumer, OnClientLoginSuccess(result))
320      .Times(1);
321
322  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
323  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
324  MockFetcher mock_fetcher(
325      client_login_source_, status, net::HTTP_OK, cookies_, data,
326      net::URLFetcher::GET, &auth);
327  auth.OnURLFetchComplete(&mock_fetcher);
328}
329
330TEST_F(GaiaAuthFetcherTest, WorkingIssueAuthToken) {
331  MockGaiaConsumer consumer;
332  EXPECT_CALL(consumer, OnIssueAuthTokenSuccess(_, "token"))
333      .Times(1);
334
335  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
336  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
337  MockFetcher mock_fetcher(
338      issue_auth_token_source_, status, net::HTTP_OK, cookies_, "token",
339      net::URLFetcher::GET, &auth);
340  auth.OnURLFetchComplete(&mock_fetcher);
341}
342
343TEST_F(GaiaAuthFetcherTest, CheckTwoFactorResponse) {
344  std::string response =
345      base::StringPrintf("Error=BadAuthentication\n%s\n",
346                         GaiaAuthFetcher::kSecondFactor);
347  EXPECT_TRUE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
348}
349
350TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
351  std::string response = "Error=BadAuthentication\n";
352  EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
353}
354
355TEST_F(GaiaAuthFetcherTest, TwoFactorLogin) {
356  std::string response = base::StringPrintf("Error=BadAuthentication\n%s\n",
357      GaiaAuthFetcher::kSecondFactor);
358
359  GoogleServiceAuthError error =
360      GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR);
361
362  MockGaiaConsumer consumer;
363  EXPECT_CALL(consumer, OnClientLoginFailure(error))
364      .Times(1);
365
366  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
367  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
368  MockFetcher mock_fetcher(
369      client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, response,
370      net::URLFetcher::GET, &auth);
371  auth.OnURLFetchComplete(&mock_fetcher);
372}
373
374TEST_F(GaiaAuthFetcherTest, CaptchaParse) {
375  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
376  std::string data = "Url=http://www.google.com/login/captcha\n"
377                     "Error=CaptchaRequired\n"
378                     "CaptchaToken=CCTOKEN\n"
379                     "CaptchaUrl=Captcha?ctoken=CCTOKEN\n";
380  GoogleServiceAuthError error =
381      GaiaAuthFetcher::GenerateAuthError(data, status);
382
383  std::string token = "CCTOKEN";
384  GURL image_url("http://accounts.google.com/Captcha?ctoken=CCTOKEN");
385  GURL unlock_url("http://www.google.com/login/captcha");
386
387  EXPECT_EQ(error.state(), GoogleServiceAuthError::CAPTCHA_REQUIRED);
388  EXPECT_EQ(error.captcha().token, token);
389  EXPECT_EQ(error.captcha().image_url, image_url);
390  EXPECT_EQ(error.captcha().unlock_url, unlock_url);
391}
392
393TEST_F(GaiaAuthFetcherTest, AccountDeletedError) {
394  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
395  std::string data = "Error=AccountDeleted\n";
396  GoogleServiceAuthError error =
397      GaiaAuthFetcher::GenerateAuthError(data, status);
398  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
399}
400
401TEST_F(GaiaAuthFetcherTest, AccountDisabledError) {
402  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
403  std::string data = "Error=AccountDisabled\n";
404  GoogleServiceAuthError error =
405      GaiaAuthFetcher::GenerateAuthError(data, status);
406  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
407}
408
409TEST_F(GaiaAuthFetcherTest,BadAuthenticationError) {
410  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
411  std::string data = "Error=BadAuthentication\n";
412  GoogleServiceAuthError error =
413      GaiaAuthFetcher::GenerateAuthError(data, status);
414  EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
415}
416
417TEST_F(GaiaAuthFetcherTest,IncomprehensibleError) {
418  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
419  std::string data = "Error=Gobbledygook\n";
420  GoogleServiceAuthError error =
421      GaiaAuthFetcher::GenerateAuthError(data, status);
422  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
423}
424
425TEST_F(GaiaAuthFetcherTest,ServiceUnavailableError) {
426  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
427  std::string data = "Error=ServiceUnavailable\n";
428  GoogleServiceAuthError error =
429      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
430  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
431}
432
433TEST_F(GaiaAuthFetcherTest, OAuthAccountDeletedError) {
434  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
435  std::string data = "Error=adel\n";
436  GoogleServiceAuthError error =
437      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
438  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
439}
440
441TEST_F(GaiaAuthFetcherTest, OAuthAccountDisabledError) {
442  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
443  std::string data = "Error=adis\n";
444  GoogleServiceAuthError error =
445      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
446  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
447}
448
449TEST_F(GaiaAuthFetcherTest, OAuthBadAuthenticationError) {
450  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
451  std::string data = "Error=badauth\n";
452  GoogleServiceAuthError error =
453      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
454  EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
455}
456
457TEST_F(GaiaAuthFetcherTest, OAuthServiceUnavailableError) {
458  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
459  std::string data = "Error=ire\n";
460  GoogleServiceAuthError error =
461      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
462  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
463}
464
465TEST_F(GaiaAuthFetcherTest, FullLogin) {
466  MockGaiaConsumer consumer;
467  EXPECT_CALL(consumer, OnClientLoginSuccess(_))
468      .Times(1);
469
470  MockURLFetcherFactory<MockFetcher> factory;
471
472  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
473  auth.StartClientLogin("username",
474                        "password",
475                        "service",
476                        std::string(),
477                        std::string(),
478                        GaiaAuthFetcher::HostedAccountsAllowed);
479}
480
481TEST_F(GaiaAuthFetcherTest, FullLoginFailure) {
482  MockGaiaConsumer consumer;
483  EXPECT_CALL(consumer, OnClientLoginFailure(_))
484      .Times(1);
485
486  MockURLFetcherFactory<MockFetcher> factory;
487  factory.set_success(false);
488
489  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
490  auth.StartClientLogin("username",
491                        "password",
492                        "service",
493                        std::string(),
494                        std::string(),
495                        GaiaAuthFetcher::HostedAccountsAllowed);
496}
497
498TEST_F(GaiaAuthFetcherTest, ClientFetchPending) {
499  MockGaiaConsumer consumer;
500  EXPECT_CALL(consumer, OnClientLoginSuccess(_))
501      .Times(1);
502
503  net::TestURLFetcherFactory factory;
504
505  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
506  auth.StartClientLogin("username",
507                        "password",
508                        "service",
509                        std::string(),
510                        std::string(),
511                        GaiaAuthFetcher::HostedAccountsAllowed);
512
513  EXPECT_TRUE(auth.HasPendingFetch());
514  MockFetcher mock_fetcher(
515      client_login_source_,
516      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
517      net::HTTP_OK, cookies_, "SID=sid\nLSID=lsid\nAuth=auth\n",
518      net::URLFetcher::GET, &auth);
519  auth.OnURLFetchComplete(&mock_fetcher);
520  EXPECT_FALSE(auth.HasPendingFetch());
521}
522
523TEST_F(GaiaAuthFetcherTest, FullTokenSuccess) {
524  MockGaiaConsumer consumer;
525  EXPECT_CALL(consumer, OnIssueAuthTokenSuccess("service", "token"))
526      .Times(1);
527
528  net::TestURLFetcherFactory factory;
529  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
530  auth.StartIssueAuthToken("sid", "lsid", "service");
531
532  EXPECT_TRUE(auth.HasPendingFetch());
533  MockFetcher mock_fetcher(
534      issue_auth_token_source_,
535      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
536      net::HTTP_OK, cookies_, "token",
537      net::URLFetcher::GET, &auth);
538  auth.OnURLFetchComplete(&mock_fetcher);
539  EXPECT_FALSE(auth.HasPendingFetch());
540}
541
542TEST_F(GaiaAuthFetcherTest, FullTokenFailure) {
543  MockGaiaConsumer consumer;
544  EXPECT_CALL(consumer, OnIssueAuthTokenFailure("service", _))
545      .Times(1);
546
547  net::TestURLFetcherFactory factory;
548
549  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
550  auth.StartIssueAuthToken("sid", "lsid", "service");
551
552  EXPECT_TRUE(auth.HasPendingFetch());
553  MockFetcher mock_fetcher(
554      issue_auth_token_source_,
555      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
556      net::HTTP_FORBIDDEN,
557      cookies_,
558      std::string(),
559      net::URLFetcher::GET,
560      &auth);
561  auth.OnURLFetchComplete(&mock_fetcher);
562  EXPECT_FALSE(auth.HasPendingFetch());
563}
564
565TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) {
566  MockGaiaConsumer consumer;
567  EXPECT_CALL(consumer, OnClientOAuthSuccess(
568      GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1);
569
570  net::TestURLFetcherFactory factory;
571  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
572  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
573  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
574  EXPECT_TRUE(NULL != fetcher);
575  EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES,
576            fetcher->GetLoadFlags());
577
578  net::ResponseCookies cookies;
579  cookies.push_back(kGetAuthCodeValidCookie);
580  EXPECT_TRUE(auth.HasPendingFetch());
581  MockFetcher mock_fetcher1(
582      client_login_to_oauth2_source_,
583      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
584      net::HTTP_OK,
585      cookies,
586      std::string(),
587      net::URLFetcher::POST,
588      &auth);
589  auth.OnURLFetchComplete(&mock_fetcher1);
590  EXPECT_TRUE(auth.HasPendingFetch());
591  MockFetcher mock_fetcher2(
592      oauth2_token_source_,
593      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
594      net::HTTP_OK, cookies_, kGetTokenPairValidResponse,
595      net::URLFetcher::POST, &auth);
596  auth.OnURLFetchComplete(&mock_fetcher2);
597  EXPECT_FALSE(auth.HasPendingFetch());
598}
599
600TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies) {
601  MockGaiaConsumer consumer;
602  net::TestURLFetcherFactory factory;
603  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
604  auth.StartCookieForOAuthLoginTokenExchange("0");
605  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
606  EXPECT_TRUE(NULL != fetcher);
607  EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
608}
609
610TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) {
611  MockGaiaConsumer consumer;
612  EXPECT_CALL(consumer, OnClientOAuthFailure(_))
613      .Times(1);
614
615  net::TestURLFetcherFactory factory;
616  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
617  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
618
619  net::ResponseCookies cookies;
620  EXPECT_TRUE(auth.HasPendingFetch());
621  MockFetcher mock_fetcher(
622      client_login_to_oauth2_source_,
623      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
624      net::HTTP_FORBIDDEN,
625      cookies,
626      std::string(),
627      net::URLFetcher::POST,
628      &auth);
629  auth.OnURLFetchComplete(&mock_fetcher);
630  EXPECT_FALSE(auth.HasPendingFetch());
631}
632
633TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) {
634  MockGaiaConsumer consumer;
635  EXPECT_CALL(consumer, OnClientOAuthFailure(_))
636      .Times(1);
637
638  net::TestURLFetcherFactory factory;
639  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
640  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
641
642  net::ResponseCookies cookies;
643  cookies.push_back(kGetAuthCodeValidCookie);
644  EXPECT_TRUE(auth.HasPendingFetch());
645  MockFetcher mock_fetcher1(
646      client_login_to_oauth2_source_,
647      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
648      net::HTTP_OK,
649      cookies,
650      std::string(),
651      net::URLFetcher::POST,
652      &auth);
653  auth.OnURLFetchComplete(&mock_fetcher1);
654  EXPECT_TRUE(auth.HasPendingFetch());
655  MockFetcher mock_fetcher2(
656      oauth2_token_source_,
657      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
658      net::HTTP_FORBIDDEN,
659      cookies_,
660      std::string(),
661      net::URLFetcher::POST,
662      &auth);
663  auth.OnURLFetchComplete(&mock_fetcher2);
664  EXPECT_FALSE(auth.HasPendingFetch());
665}
666
667TEST_F(GaiaAuthFetcherTest, OAuthCodeWithCookiesSuccess) {
668  MockGaiaConsumer consumer;
669  EXPECT_CALL(consumer, OnClientOAuthCodeSuccess("test-code")).Times(1);
670
671  net::TestURLFetcherFactory factory;
672  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
673  auth.StartCookieForOAuthCodeExchange("");
674
675  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
676  EXPECT_TRUE(NULL != fetcher);
677  EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
678  EXPECT_TRUE(auth.HasPendingFetch());
679
680  net::ResponseCookies cookies;
681  cookies.push_back(kGetAuthCodeValidCookie);
682  MockFetcher mock_fetcher(
683      client_login_to_oauth2_source_,
684      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
685      net::HTTP_OK,
686      cookies,
687      std::string(),
688      net::URLFetcher::POST,
689      &auth);
690  auth.OnURLFetchComplete(&mock_fetcher);
691  EXPECT_FALSE(auth.HasPendingFetch());
692}
693
694TEST_F(GaiaAuthFetcherTest, OAuthCodeWithCookiesFailure) {
695  MockGaiaConsumer consumer;
696  EXPECT_CALL(consumer, OnClientOAuthCodeFailure(_)).Times(1);
697
698  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
699  auth.StartCookieForOAuthCodeExchange("");
700
701  EXPECT_TRUE(auth.HasPendingFetch());
702  net::ResponseCookies cookies;
703  MockFetcher mock_fetcher(
704      client_login_to_oauth2_source_,
705      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
706      net::HTTP_FORBIDDEN,
707      cookies,
708      std::string(),
709      net::URLFetcher::POST,
710      &auth);
711  auth.OnURLFetchComplete(&mock_fetcher);
712  EXPECT_FALSE(auth.HasPendingFetch());
713}
714
715TEST_F(GaiaAuthFetcherTest, MergeSessionSuccess) {
716  MockGaiaConsumer consumer;
717  EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
718      .Times(1);
719
720  net::TestURLFetcherFactory factory;
721
722  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
723  auth.StartMergeSession("myubertoken");
724
725  EXPECT_TRUE(auth.HasPendingFetch());
726  MockFetcher mock_fetcher(
727      merge_session_source_,
728      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
729      net::HTTP_OK, cookies_, "<html></html>", net::URLFetcher::GET,
730      &auth);
731  auth.OnURLFetchComplete(&mock_fetcher);
732  EXPECT_FALSE(auth.HasPendingFetch());
733}
734
735TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) {
736  MockGaiaConsumer consumer;
737  EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
738      .Times(1);
739
740  net::TestURLFetcherFactory factory;
741
742  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
743  auth.StartMergeSession("myubertoken");
744
745  // Make sure the fetcher created has the expected flags.  Set its url()
746  // properties to reflect a redirect.
747  net::TestURLFetcher* test_fetcher = factory.GetFetcherByID(0);
748  EXPECT_TRUE(test_fetcher != NULL);
749  EXPECT_TRUE(test_fetcher->GetLoadFlags() == net::LOAD_NORMAL);
750  EXPECT_TRUE(auth.HasPendingFetch());
751
752  GURL final_url("http://www.google.com/CheckCookie");
753  test_fetcher->set_url(final_url);
754  test_fetcher->set_status(
755      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
756  test_fetcher->set_response_code(net::HTTP_OK);
757  test_fetcher->set_cookies(cookies_);
758  test_fetcher->SetResponseString("<html></html>");
759
760  auth.OnURLFetchComplete(test_fetcher);
761  EXPECT_FALSE(auth.HasPendingFetch());
762}
763
764TEST_F(GaiaAuthFetcherTest, UberAuthTokenSuccess) {
765  MockGaiaConsumer consumer;
766  EXPECT_CALL(consumer, OnUberAuthTokenSuccess("uberToken"))
767      .Times(1);
768
769  net::TestURLFetcherFactory factory;
770
771  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
772  auth.StartTokenFetchForUberAuthExchange("myAccessToken");
773
774  EXPECT_TRUE(auth.HasPendingFetch());
775  MockFetcher mock_fetcher(
776      uberauth_token_source_,
777      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
778      net::HTTP_OK, cookies_, "uberToken", net::URLFetcher::POST,
779      &auth);
780  auth.OnURLFetchComplete(&mock_fetcher);
781  EXPECT_FALSE(auth.HasPendingFetch());
782}
783
784TEST_F(GaiaAuthFetcherTest, ParseClientLoginToOAuth2Response) {
785  {  // No cookies.
786    std::string auth_code;
787    net::ResponseCookies cookies;
788    EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
789        cookies, &auth_code));
790    EXPECT_EQ("", auth_code);
791  }
792  {  // Few cookies, nothing appropriate.
793    std::string auth_code;
794    net::ResponseCookies cookies;
795    cookies.push_back(kGetAuthCodeCookieNoSecure);
796    cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
797    cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
798    EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
799        cookies, &auth_code));
800    EXPECT_EQ("", auth_code);
801  }
802  {  // Few cookies, one of them is valid.
803    std::string auth_code;
804    net::ResponseCookies cookies;
805    cookies.push_back(kGetAuthCodeCookieNoSecure);
806    cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
807    cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
808    cookies.push_back(kGetAuthCodeValidCookie);
809    EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
810        cookies, &auth_code));
811    EXPECT_EQ("test-code", auth_code);
812  }
813  {  // Single valid cookie (like in real responses).
814    std::string auth_code;
815    net::ResponseCookies cookies;
816    cookies.push_back(kGetAuthCodeValidCookie);
817    EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
818        cookies, &auth_code));
819    EXPECT_EQ("test-code", auth_code);
820  }
821}
822
823TEST_F(GaiaAuthFetcherTest, StartOAuthLogin) {
824  // OAuthLogin returns the same as the ClientLogin endpoint, minus CAPTCHA
825  // responses.
826  std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
827
828  GaiaAuthConsumer::ClientLoginResult result;
829  result.lsid = "lsid";
830  result.sid = "sid";
831  result.token = "auth";
832  result.data = data;
833
834  MockGaiaConsumer consumer;
835  EXPECT_CALL(consumer, OnClientLoginSuccess(result))
836      .Times(1);
837
838  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
839  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
840  MockFetcher mock_fetcher(
841      oauth_login_gurl_, status, net::HTTP_OK, cookies_, data,
842      net::URLFetcher::GET, &auth);
843  auth.OnURLFetchComplete(&mock_fetcher);
844}
845
846TEST_F(GaiaAuthFetcherTest, ListAccounts) {
847  std::string data("[\"gaia.l.a.r\", ["
848      "[\"gaia.l.a\", 1, \"First Last\", \"user@gmail.com\", "
849      "\"//googleusercontent.com/A/B/C/D/photo.jpg\", 1, 1, 0]]]");
850  MockGaiaConsumer consumer;
851  EXPECT_CALL(consumer, OnListAccountsSuccess(data)).Times(1);
852
853  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
854  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
855  MockFetcher mock_fetcher(GaiaUrls::GetInstance()->list_accounts_url(),
856      status, net::HTTP_OK, cookies_, data, net::URLFetcher::GET, &auth);
857  auth.OnURLFetchComplete(&mock_fetcher);
858}
859