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