Home | History | Annotate | Download | only in gaia
      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 
     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 
     38 MockFetcher::~MockFetcher() {}
     39 
     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:
     63   GaiaAuthFetcherTest()
     64       : client_login_source_(GaiaAuthFetcher::kClientLoginUrl),
     65         issue_auth_token_source_(GaiaAuthFetcher::kIssueAuthTokenUrl) {}
     66 
     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 
     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:
    115   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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    288 TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
    289   std::string response = "Error=BadAuthentication\n";
    290   EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
    291 }
    292 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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