1 // Copyright (c) 2011 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/message_loop.h"
11 #include "base/string_util.h"
12 #include "chrome/common/net/gaia/gaia_auth_consumer.h"
13 #include "chrome/common/net/gaia/gaia_auth_fetcher.h"
14 #include "chrome/common/net/gaia/gaia_auth_fetcher_unittest.h"
15 #include "chrome/common/net/gaia/google_service_auth_error.h"
16 #include "chrome/common/net/http_return.h"
17 #include "chrome/common/net/test_url_fetcher_factory.h"
18 #include "chrome/common/net/url_fetcher.h"
19 #include "chrome/test/testing_profile.h"
20 #include "googleurl/src/gurl.h"
21 #include "net/base/net_errors.h"
22 #include "net/url_request/url_request_status.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 using ::testing::_;
27
MockFetcher(bool success,const GURL & url,const std::string & results,URLFetcher::RequestType request_type,URLFetcher::Delegate * d)28 MockFetcher::MockFetcher(bool success,
29 const GURL& url,
30 const std::string& results,
31 URLFetcher::RequestType request_type,
32 URLFetcher::Delegate* d)
33 : URLFetcher(url, request_type, d),
34 success_(success),
35 url_(url),
36 results_(results) {}
37
~MockFetcher()38 MockFetcher::~MockFetcher() {}
39
Start()40 void MockFetcher::Start() {
41 net::URLRequestStatus::Status code;
42 int http_code;
43 if (success_) {
44 http_code = RC_REQUEST_OK;
45 code = net::URLRequestStatus::SUCCESS;
46 } else {
47 http_code = RC_FORBIDDEN;
48 code = net::URLRequestStatus::FAILED;
49 }
50
51 net::URLRequestStatus status(code, 0);
52 delegate()->OnURLFetchComplete(NULL,
53 url_,
54 status,
55 http_code,
56 ResponseCookies(),
57 results_);
58 }
59
60
61 class GaiaAuthFetcherTest : public testing::Test {
62 public:
GaiaAuthFetcherTest()63 GaiaAuthFetcherTest()
64 : client_login_source_(GaiaAuthFetcher::kClientLoginUrl),
65 issue_auth_token_source_(GaiaAuthFetcher::kIssueAuthTokenUrl) {}
66
RunParsingTest(const std::string & data,const std::string & sid,const std::string & lsid,const std::string & token)67 void RunParsingTest(const std::string& data,
68 const std::string& sid,
69 const std::string& lsid,
70 const std::string& token) {
71 std::string out_sid;
72 std::string out_lsid;
73 std::string out_token;
74
75 GaiaAuthFetcher::ParseClientLoginResponse(data,
76 &out_sid,
77 &out_lsid,
78 &out_token);
79 EXPECT_EQ(lsid, out_lsid);
80 EXPECT_EQ(sid, out_sid);
81 EXPECT_EQ(token, out_token);
82 }
83
RunErrorParsingTest(const std::string & data,const std::string & error,const std::string & error_url,const std::string & captcha_url,const std::string & captcha_token)84 void RunErrorParsingTest(const std::string& data,
85 const std::string& error,
86 const std::string& error_url,
87 const std::string& captcha_url,
88 const std::string& captcha_token) {
89 std::string out_error;
90 std::string out_error_url;
91 std::string out_captcha_url;
92 std::string out_captcha_token;
93
94 GaiaAuthFetcher::ParseClientLoginFailure(data,
95 &out_error,
96 &out_error_url,
97 &out_captcha_url,
98 &out_captcha_token);
99 EXPECT_EQ(error, out_error);
100 EXPECT_EQ(error_url, out_error_url);
101 EXPECT_EQ(captcha_url, out_captcha_url);
102 EXPECT_EQ(captcha_token, out_captcha_token);
103 }
104
105 ResponseCookies cookies_;
106 GURL client_login_source_;
107 GURL issue_auth_token_source_;
108 TestingProfile profile_;
109 protected:
110 MessageLoop message_loop_;
111 };
112
113 class MockGaiaConsumer : public GaiaAuthConsumer {
114 public:
MockGaiaConsumer()115 MockGaiaConsumer() {}
~MockGaiaConsumer()116 ~MockGaiaConsumer() {}
117
118 MOCK_METHOD1(OnClientLoginSuccess, void(const ClientLoginResult& result));
119 MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service,
120 const std::string& token));
121 MOCK_METHOD1(OnClientLoginFailure,
122 void(const GoogleServiceAuthError& error));
123 MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service,
124 const GoogleServiceAuthError& error));
125 };
126
TEST_F(GaiaAuthFetcherTest,ErrorComparator)127 TEST_F(GaiaAuthFetcherTest, ErrorComparator) {
128 GoogleServiceAuthError expected_error =
129 GoogleServiceAuthError::FromConnectionError(-101);
130
131 GoogleServiceAuthError matching_error =
132 GoogleServiceAuthError::FromConnectionError(-101);
133
134 EXPECT_TRUE(expected_error == matching_error);
135
136 expected_error = GoogleServiceAuthError::FromConnectionError(6);
137
138 EXPECT_FALSE(expected_error == matching_error);
139
140 expected_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
141
142 EXPECT_FALSE(expected_error == matching_error);
143
144 matching_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
145
146 EXPECT_TRUE(expected_error == matching_error);
147 }
148
TEST_F(GaiaAuthFetcherTest,LoginNetFailure)149 TEST_F(GaiaAuthFetcherTest, LoginNetFailure) {
150 int error_no = net::ERR_CONNECTION_RESET;
151 net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
152
153 GoogleServiceAuthError expected_error =
154 GoogleServiceAuthError::FromConnectionError(error_no);
155
156 MockGaiaConsumer consumer;
157 EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
158 .Times(1);
159
160 GaiaAuthFetcher auth(&consumer, std::string(),
161 profile_.GetRequestContext());
162
163 auth.OnURLFetchComplete(NULL,
164 client_login_source_,
165 status,
166 0,
167 cookies_,
168 std::string());
169 }
170
TEST_F(GaiaAuthFetcherTest,TokenNetFailure)171 TEST_F(GaiaAuthFetcherTest, TokenNetFailure) {
172 int error_no = net::ERR_CONNECTION_RESET;
173 net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
174
175 GoogleServiceAuthError expected_error =
176 GoogleServiceAuthError::FromConnectionError(error_no);
177
178 MockGaiaConsumer consumer;
179 EXPECT_CALL(consumer, OnIssueAuthTokenFailure(_, expected_error))
180 .Times(1);
181
182 GaiaAuthFetcher auth(&consumer, std::string(),
183 profile_.GetRequestContext());
184
185 auth.OnURLFetchComplete(NULL,
186 issue_auth_token_source_,
187 status,
188 0,
189 cookies_,
190 std::string());
191 }
192
193
TEST_F(GaiaAuthFetcherTest,LoginDenied)194 TEST_F(GaiaAuthFetcherTest, LoginDenied) {
195 std::string data("Error=BadAuthentication");
196 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
197
198 GoogleServiceAuthError expected_error(
199 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
200
201 MockGaiaConsumer consumer;
202 EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
203 .Times(1);
204
205 GaiaAuthFetcher auth(&consumer, std::string(),
206 profile_.GetRequestContext());
207 auth.OnURLFetchComplete(NULL,
208 client_login_source_,
209 status,
210 RC_FORBIDDEN,
211 cookies_,
212 data);
213 }
214
TEST_F(GaiaAuthFetcherTest,ParseRequest)215 TEST_F(GaiaAuthFetcherTest, ParseRequest) {
216 RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth\n", "sid", "lsid", "auth");
217 RunParsingTest("LSID=lsid\nSID=sid\nAuth=auth\n", "sid", "lsid", "auth");
218 RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth", "sid", "lsid", "auth");
219 RunParsingTest("SID=sid\nAuth=auth\n", "sid", "", "auth");
220 RunParsingTest("LSID=lsid\nAuth=auth\n", "", "lsid", "auth");
221 RunParsingTest("\nAuth=auth\n", "", "", "auth");
222 RunParsingTest("SID=sid", "sid", "", "");
223 }
224
TEST_F(GaiaAuthFetcherTest,ParseErrorRequest)225 TEST_F(GaiaAuthFetcherTest, ParseErrorRequest) {
226 RunErrorParsingTest("Url=U\n"
227 "Error=E\n"
228 "CaptchaToken=T\n"
229 "CaptchaUrl=C\n", "E", "U", "C", "T");
230 RunErrorParsingTest("CaptchaToken=T\n"
231 "Error=E\n"
232 "Url=U\n"
233 "CaptchaUrl=C\n", "E", "U", "C", "T");
234 RunErrorParsingTest("\n\n\nCaptchaToken=T\n"
235 "\nError=E\n"
236 "\nUrl=U\n"
237 "CaptchaUrl=C\n", "E", "U", "C", "T");
238 }
239
240
TEST_F(GaiaAuthFetcherTest,OnlineLogin)241 TEST_F(GaiaAuthFetcherTest, OnlineLogin) {
242 std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
243
244 GaiaAuthConsumer::ClientLoginResult result;
245 result.lsid = "lsid";
246 result.sid = "sid";
247 result.token = "auth";
248 result.data = data;
249
250 MockGaiaConsumer consumer;
251 EXPECT_CALL(consumer, OnClientLoginSuccess(result))
252 .Times(1);
253
254 GaiaAuthFetcher auth(&consumer, std::string(),
255 profile_.GetRequestContext());
256 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
257 auth.OnURLFetchComplete(NULL,
258 client_login_source_,
259 status,
260 RC_REQUEST_OK,
261 cookies_,
262 data);
263 }
264
TEST_F(GaiaAuthFetcherTest,WorkingIssueAuthToken)265 TEST_F(GaiaAuthFetcherTest, WorkingIssueAuthToken) {
266 MockGaiaConsumer consumer;
267 EXPECT_CALL(consumer, OnIssueAuthTokenSuccess(_, "token"))
268 .Times(1);
269
270 GaiaAuthFetcher auth(&consumer, std::string(),
271 profile_.GetRequestContext());
272 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
273 auth.OnURLFetchComplete(NULL,
274 issue_auth_token_source_,
275 status,
276 RC_REQUEST_OK,
277 cookies_,
278 "token");
279 }
280
TEST_F(GaiaAuthFetcherTest,CheckTwoFactorResponse)281 TEST_F(GaiaAuthFetcherTest, CheckTwoFactorResponse) {
282 std::string response =
283 base::StringPrintf("Error=BadAuthentication\n%s\n",
284 GaiaAuthFetcher::kSecondFactor);
285 EXPECT_TRUE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
286 }
287
TEST_F(GaiaAuthFetcherTest,CheckNormalErrorCode)288 TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
289 std::string response = "Error=BadAuthentication\n";
290 EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
291 }
292
TEST_F(GaiaAuthFetcherTest,TwoFactorLogin)293 TEST_F(GaiaAuthFetcherTest, TwoFactorLogin) {
294 std::string response = base::StringPrintf("Error=BadAuthentication\n%s\n",
295 GaiaAuthFetcher::kSecondFactor);
296
297 GoogleServiceAuthError error =
298 GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR);
299
300 MockGaiaConsumer consumer;
301 EXPECT_CALL(consumer, OnClientLoginFailure(error))
302 .Times(1);
303
304 GaiaAuthFetcher auth(&consumer, std::string(),
305 profile_.GetRequestContext());
306 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
307 auth.OnURLFetchComplete(NULL,
308 client_login_source_,
309 status,
310 RC_FORBIDDEN,
311 cookies_,
312 response);
313 }
314
TEST_F(GaiaAuthFetcherTest,CaptchaParse)315 TEST_F(GaiaAuthFetcherTest, CaptchaParse) {
316 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
317 std::string data = "Url=http://www.google.com/login/captcha\n"
318 "Error=CaptchaRequired\n"
319 "CaptchaToken=CCTOKEN\n"
320 "CaptchaUrl=Captcha?ctoken=CCTOKEN\n";
321 GoogleServiceAuthError error =
322 GaiaAuthFetcher::GenerateAuthError(data, status);
323
324 std::string token = "CCTOKEN";
325 GURL image_url("http://www.google.com/accounts/Captcha?ctoken=CCTOKEN");
326 GURL unlock_url("http://www.google.com/login/captcha");
327
328 EXPECT_EQ(error.state(), GoogleServiceAuthError::CAPTCHA_REQUIRED);
329 EXPECT_EQ(error.captcha().token, token);
330 EXPECT_EQ(error.captcha().image_url, image_url);
331 EXPECT_EQ(error.captcha().unlock_url, unlock_url);
332 }
333
TEST_F(GaiaAuthFetcherTest,AccountDeletedError)334 TEST_F(GaiaAuthFetcherTest, AccountDeletedError) {
335 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
336 std::string data = "Error=AccountDeleted\n";
337 GoogleServiceAuthError error =
338 GaiaAuthFetcher::GenerateAuthError(data, status);
339 EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
340 }
341
TEST_F(GaiaAuthFetcherTest,AccountDisabledError)342 TEST_F(GaiaAuthFetcherTest, AccountDisabledError) {
343 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
344 std::string data = "Error=AccountDisabled\n";
345 GoogleServiceAuthError error =
346 GaiaAuthFetcher::GenerateAuthError(data, status);
347 EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
348 }
349
TEST_F(GaiaAuthFetcherTest,BadAuthenticationError)350 TEST_F(GaiaAuthFetcherTest,BadAuthenticationError) {
351 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
352 std::string data = "Error=BadAuthentication\n";
353 GoogleServiceAuthError error =
354 GaiaAuthFetcher::GenerateAuthError(data, status);
355 EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
356 }
357
TEST_F(GaiaAuthFetcherTest,IncomprehensibleError)358 TEST_F(GaiaAuthFetcherTest,IncomprehensibleError) {
359 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
360 std::string data = "Error=Gobbledygook\n";
361 GoogleServiceAuthError error =
362 GaiaAuthFetcher::GenerateAuthError(data, status);
363 EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
364 }
365
TEST_F(GaiaAuthFetcherTest,ServiceUnavailableError)366 TEST_F(GaiaAuthFetcherTest,ServiceUnavailableError) {
367 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
368 std::string data = "Error=ServiceUnavailable\n";
369 GoogleServiceAuthError error =
370 GaiaAuthFetcher::GenerateAuthError(data, status);
371 EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
372 }
373
TEST_F(GaiaAuthFetcherTest,FullLogin)374 TEST_F(GaiaAuthFetcherTest, FullLogin) {
375 MockGaiaConsumer consumer;
376 EXPECT_CALL(consumer, OnClientLoginSuccess(_))
377 .Times(1);
378
379 TestingProfile profile;
380
381 MockFactory<MockFetcher> factory;
382 URLFetcher::set_factory(&factory);
383
384 GaiaAuthFetcher auth(&consumer, std::string(),
385 profile_.GetRequestContext());
386 auth.StartClientLogin("username",
387 "password",
388 "service",
389 std::string(),
390 std::string(),
391 GaiaAuthFetcher::HostedAccountsAllowed);
392
393 URLFetcher::set_factory(NULL);
394 }
395
TEST_F(GaiaAuthFetcherTest,FullLoginFailure)396 TEST_F(GaiaAuthFetcherTest, FullLoginFailure) {
397 MockGaiaConsumer consumer;
398 EXPECT_CALL(consumer, OnClientLoginFailure(_))
399 .Times(1);
400
401 TestingProfile profile;
402
403 MockFactory<MockFetcher> factory;
404 URLFetcher::set_factory(&factory);
405 factory.set_success(false);
406
407 GaiaAuthFetcher auth(&consumer, std::string(),
408 profile_.GetRequestContext());
409 auth.StartClientLogin("username",
410 "password",
411 "service",
412 std::string(),
413 std::string(),
414 GaiaAuthFetcher::HostedAccountsAllowed);
415
416 URLFetcher::set_factory(NULL);
417 }
418
TEST_F(GaiaAuthFetcherTest,ClientFetchPending)419 TEST_F(GaiaAuthFetcherTest, ClientFetchPending) {
420 MockGaiaConsumer consumer;
421 EXPECT_CALL(consumer, OnClientLoginSuccess(_))
422 .Times(1);
423
424 TestingProfile profile;
425 TestURLFetcherFactory factory;
426 URLFetcher::set_factory(&factory);
427
428 GaiaAuthFetcher auth(&consumer, std::string(),
429 profile_.GetRequestContext());
430 auth.StartClientLogin("username",
431 "password",
432 "service",
433 std::string(),
434 std::string(),
435 GaiaAuthFetcher::HostedAccountsAllowed);
436
437 URLFetcher::set_factory(NULL);
438 EXPECT_TRUE(auth.HasPendingFetch());
439 auth.OnURLFetchComplete(
440 NULL,
441 client_login_source_,
442 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
443 RC_REQUEST_OK,
444 cookies_,
445 "SID=sid\nLSID=lsid\nAuth=auth\n");
446 EXPECT_FALSE(auth.HasPendingFetch());
447 }
448
TEST_F(GaiaAuthFetcherTest,FullTokenSuccess)449 TEST_F(GaiaAuthFetcherTest, FullTokenSuccess) {
450 MockGaiaConsumer consumer;
451 EXPECT_CALL(consumer, OnIssueAuthTokenSuccess("service", "token"))
452 .Times(1);
453
454 TestingProfile profile;
455 TestURLFetcherFactory factory;
456 URLFetcher::set_factory(&factory);
457
458 GaiaAuthFetcher auth(&consumer, std::string(),
459 profile_.GetRequestContext());
460 auth.StartIssueAuthToken("sid", "lsid", "service");
461
462 URLFetcher::set_factory(NULL);
463 EXPECT_TRUE(auth.HasPendingFetch());
464 auth.OnURLFetchComplete(
465 NULL,
466 issue_auth_token_source_,
467 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
468 RC_REQUEST_OK,
469 cookies_,
470 "token");
471 EXPECT_FALSE(auth.HasPendingFetch());
472 }
473
TEST_F(GaiaAuthFetcherTest,FullTokenFailure)474 TEST_F(GaiaAuthFetcherTest, FullTokenFailure) {
475 MockGaiaConsumer consumer;
476 EXPECT_CALL(consumer, OnIssueAuthTokenFailure("service", _))
477 .Times(1);
478
479 TestingProfile profile;
480 TestURLFetcherFactory factory;
481 URLFetcher::set_factory(&factory);
482
483 GaiaAuthFetcher auth(&consumer, std::string(),
484 profile_.GetRequestContext());
485 auth.StartIssueAuthToken("sid", "lsid", "service");
486
487 URLFetcher::set_factory(NULL);
488 EXPECT_TRUE(auth.HasPendingFetch());
489 auth.OnURLFetchComplete(
490 NULL,
491 issue_auth_token_source_,
492 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
493 RC_FORBIDDEN,
494 cookies_,
495 "");
496 EXPECT_FALSE(auth.HasPendingFetch());
497 }
498