Home | History | Annotate | Download | only in login
      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 #include "chrome/browser/chromeos/login/google_authenticator.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/file_path.h"
     11 #include "base/file_util.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/message_loop.h"
     14 #include "base/path_service.h"
     15 #include "base/string_util.h"
     16 #include "base/stringprintf.h"
     17 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h"
     18 #include "chrome/browser/chromeos/cros/mock_library_loader.h"
     19 #include "chrome/browser/chromeos/login/client_login_response_handler.h"
     20 #include "chrome/browser/chromeos/login/issue_response_handler.h"
     21 #include "chrome/browser/chromeos/login/mock_auth_response_handler.h"
     22 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h"
     23 #include "chrome/browser/chromeos/login/mock_url_fetchers.h"
     24 #include "chrome/browser/chromeos/login/mock_user_manager.h"
     25 #include "chrome/browser/chromeos/login/user_manager.h"
     26 #include "chrome/common/chrome_paths.h"
     27 #include "chrome/common/net/gaia/gaia_auth_fetcher_unittest.h"
     28 #include "chrome/common/net/url_fetcher.h"
     29 #include "chrome/test/testing_profile.h"
     30 #include "content/browser/browser_thread.h"
     31 #include "googleurl/src/gurl.h"
     32 #include "net/base/net_errors.h"
     33 #include "net/url_request/url_request_status.h"
     34 #include "testing/gmock/include/gmock/gmock.h"
     35 #include "testing/gtest/include/gtest/gtest.h"
     36 
     37 using namespace file_util;
     38 using ::testing::AnyNumber;
     39 using ::testing::DoAll;
     40 using ::testing::Eq;
     41 using ::testing::Invoke;
     42 using ::testing::Return;
     43 using ::testing::SetArgumentPointee;
     44 using ::testing::_;
     45 
     46 namespace chromeos {
     47 
     48 class GoogleAuthenticatorTest : public ::testing::Test {
     49  public:
     50   GoogleAuthenticatorTest()
     51       : message_loop_ui_(MessageLoop::TYPE_UI),
     52         ui_thread_(BrowserThread::UI, &message_loop_ui_),
     53         username_("me (at) nowhere.org"),
     54         password_("fakepass"),
     55         result_("", "", "", ""),
     56         bytes_as_ascii_("ffff"),
     57         user_manager_(new MockUserManager) {
     58     memset(fake_hash_, 0, sizeof(fake_hash_));
     59     fake_hash_[0] = 10;
     60     fake_hash_[1] = 1;
     61     fake_hash_[7] = 10 << 4;
     62     hash_ascii_.assign("0a010000000000a0");
     63     hash_ascii_.append(std::string(16, '0'));
     64 
     65     memset(raw_bytes_, 0xff, sizeof(raw_bytes_));
     66   }
     67   ~GoogleAuthenticatorTest() {}
     68 
     69   virtual void SetUp() {
     70     chromeos::CrosLibrary::TestApi* test_api =
     71         chromeos::CrosLibrary::Get()->GetTestApi();
     72 
     73     loader_ = new MockLibraryLoader();
     74     ON_CALL(*loader_, Load(_))
     75         .WillByDefault(Return(true));
     76     EXPECT_CALL(*loader_, Load(_))
     77         .Times(AnyNumber());
     78 
     79     test_api->SetLibraryLoader(loader_, true);
     80 
     81     mock_library_ = new MockCryptohomeLibrary();
     82     test_api->SetCryptohomeLibrary(mock_library_, true);
     83   }
     84 
     85   // Tears down the test fixture.
     86   virtual void TearDown() {
     87     // Prevent bogus gMock leak check from firing.
     88     chromeos::CrosLibrary::TestApi* test_api =
     89         chromeos::CrosLibrary::Get()->GetTestApi();
     90     test_api->SetLibraryLoader(NULL, false);
     91     test_api->SetCryptohomeLibrary(NULL, false);
     92   }
     93 
     94   FilePath PopulateTempFile(const char* data, int data_len) {
     95     FilePath out;
     96     FILE* tmp_file = CreateAndOpenTemporaryFile(&out);
     97     EXPECT_NE(tmp_file, static_cast<FILE*>(NULL));
     98     EXPECT_EQ(WriteFile(out, data, data_len), data_len);
     99     EXPECT_TRUE(CloseFile(tmp_file));
    100     return out;
    101   }
    102 
    103   FilePath FakeLocalaccountFile(const std::string& ascii) {
    104     FilePath exe_dir;
    105     FilePath local_account_file;
    106     PathService::Get(base::DIR_EXE, &exe_dir);
    107     FILE* tmp_file = CreateAndOpenTemporaryFileInDir(exe_dir,
    108                                                      &local_account_file);
    109     int ascii_len = ascii.length();
    110     EXPECT_NE(tmp_file, static_cast<FILE*>(NULL));
    111     EXPECT_EQ(WriteFile(local_account_file, ascii.c_str(), ascii_len),
    112               ascii_len);
    113     EXPECT_TRUE(CloseFile(tmp_file));
    114     return local_account_file;
    115   }
    116 
    117   void ReadLocalaccountFile(GoogleAuthenticator* auth,
    118                             const std::string& filename) {
    119     BrowserThread file_thread(BrowserThread::FILE);
    120     file_thread.Start();
    121 
    122     BrowserThread::PostTask(
    123         BrowserThread::FILE, FROM_HERE,
    124         NewRunnableMethod(auth,
    125                           &GoogleAuthenticator::LoadLocalaccount,
    126                           filename));
    127   }
    128 
    129   void PrepForLogin(GoogleAuthenticator* auth) {
    130     auth->set_password_hash(hash_ascii_);
    131     auth->set_username(username_);
    132     auth->set_password(password_);
    133     auth->SetLocalaccount("");
    134     auth->set_user_manager(user_manager_.get());
    135     ON_CALL(*user_manager_.get(), IsKnownUser(username_))
    136         .WillByDefault(Return(true));
    137   }
    138 
    139   void PrepForFailedLogin(GoogleAuthenticator* auth) {
    140     PrepForLogin(auth);
    141     auth->set_hosted_policy(GaiaAuthFetcher::HostedAccountsAllowed);
    142   }
    143 
    144   void CancelLogin(GoogleAuthenticator* auth) {
    145     BrowserThread::PostTask(
    146         BrowserThread::UI,
    147         FROM_HERE,
    148         NewRunnableMethod(auth,
    149                           &GoogleAuthenticator::CancelClientLogin));
    150   }
    151 
    152   MessageLoop message_loop_ui_;
    153   BrowserThread ui_thread_;
    154 
    155   unsigned char fake_hash_[32];
    156   std::string hash_ascii_;
    157   std::string username_;
    158   std::string password_;
    159   GaiaAuthConsumer::ClientLoginResult result_;
    160   // Mocks, destroyed by CrosLibrary class.
    161   MockCryptohomeLibrary* mock_library_;
    162   MockLibraryLoader* loader_;
    163 
    164   char raw_bytes_[2];
    165   std::string bytes_as_ascii_;
    166 
    167   scoped_ptr<MockUserManager> user_manager_;
    168 };
    169 
    170 TEST_F(GoogleAuthenticatorTest, SaltToAscii) {
    171   unsigned char fake_salt[8] = { 0 };
    172   fake_salt[0] = 10;
    173   fake_salt[1] = 1;
    174   fake_salt[7] = 10 << 4;
    175   std::vector<unsigned char> salt_v(fake_salt, fake_salt + sizeof(fake_salt));
    176 
    177   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(NULL));
    178 
    179   ON_CALL(*mock_library_, GetSystemSalt())
    180       .WillByDefault(Return(salt_v));
    181   EXPECT_CALL(*mock_library_, GetSystemSalt())
    182       .Times(1)
    183       .RetiresOnSaturation();
    184 
    185   EXPECT_EQ("0a010000000000a0", auth->SaltAsAscii());
    186 }
    187 
    188 TEST_F(GoogleAuthenticatorTest, ReadLocalaccount) {
    189   FilePath tmp_file_path = FakeLocalaccountFile(bytes_as_ascii_);
    190 
    191   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(NULL));
    192   ReadLocalaccountFile(auth.get(), tmp_file_path.BaseName().value());
    193   EXPECT_EQ(auth->localaccount_, bytes_as_ascii_);
    194   Delete(tmp_file_path, false);
    195 }
    196 
    197 TEST_F(GoogleAuthenticatorTest, ReadLocalaccountTrailingWS) {
    198   FilePath tmp_file_path =
    199       FakeLocalaccountFile(base::StringPrintf("%s\n",
    200                                               bytes_as_ascii_.c_str()));
    201 
    202   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(NULL));
    203   ReadLocalaccountFile(auth.get(), tmp_file_path.BaseName().value());
    204   EXPECT_EQ(auth->localaccount_, bytes_as_ascii_);
    205   Delete(tmp_file_path, false);
    206 }
    207 
    208 TEST_F(GoogleAuthenticatorTest, ReadNoLocalaccount) {
    209   FilePath tmp_file_path = FakeLocalaccountFile(bytes_as_ascii_);
    210   EXPECT_TRUE(Delete(tmp_file_path, false));  // Ensure non-existent file.
    211 
    212   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(NULL));
    213   ReadLocalaccountFile(auth.get(), tmp_file_path.BaseName().value());
    214   EXPECT_EQ(auth->localaccount_, std::string());
    215 }
    216 
    217 TEST_F(GoogleAuthenticatorTest, OnLoginSuccess) {
    218   MockConsumer consumer;
    219   EXPECT_CALL(consumer, OnLoginSuccess(username_, password_, _, false))
    220       .Times(1)
    221       .RetiresOnSaturation();
    222 
    223   EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_, _))
    224       .WillOnce(Return(true))
    225       .RetiresOnSaturation();
    226 
    227   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    228   auth->set_password_hash(hash_ascii_);
    229   auth->set_username(username_);
    230   auth->set_password(password_);
    231   auth->OnLoginSuccess(result_, false);
    232 }
    233 
    234 TEST_F(GoogleAuthenticatorTest, MountFailure) {
    235   MockConsumer consumer;
    236   EXPECT_CALL(consumer, OnLoginFailure(_))
    237       .Times(1)
    238       .RetiresOnSaturation();
    239 
    240   EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_, _))
    241       .WillOnce(Return(false))
    242       .RetiresOnSaturation();
    243 
    244   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    245   PrepForLogin(auth.get());
    246   auth->OnLoginSuccess(result_, false);
    247 }
    248 
    249 TEST_F(GoogleAuthenticatorTest, PasswordChange) {
    250   MockConsumer consumer;
    251   EXPECT_CALL(consumer, OnPasswordChangeDetected(result_))
    252       .Times(1)
    253       .RetiresOnSaturation();
    254   EXPECT_CALL(consumer, OnLoginSuccess(username_, password_, result_, false))
    255       .Times(1)
    256       .RetiresOnSaturation();
    257 
    258   EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_, _))
    259       .WillOnce(
    260           DoAll(SetArgumentPointee<2>(
    261               chromeos::kCryptohomeMountErrorKeyFailure),
    262                 Return(false)))
    263       .WillOnce(Return(true))
    264       .RetiresOnSaturation();
    265 
    266   EXPECT_CALL(*mock_library_, GetSystemSalt())
    267       .WillOnce(Return(chromeos::CryptohomeBlob(8, 'a')))
    268       .RetiresOnSaturation();
    269   EXPECT_CALL(*mock_library_, MigrateKey(username_, _, hash_ascii_))
    270       .WillOnce(Return(true))
    271       .RetiresOnSaturation();
    272 
    273   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    274   PrepForLogin(auth.get());
    275   auth->OnLoginSuccess(result_, false);
    276   auth->RecoverEncryptedData("whaty", result_);
    277 }
    278 
    279 TEST_F(GoogleAuthenticatorTest, PasswordChangeWrongPassword) {
    280   MockConsumer consumer;
    281   EXPECT_CALL(consumer, OnPasswordChangeDetected(result_))
    282       .Times(2)
    283       .RetiresOnSaturation();
    284 
    285   EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_, _))
    286       .WillOnce(
    287           DoAll(SetArgumentPointee<2>(
    288               chromeos::kCryptohomeMountErrorKeyFailure),
    289                 Return(false)))
    290       .RetiresOnSaturation();
    291   EXPECT_CALL(*mock_library_, GetSystemSalt())
    292       .WillOnce(Return(chromeos::CryptohomeBlob(8, 'a')))
    293       .RetiresOnSaturation();
    294   EXPECT_CALL(*mock_library_, MigrateKey(username_, _, hash_ascii_))
    295       .WillOnce(Return(false))
    296       .RetiresOnSaturation();
    297 
    298   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    299   PrepForLogin(auth.get());
    300   auth->OnLoginSuccess(result_, false);
    301   auth->RecoverEncryptedData("whaty", result_);
    302 }
    303 
    304 TEST_F(GoogleAuthenticatorTest, ForgetOldData) {
    305   MockConsumer consumer;
    306   EXPECT_CALL(consumer, OnPasswordChangeDetected(result_))
    307       .Times(1)
    308       .RetiresOnSaturation();
    309   EXPECT_CALL(consumer, OnLoginSuccess(username_, password_, result_, false))
    310       .Times(1)
    311       .RetiresOnSaturation();
    312 
    313   EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_, _))
    314       .WillOnce(
    315           DoAll(SetArgumentPointee<2>(
    316               chromeos::kCryptohomeMountErrorKeyFailure),
    317                 Return(false)))
    318       .WillOnce(Return(true))
    319       .RetiresOnSaturation();
    320 
    321   EXPECT_CALL(*mock_library_, Remove(username_))
    322       .WillOnce(Return(true))
    323       .RetiresOnSaturation();
    324 
    325   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    326   PrepForLogin(auth.get());
    327   auth->OnLoginSuccess(result_, false);
    328   auth->ResyncEncryptedData(result_);
    329 }
    330 
    331 TEST_F(GoogleAuthenticatorTest, LoginNetFailure) {
    332   GoogleServiceAuthError error =
    333       GoogleServiceAuthError::FromConnectionError(net::ERR_CONNECTION_RESET);
    334 
    335   LoginFailure failure =
    336       LoginFailure::FromNetworkAuthFailure(error);
    337 
    338   MockConsumer consumer;
    339   EXPECT_CALL(consumer, OnLoginFailure(failure))
    340       .Times(1)
    341       .RetiresOnSaturation();
    342   EXPECT_CALL(*mock_library_, CheckKey(username_, hash_ascii_))
    343       .WillOnce(Return(false))
    344       .RetiresOnSaturation();
    345 
    346   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    347   PrepForLogin(auth.get());
    348   auth->OnClientLoginFailure(error);
    349   message_loop_ui_.RunAllPending();
    350 }
    351 
    352 TEST_F(GoogleAuthenticatorTest, LoginDenied) {
    353   GoogleServiceAuthError client_error(
    354       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
    355 
    356   MockConsumer consumer;
    357   EXPECT_CALL(consumer, OnLoginFailure(_))
    358       .Times(1)
    359       .RetiresOnSaturation();
    360 
    361   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    362   PrepForFailedLogin(auth.get());
    363   EXPECT_CALL(*user_manager_.get(), IsKnownUser(username_))
    364       .WillOnce(Return(true))
    365       .RetiresOnSaturation();
    366   auth->OnClientLoginFailure(client_error);
    367   message_loop_ui_.RunAllPending();
    368 }
    369 
    370 TEST_F(GoogleAuthenticatorTest, LoginAccountDisabled) {
    371   GoogleServiceAuthError client_error(
    372       GoogleServiceAuthError::ACCOUNT_DISABLED);
    373 
    374   MockConsumer consumer;
    375   EXPECT_CALL(consumer, OnLoginFailure(_))
    376       .Times(1)
    377       .RetiresOnSaturation();
    378 
    379   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    380   PrepForFailedLogin(auth.get());
    381   auth->OnClientLoginFailure(client_error);
    382   message_loop_ui_.RunAllPending();
    383 }
    384 
    385 TEST_F(GoogleAuthenticatorTest, LoginAccountDeleted) {
    386   GoogleServiceAuthError client_error(
    387       GoogleServiceAuthError::ACCOUNT_DELETED);
    388 
    389   MockConsumer consumer;
    390   EXPECT_CALL(consumer, OnLoginFailure(_))
    391       .Times(1)
    392       .RetiresOnSaturation();
    393 
    394   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    395   PrepForFailedLogin(auth.get());
    396   auth->OnClientLoginFailure(client_error);
    397   message_loop_ui_.RunAllPending();
    398 }
    399 
    400 TEST_F(GoogleAuthenticatorTest, LoginServiceUnavailable) {
    401   GoogleServiceAuthError client_error(
    402       GoogleServiceAuthError::SERVICE_UNAVAILABLE);
    403 
    404   MockConsumer consumer;
    405   EXPECT_CALL(consumer, OnLoginFailure(_))
    406       .Times(1)
    407       .RetiresOnSaturation();
    408 
    409   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    410   PrepForFailedLogin(auth.get());
    411   auth->OnClientLoginFailure(client_error);
    412   message_loop_ui_.RunAllPending();
    413 }
    414 
    415 TEST_F(GoogleAuthenticatorTest, CaptchaErrorOutputted) {
    416   GoogleServiceAuthError auth_error =
    417       GoogleServiceAuthError::FromCaptchaChallenge(
    418           "CCTOKEN",
    419           GURL("http://www.google.com/accounts/Captcha?ctoken=CCTOKEN"),
    420           GURL("http://www.google.com/login/captcha"));
    421 
    422   LoginFailure failure = LoginFailure::FromNetworkAuthFailure(auth_error);
    423 
    424   MockConsumer consumer;
    425   EXPECT_CALL(consumer, OnLoginFailure(failure))
    426       .Times(1)
    427       .RetiresOnSaturation();
    428 
    429   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    430   PrepForFailedLogin(auth.get());
    431   auth->OnClientLoginFailure(auth_error);
    432   message_loop_ui_.RunAllPending();
    433 }
    434 
    435 TEST_F(GoogleAuthenticatorTest, OfflineLogin) {
    436   GoogleServiceAuthError auth_error(
    437       GoogleServiceAuthError::FromConnectionError(net::ERR_CONNECTION_RESET));
    438 
    439   MockConsumer consumer;
    440   EXPECT_CALL(consumer, OnLoginSuccess(username_, password_, result_, false))
    441       .Times(1)
    442       .RetiresOnSaturation();
    443   EXPECT_CALL(*mock_library_, CheckKey(username_, hash_ascii_))
    444       .WillOnce(Return(true))
    445       .RetiresOnSaturation();
    446   EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_, _))
    447       .WillOnce(Return(true))
    448       .RetiresOnSaturation();
    449 
    450   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    451   PrepForLogin(auth.get());
    452   auth->OnClientLoginFailure(auth_error);
    453   message_loop_ui_.RunAllPending();
    454 }
    455 
    456 TEST_F(GoogleAuthenticatorTest, OnlineLogin) {
    457   MockConsumer consumer;
    458   EXPECT_CALL(consumer, OnLoginSuccess(username_, password_, result_, false))
    459       .Times(1)
    460       .RetiresOnSaturation();
    461   EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_, _))
    462       .WillOnce(Return(true))
    463       .RetiresOnSaturation();
    464 
    465   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    466   PrepForLogin(auth.get());
    467   EXPECT_CALL(*user_manager_.get(), IsKnownUser(username_))
    468       .WillOnce(Return(true))
    469       .RetiresOnSaturation();
    470   auth->OnClientLoginSuccess(result_);
    471   message_loop_ui_.RunAllPending();
    472 }
    473 
    474 TEST_F(GoogleAuthenticatorTest, CheckLocalaccount) {
    475   GURL source(AuthResponseHandler::kTokenAuthUrl);
    476   net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
    477 
    478   MockConsumer consumer;
    479   EXPECT_CALL(consumer, OnLoginSuccess(username_, std::string(), _, false))
    480       .Times(1)
    481       .RetiresOnSaturation();
    482   EXPECT_CALL(*mock_library_, MountForBwsi(_))
    483       .WillOnce(Return(true))
    484       .RetiresOnSaturation();
    485 
    486   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    487   PrepForLogin(auth.get());
    488   auth->SetLocalaccount(username_);
    489 
    490   auth->CheckLocalaccount(LoginFailure(LoginFailure::LOGIN_TIMED_OUT));
    491 }
    492 
    493 TEST_F(GoogleAuthenticatorTest, LocalaccountLogin) {
    494   // This test checks the logic that governs asynchronously reading the
    495   // localaccount name off disk and trying to authenticate against it
    496   // simultaneously.
    497   MockConsumer consumer;
    498   EXPECT_CALL(consumer, OnLoginSuccess(username_, std::string(), _, false))
    499       .WillOnce(Invoke(MockConsumer::OnSuccessQuit))
    500       .RetiresOnSaturation();
    501   EXPECT_CALL(*mock_library_, MountForBwsi(_))
    502       .WillOnce(Return(true))
    503       .RetiresOnSaturation();
    504   // Enable the test to terminate (and fail), even if the login fails.
    505   ON_CALL(consumer, OnLoginFailure(_))
    506       .WillByDefault(Invoke(MockConsumer::OnFailQuitAndFail));
    507 
    508   // Manually prep for login, so that localaccount isn't set for us.
    509   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    510   auth->set_password_hash(hash_ascii_);
    511   auth->set_username(username_);
    512 
    513   // First, force a check of username_ against the localaccount -- which we
    514   // haven't yet gotten off disk.
    515   BrowserThread::PostTask(
    516       BrowserThread::UI, FROM_HERE,
    517       NewRunnableMethod(auth.get(),
    518                         &GoogleAuthenticator::CheckLocalaccount,
    519                         LoginFailure(LoginFailure::LOGIN_TIMED_OUT)));
    520   message_loop_ui_.RunAllPending();
    521   // The foregoing has now rescheduled itself in a few ms because we don't
    522   // yet have the localaccount loaded off disk.
    523 
    524   // Now, cause the FILE thread to go load the localaccount off disk.
    525   FilePath tmp_file_path = FakeLocalaccountFile(username_);
    526   ReadLocalaccountFile(auth.get(), tmp_file_path.BaseName().value());
    527 
    528   // Run remaining events, until OnLoginSuccess or OnLoginFailure is called.
    529   message_loop_ui_.Run();
    530 
    531   // Cleanup.
    532   Delete(tmp_file_path, false);
    533 }
    534 
    535 TEST_F(GoogleAuthenticatorTest, FullLogin) {
    536   chromeos::CryptohomeBlob salt_v(fake_hash_, fake_hash_ + sizeof(fake_hash_));
    537 
    538   MockConsumer consumer;
    539   EXPECT_CALL(consumer, OnLoginSuccess(username_,
    540                                        password_,
    541                                        Eq(result_),
    542                                        false))
    543       .Times(1)
    544       .RetiresOnSaturation();
    545   EXPECT_CALL(*mock_library_, Mount(username_, _, _))
    546       .WillOnce(Return(true))
    547       .RetiresOnSaturation();
    548 
    549   EXPECT_CALL(*mock_library_, GetSystemSalt())
    550       .WillOnce(Return(salt_v))
    551       .RetiresOnSaturation();
    552 
    553   TestingProfile profile;
    554 
    555   MockFactory<MockFetcher> factory;
    556   URLFetcher::set_factory(&factory);
    557 
    558   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    559   EXPECT_CALL(*user_manager_.get(), IsKnownUser(username_))
    560       .WillOnce(Return(true))
    561       .RetiresOnSaturation();
    562   auth->set_user_manager(user_manager_.get());
    563   auth->AuthenticateToLogin(
    564       &profile, username_, password_, std::string(), std::string());
    565 
    566   URLFetcher::set_factory(NULL);
    567   message_loop_ui_.RunAllPending();
    568 }
    569 
    570 TEST_F(GoogleAuthenticatorTest, FullHostedLoginFailure) {
    571   chromeos::CryptohomeBlob salt_v(fake_hash_, fake_hash_ + sizeof(fake_hash_));
    572 
    573   LoginFailure failure_details =
    574       LoginFailure::FromNetworkAuthFailure(
    575           GoogleServiceAuthError(
    576               GoogleServiceAuthError::HOSTED_NOT_ALLOWED));
    577 
    578   MockConsumer consumer;
    579   EXPECT_CALL(consumer, OnLoginFailure(failure_details))
    580       .WillOnce(Invoke(MockConsumer::OnFailQuit))
    581       .RetiresOnSaturation();
    582   // A failure case, but we still want the test to finish gracefully.
    583   ON_CALL(consumer, OnLoginSuccess(username_, password_, _, _))
    584       .WillByDefault(Invoke(MockConsumer::OnSuccessQuitAndFail));
    585 
    586   EXPECT_CALL(*mock_library_, GetSystemSalt())
    587       .WillOnce(Return(salt_v))
    588       .RetiresOnSaturation();
    589 
    590   TestingProfile profile;
    591 
    592   MockFactory<HostedFetcher> factory_invalid;
    593   URLFetcher::set_factory(&factory_invalid);
    594 
    595   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    596   auth->set_user_manager(user_manager_.get());
    597   EXPECT_CALL(*user_manager_.get(), IsKnownUser(username_))
    598       .WillOnce(Return(false))
    599       .WillOnce(Return(false))
    600       .RetiresOnSaturation();
    601   auth->AuthenticateToLogin(
    602       &profile, username_, hash_ascii_, std::string(), std::string());
    603 
    604   // For when |auth| tries to load the localaccount file.
    605   BrowserThread file_thread(BrowserThread::FILE);
    606   file_thread.Start();
    607 
    608   // Run the UI thread until we exit it gracefully.
    609   message_loop_ui_.Run();
    610   URLFetcher::set_factory(NULL);
    611 }
    612 
    613 TEST_F(GoogleAuthenticatorTest, CancelLogin) {
    614   chromeos::CryptohomeBlob salt_v(fake_hash_, fake_hash_ + sizeof(fake_hash_));
    615 
    616   MockConsumer consumer;
    617   // The expected case.
    618   EXPECT_CALL(consumer, OnLoginFailure(_))
    619       .WillOnce(Invoke(MockConsumer::OnFailQuit))
    620       .RetiresOnSaturation();
    621 
    622   // A failure case, but we still want the test to finish gracefully.
    623   ON_CALL(consumer, OnLoginSuccess(username_, password_, _, _))
    624       .WillByDefault(Invoke(MockConsumer::OnSuccessQuitAndFail));
    625 
    626   // Stuff we expect to happen along the way.
    627   EXPECT_CALL(*mock_library_, GetSystemSalt())
    628       .WillOnce(Return(salt_v))
    629       .RetiresOnSaturation();
    630   EXPECT_CALL(*mock_library_, CheckKey(username_, _))
    631       .WillOnce(Return(false))
    632       .RetiresOnSaturation();
    633 
    634   TestingProfile profile;
    635 
    636   // This is how we inject fake URLFetcher objects, with a factory.
    637   // This factory creates fake URLFetchers that Start() a fake fetch attempt
    638   // and then come back on the UI thread after a small delay.  They expect to
    639   // be canceled before they come back, and the test will fail if they are not.
    640   MockFactory<ExpectCanceledFetcher> factory;
    641   URLFetcher::set_factory(&factory);
    642 
    643   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    644   // For when |auth| tries to load the localaccount file.
    645   BrowserThread file_thread(BrowserThread::FILE);
    646   file_thread.Start();
    647 
    648   // Start an authentication attempt, which will kick off a URL "fetch" that
    649   // we expect to cancel before it completes.
    650   auth->AuthenticateToLogin(
    651       &profile, username_, hash_ascii_, std::string(), std::string());
    652 
    653   // Post a task to cancel the login attempt.
    654   CancelLogin(auth.get());
    655 
    656   URLFetcher::set_factory(NULL);
    657 
    658   // Run the UI thread until we exit it gracefully.
    659   message_loop_ui_.Run();
    660 }
    661 
    662 TEST_F(GoogleAuthenticatorTest, CancelLoginAlreadyGotLocalaccount) {
    663   chromeos::CryptohomeBlob salt_v(fake_hash_, fake_hash_ + sizeof(fake_hash_));
    664 
    665   MockConsumer consumer;
    666   // The expected case.
    667   EXPECT_CALL(consumer, OnLoginFailure(_))
    668       .WillOnce(Invoke(MockConsumer::OnFailQuit))
    669       .RetiresOnSaturation();
    670 
    671   // A failure case, but we still want the test to finish gracefully.
    672   ON_CALL(consumer, OnLoginSuccess(username_, password_, _, _))
    673       .WillByDefault(Invoke(MockConsumer::OnSuccessQuitAndFail));
    674 
    675   // Stuff we expect to happen along the way.
    676   EXPECT_CALL(*mock_library_, GetSystemSalt())
    677       .WillOnce(Return(salt_v))
    678       .RetiresOnSaturation();
    679   EXPECT_CALL(*mock_library_, CheckKey(username_, _))
    680       .WillOnce(Return(false))
    681       .RetiresOnSaturation();
    682 
    683   TestingProfile profile;
    684 
    685   // This is how we inject fake URLFetcher objects, with a factory.
    686   // This factory creates fake URLFetchers that Start() a fake fetch attempt
    687   // and then come back on the UI thread after a small delay.  They expect to
    688   // be canceled before they come back, and the test will fail if they are not.
    689   MockFactory<ExpectCanceledFetcher> factory;
    690   URLFetcher::set_factory(&factory);
    691 
    692   scoped_refptr<GoogleAuthenticator> auth(new GoogleAuthenticator(&consumer));
    693   // This time, instead of allowing |auth| to go get the localaccount file
    694   // itself, we simulate the case where the file is already loaded, which
    695   // happens when this isn't the first login since chrome started.
    696   ReadLocalaccountFile(auth.get(), "");
    697 
    698   // Start an authentication attempt, which will kick off a URL "fetch" that
    699   // we expect to cancel before it completes.
    700   auth->AuthenticateToLogin(
    701       &profile, username_, hash_ascii_, std::string(), std::string());
    702 
    703   // Post a task to cancel the login attempt.
    704   CancelLogin(auth.get());
    705 
    706   URLFetcher::set_factory(NULL);
    707 
    708   // Run the UI thread until we exit it gracefully.
    709   message_loop_ui_.Run();
    710 }
    711 
    712 }  // namespace chromeos
    713