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