Home | History | Annotate | Download | only in login
      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 #include "chrome/browser/chromeos/login/login_utils.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/bind.h"
      9 #include "base/command_line.h"
     10 #include "base/files/scoped_temp_dir.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/path_service.h"
     13 #include "base/prefs/pref_registry_simple.h"
     14 #include "base/run_loop.h"
     15 #include "base/strings/string_util.h"
     16 #include "base/synchronization/waitable_event.h"
     17 #include "base/threading/sequenced_worker_pool.h"
     18 #include "base/threading/thread.h"
     19 #include "chrome/browser/chrome_notification_types.h"
     20 #include "chrome/browser/chromeos/cros/network_library.h"
     21 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
     22 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
     23 #include "chrome/browser/chromeos/login/authenticator.h"
     24 #include "chrome/browser/chromeos/login/login_status_consumer.h"
     25 #include "chrome/browser/chromeos/login/user_manager.h"
     26 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
     27 #include "chrome/browser/chromeos/settings/cros_settings.h"
     28 #include "chrome/browser/chromeos/settings/device_settings_service.h"
     29 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
     30 #include "chrome/browser/chromeos/settings/mock_owner_key_util.h"
     31 #include "chrome/browser/io_thread.h"
     32 #include "chrome/browser/net/predictor.h"
     33 #include "chrome/browser/policy/browser_policy_connector.h"
     34 #include "chrome/browser/policy/cloud/device_management_service.h"
     35 #include "chrome/browser/policy/policy_service.h"
     36 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
     37 #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h"
     38 #include "chrome/browser/profiles/profile_manager.h"
     39 #include "chrome/browser/rlz/rlz.h"
     40 #include "chrome/common/chrome_paths.h"
     41 #include "chrome/common/chrome_switches.h"
     42 #include "chrome/common/pref_names.h"
     43 #include "chrome/test/base/scoped_testing_local_state.h"
     44 #include "chrome/test/base/testing_browser_process.h"
     45 #include "chromeos/chromeos_switches.h"
     46 #include "chromeos/cryptohome/mock_async_method_caller.h"
     47 #include "chromeos/cryptohome/mock_cryptohome_library.h"
     48 #include "chromeos/dbus/mock_dbus_thread_manager_without_gmock.h"
     49 #include "chromeos/disks/disk_mount_manager.h"
     50 #include "chromeos/disks/mock_disk_mount_manager.h"
     51 #include "chromeos/login/login_state.h"
     52 #include "chromeos/network/network_handler.h"
     53 #include "content/public/browser/browser_thread.h"
     54 #include "content/public/test/test_browser_thread.h"
     55 #include "content/public/test/test_utils.h"
     56 #include "google_apis/gaia/gaia_auth_consumer.h"
     57 #include "google_apis/gaia/gaia_urls.h"
     58 #include "net/url_request/test_url_fetcher_factory.h"
     59 #include "net/url_request/url_fetcher_delegate.h"
     60 #include "net/url_request/url_request.h"
     61 #include "net/url_request/url_request_context_getter.h"
     62 #include "net/url_request/url_request_status.h"
     63 #include "testing/gmock/include/gmock/gmock.h"
     64 #include "testing/gtest/include/gtest/gtest.h"
     65 
     66 #if defined(ENABLE_RLZ)
     67 #include "rlz/lib/rlz_value_store.h"
     68 #endif
     69 
     70 using ::testing::AnyNumber;
     71 
     72 namespace chromeos {
     73 
     74 namespace {
     75 
     76 namespace em = enterprise_management;
     77 
     78 using ::testing::DoAll;
     79 using ::testing::Return;
     80 using ::testing::SaveArg;
     81 using ::testing::SetArgPointee;
     82 using ::testing::_;
     83 using content::BrowserThread;
     84 
     85 const char kTrue[] = "true";
     86 const char kFalse[] = "false";
     87 const char kDomain[] = "domain.com";
     88 const char kUsername[] = "user (at) domain.com";
     89 const char kMode[] = "enterprise";
     90 const char kDeviceId[] = "100200300";
     91 const char kUsernameOtherDomain[] = "user (at) other.com";
     92 const char kAttributeOwned[] = "enterprise.owned";
     93 const char kAttributeOwner[] = "enterprise.user";
     94 const char kAttributeConsumerKiosk[] = "consumer.app_kiosk_enabled";
     95 const char kAttrEnterpriseDomain[] = "enterprise.domain";
     96 const char kAttrEnterpriseMode[] = "enterprise.mode";
     97 const char kAttrEnterpriseDeviceId[] = "enterprise.device_id";
     98 
     99 const char kOAuthTokenCookie[] = "oauth_token=1234";
    100 
    101 const char kGaiaAccountDisabledResponse[] = "Error=AccountDeleted";
    102 
    103 const char kOAuth2TokenPairData[] =
    104     "{"
    105     "  \"refresh_token\": \"1234\","
    106     "  \"access_token\": \"5678\","
    107     "  \"expires_in\": 3600"
    108     "}";
    109 
    110 const char kOAuth2AccessTokenData[] =
    111     "{"
    112     "  \"access_token\": \"5678\","
    113     "  \"expires_in\": 3600"
    114     "}";
    115 
    116 const char kDMServer[] = "http://server/device_management";
    117 const char kDMRegisterRequest[] =
    118     "http://server/device_management?request=register";
    119 const char kDMPolicyRequest[] =
    120     "http://server/device_management?request=policy";
    121 
    122 const char kDMToken[] = "1234";
    123 
    124 // Used to mark |flag|, indicating that RefreshPolicies() has executed its
    125 // callback.
    126 void SetFlag(bool* flag) {
    127   *flag = true;
    128 }
    129 
    130 // Single task of the fake IO loop used in the test, that just waits until
    131 // it is signaled to quit or perform some work.
    132 // |completion| is the event to wait for, and |work| is the task to invoke
    133 // when signaled. If the task returns false then this quits the IO loop.
    134 void BlockLoop(base::WaitableEvent* completion, base::Callback<bool()> work) {
    135   do {
    136     completion->Wait();
    137   } while (work.Run());
    138   base::MessageLoop::current()->QuitNow();
    139 }
    140 
    141 void CopyLockResult(base::RunLoop* loop,
    142                     policy::EnterpriseInstallAttributes::LockResult* out,
    143                     policy::EnterpriseInstallAttributes::LockResult result) {
    144   *out = result;
    145   loop->Quit();
    146 }
    147 
    148 class LoginUtilsTest : public testing::Test,
    149                        public LoginUtils::Delegate,
    150                        public LoginStatusConsumer {
    151  public:
    152   // Initialization here is important. The UI thread gets the test's
    153   // message loop, as does the file thread (which never actually gets
    154   // started - so this is a way to fake multiple threads on a single
    155   // test thread).  The IO thread does not get the message loop set,
    156   // and is never started.  This is necessary so that we skip various
    157   // bits of initialization that get posted to the IO thread.  We do
    158   // however, at one point in the test, temporarily set the message
    159   // loop for the IO thread.
    160   LoginUtilsTest()
    161       : fake_io_thread_completion_(false, false),
    162         fake_io_thread_("fake_io_thread"),
    163         loop_(base::MessageLoop::TYPE_IO),
    164         browser_process_(TestingBrowserProcess::GetGlobal()),
    165         local_state_(browser_process_),
    166         ui_thread_(BrowserThread::UI, &loop_),
    167         db_thread_(BrowserThread::DB, &loop_),
    168         file_thread_(BrowserThread::FILE, &loop_),
    169         mock_input_method_manager_(NULL),
    170         mock_async_method_caller_(NULL),
    171         connector_(NULL),
    172         prepared_profile_(NULL) {}
    173 
    174   virtual void SetUp() OVERRIDE {
    175     // This test is not a full blown InProcessBrowserTest, and doesn't have
    176     // all the usual threads running. However a lot of subsystems pulled from
    177     // ProfileImpl post to IO (usually from ProfileIOData), and DCHECK that
    178     // those tasks were posted. Those tasks in turn depend on a lot of other
    179     // components that aren't there during this test, so this kludge is used to
    180     // have a running IO loop that doesn't really execute any tasks.
    181     //
    182     // See InvokeOnIO() below for a way to perform specific tasks on IO, when
    183     // that's necessary.
    184 
    185     // A thread is needed to create a new MessageLoop, since there can be only
    186     // one loop per thread.
    187     fake_io_thread_.StartWithOptions(
    188         base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
    189     base::MessageLoop* fake_io_loop = fake_io_thread_.message_loop();
    190     // Make this loop enter the single task, BlockLoop(). Pass in the completion
    191     // event and the work callback.
    192     fake_io_thread_.StopSoon();
    193     fake_io_loop->PostTask(
    194         FROM_HERE,
    195         base::Bind(
    196           BlockLoop,
    197           &fake_io_thread_completion_,
    198           base::Bind(&LoginUtilsTest::DoIOWork, base::Unretained(this))));
    199     // Map BrowserThread::IO to this loop. This allows posting to IO but nothing
    200     // will be executed.
    201     io_thread_.reset(
    202         new content::TestBrowserThread(BrowserThread::IO, fake_io_loop));
    203 
    204     ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    205 
    206     CommandLine* command_line = CommandLine::ForCurrentProcess();
    207     command_line->AppendSwitchASCII(
    208         ::switches::kDeviceManagementUrl, kDMServer);
    209     command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
    210 
    211     // DBusThreadManager should be initialized before io_thread_state_, as
    212     // DBusThreadManager is used from chromeos::ProxyConfigServiceImpl,
    213     // which is part of io_thread_state_.
    214     DBusThreadManager::InitializeForTesting(&mock_dbus_thread_manager_);
    215 
    216     CryptohomeLibrary::Initialize();
    217     LoginState::Initialize();
    218 
    219     mock_input_method_manager_ = new input_method::MockInputMethodManager();
    220     input_method::InitializeForTesting(mock_input_method_manager_);
    221     disks::DiskMountManager::InitializeForTesting(&mock_disk_mount_manager_);
    222     mock_disk_mount_manager_.SetupDefaultReplies();
    223 
    224     mock_async_method_caller_ = new cryptohome::MockAsyncMethodCaller;
    225     cryptohome::AsyncMethodCaller::InitializeForTesting(
    226         mock_async_method_caller_);
    227 
    228     cryptohome_.reset(new MockCryptohomeLibrary());
    229     EXPECT_CALL(*cryptohome_, InstallAttributesIsInvalid())
    230         .WillRepeatedly(Return(false));
    231     EXPECT_CALL(*cryptohome_, InstallAttributesIsFirstInstall())
    232         .WillRepeatedly(Return(true));
    233     EXPECT_CALL(*cryptohome_, TpmIsEnabled())
    234         .WillRepeatedly(Return(false));
    235     EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttributeOwned, kTrue))
    236         .WillRepeatedly(Return(true));
    237     EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttributeOwner,
    238                                                    kUsername))
    239         .WillRepeatedly(Return(true));
    240     EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttrEnterpriseDomain,
    241                                                    kDomain))
    242         .WillRepeatedly(Return(true));
    243     EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttrEnterpriseMode,
    244                                                    kMode))
    245         .WillRepeatedly(Return(true));
    246     EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttrEnterpriseDeviceId,
    247                                                    kDeviceId))
    248         .WillRepeatedly(Return(true));
    249     EXPECT_CALL(*cryptohome_, InstallAttributesFinalize())
    250         .WillRepeatedly(Return(true));
    251     EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttributeOwned, _))
    252         .WillRepeatedly(DoAll(SetArgPointee<1>(kTrue),
    253                               Return(true)));
    254     EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttributeConsumerKiosk, _))
    255         .WillRepeatedly(DoAll(SetArgPointee<1>(kFalse),
    256                               Return(true)));
    257     EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttributeOwner, _))
    258         .WillRepeatedly(DoAll(SetArgPointee<1>(kUsername),
    259                               Return(true)));
    260     EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttrEnterpriseDomain, _))
    261         .WillRepeatedly(DoAll(SetArgPointee<1>(kDomain),
    262                               Return(true)));
    263     EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttrEnterpriseMode, _))
    264         .WillRepeatedly(DoAll(SetArgPointee<1>(kMode),
    265                               Return(true)));
    266     EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttrEnterpriseDeviceId, _))
    267         .WillRepeatedly(DoAll(SetArgPointee<1>(kDeviceId),
    268                               Return(true)));
    269     CryptohomeLibrary::SetForTest(cryptohome_.get());
    270 
    271     test_device_settings_service_.reset(new ScopedTestDeviceSettingsService);
    272     test_cros_settings_.reset(new ScopedTestCrosSettings);
    273     test_user_manager_.reset(new ScopedTestUserManager);
    274 
    275     browser_process_->SetProfileManager(
    276         new ProfileManagerWithoutInit(scoped_temp_dir_.path()));
    277     connector_ = browser_process_->browser_policy_connector();
    278     connector_->Init(local_state_.Get(),
    279                      browser_process_->system_request_context());
    280 
    281     // IOThread creates ProxyConfigServiceImpl which in turn needs
    282     // NetworkHandler. Thus initialize it here before creating IOThread.
    283     NetworkHandler::Initialize();
    284 
    285     io_thread_state_.reset(new IOThread(local_state_.Get(),
    286                                         browser_process_->policy_service(),
    287                                         NULL, NULL));
    288     browser_process_->SetIOThread(io_thread_state_.get());
    289 
    290 #if defined(ENABLE_RLZ)
    291     rlz_initialized_cb_ = base::Bind(&base::DoNothing);
    292     rlz_lib::testing::SetRlzStoreDirectory(scoped_temp_dir_.path());
    293     RLZTracker::EnableZeroDelayForTesting();
    294 #endif
    295 
    296     RunUntilIdle();
    297   }
    298 
    299   virtual void TearDown() OVERRIDE {
    300     cryptohome::AsyncMethodCaller::Shutdown();
    301     mock_async_method_caller_ = NULL;
    302 
    303     test_user_manager_.reset();
    304 
    305     InvokeOnIO(
    306         base::Bind(&LoginUtilsTest::TearDownOnIO, base::Unretained(this)));
    307 
    308     // LoginUtils instance must not outlive Profile instances.
    309     LoginUtils::Set(NULL);
    310 
    311     input_method::Shutdown();
    312     LoginState::Shutdown();
    313     CryptohomeLibrary::Shutdown();
    314 
    315     // These trigger some tasks that have to run while BrowserThread::UI
    316     // exists. Delete all the profiles before deleting the connector.
    317     browser_process_->SetProfileManager(NULL);
    318     connector_ = NULL;
    319     browser_process_->SetBrowserPolicyConnector(NULL);
    320     QuitIOLoop();
    321     RunUntilIdle();
    322 
    323     CryptohomeLibrary::SetForTest(NULL);
    324   }
    325 
    326   void TearDownOnIO() {
    327     // chrome_browser_net::Predictor usually skips its shutdown routines on
    328     // unit_tests, but does the full thing when
    329     // g_browser_process->profile_manager() is valid during initialization.
    330     // That includes a WaitableEvent on UI waiting for a task on IO, so that
    331     // task must execute. Do it directly from here now.
    332     std::vector<Profile*> profiles =
    333         browser_process_->profile_manager()->GetLoadedProfiles();
    334     for (size_t i = 0; i < profiles.size(); ++i) {
    335       chrome_browser_net::Predictor* predictor =
    336           profiles[i]->GetNetworkPredictor();
    337       if (predictor) {
    338         predictor->EnablePredictorOnIOThread(false);
    339         predictor->Shutdown();
    340       }
    341     }
    342   }
    343 
    344   void RunUntilIdle() {
    345     loop_.RunUntilIdle();
    346     BrowserThread::GetBlockingPool()->FlushForTesting();
    347     loop_.RunUntilIdle();
    348   }
    349 
    350   // Invokes |task| on the IO loop and returns after it has executed.
    351   void InvokeOnIO(const base::Closure& task) {
    352     fake_io_thread_work_ = task;
    353     fake_io_thread_completion_.Signal();
    354     content::RunMessageLoop();
    355   }
    356 
    357   // Makes the fake IO loop return.
    358   void QuitIOLoop() {
    359     fake_io_thread_completion_.Signal();
    360     content::RunMessageLoop();
    361   }
    362 
    363   // Helper for BlockLoop, InvokeOnIO and QuitIOLoop.
    364   bool DoIOWork() {
    365     bool has_work = !fake_io_thread_work_.is_null();
    366     if (has_work)
    367       fake_io_thread_work_.Run();
    368     fake_io_thread_work_.Reset();
    369     BrowserThread::PostTask(
    370         BrowserThread::UI, FROM_HERE,
    371         base::MessageLoop::QuitWhenIdleClosure());
    372     // If there was work then keep waiting for more work.
    373     // If there was no work then quit the fake IO loop.
    374     return has_work;
    375   }
    376 
    377   virtual void OnProfilePrepared(Profile* profile) OVERRIDE {
    378     EXPECT_FALSE(prepared_profile_);
    379     prepared_profile_ = profile;
    380   }
    381 
    382 #if defined(ENABLE_RLZ)
    383   virtual void OnRlzInitialized(Profile* profile) OVERRIDE {
    384     rlz_initialized_cb_.Run();
    385   }
    386 #endif
    387 
    388   virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE {
    389     FAIL() << "OnLoginFailure not expected";
    390   }
    391 
    392   virtual void OnLoginSuccess(const UserContext& user_context,
    393                               bool pending_requests,
    394                               bool using_oauth) OVERRIDE {
    395     FAIL() << "OnLoginSuccess not expected";
    396   }
    397 
    398   void EnrollDevice(const std::string& username) {
    399     EXPECT_CALL(*cryptohome_, InstallAttributesIsFirstInstall())
    400         .WillOnce(Return(true))
    401         .WillRepeatedly(Return(false));
    402 
    403     base::RunLoop loop;
    404     policy::EnterpriseInstallAttributes::LockResult result;
    405     connector_->GetInstallAttributes()->LockDevice(
    406         username, policy::DEVICE_MODE_ENTERPRISE, kDeviceId,
    407         base::Bind(&CopyLockResult, &loop, &result));
    408     loop.Run();
    409     EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS, result);
    410     RunUntilIdle();
    411   }
    412 
    413   void PrepareProfile(const std::string& username) {
    414     // Normally this would happen during browser startup, but for tests
    415     // we need to trigger creation of Profile-related services.
    416     ChromeBrowserMainExtraPartsProfiles::
    417         EnsureBrowserContextKeyedServiceFactoriesBuilt();
    418     ProfileManager::AllowGetDefaultProfile();
    419 
    420     DeviceSettingsTestHelper device_settings_test_helper;
    421     DeviceSettingsService::Get()->SetSessionManager(
    422         &device_settings_test_helper, new MockOwnerKeyUtil());
    423 
    424     EXPECT_CALL(*cryptohome_, GetSystemSalt())
    425         .WillRepeatedly(Return(std::string("stub_system_salt")));
    426     EXPECT_CALL(*mock_async_method_caller_, AsyncMount(_, _, _, _))
    427         .WillRepeatedly(Return());
    428     EXPECT_CALL(*mock_async_method_caller_, AsyncGetSanitizedUsername(_, _))
    429         .WillRepeatedly(Return());
    430 
    431     scoped_refptr<Authenticator> authenticator =
    432         LoginUtils::Get()->CreateAuthenticator(this);
    433     authenticator->CompleteLogin(ProfileManager::GetDefaultProfile(),
    434                                  UserContext(username,
    435                                              "password",
    436                                              std::string(),
    437                                              username));   // username_hash
    438 
    439     const bool kUsingOAuth = true;
    440     // Setting |kHasCookies| to false prevents ProfileAuthData::Transfer from
    441     // waiting for an IO task before proceeding.
    442     const bool kHasCookies = false;
    443     const bool kHasActiveSession = false;
    444     LoginUtils::Get()->PrepareProfile(
    445         UserContext(username, "password", std::string(), username),
    446         std::string(), kUsingOAuth, kHasCookies, kHasActiveSession, this);
    447     device_settings_test_helper.Flush();
    448     RunUntilIdle();
    449 
    450     DeviceSettingsService::Get()->UnsetSessionManager();
    451   }
    452 
    453   net::TestURLFetcher* PrepareOAuthFetcher(const std::string& expected_url) {
    454     net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
    455     EXPECT_TRUE(fetcher);
    456     if (!fetcher)
    457       return NULL;
    458     EXPECT_TRUE(fetcher->delegate());
    459     EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(),
    460                                 expected_url,
    461                                 true));
    462     fetcher->set_url(fetcher->GetOriginalURL());
    463     fetcher->set_response_code(200);
    464     fetcher->set_status(net::URLRequestStatus());
    465     return fetcher;
    466   }
    467 
    468   net::TestURLFetcher* PrepareDMServiceFetcher(
    469       const std::string& expected_url,
    470       const em::DeviceManagementResponse& response) {
    471     net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(
    472         policy::DeviceManagementService::kURLFetcherID);
    473     EXPECT_TRUE(fetcher);
    474     if (!fetcher)
    475       return NULL;
    476     EXPECT_TRUE(fetcher->delegate());
    477     EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(),
    478                                 expected_url,
    479                                 true));
    480     fetcher->set_url(fetcher->GetOriginalURL());
    481     fetcher->set_response_code(200);
    482     fetcher->set_status(net::URLRequestStatus());
    483     std::string data;
    484     EXPECT_TRUE(response.SerializeToString(&data));
    485     fetcher->SetResponseString(data);
    486     return fetcher;
    487   }
    488 
    489   net::TestURLFetcher* PrepareDMRegisterFetcher() {
    490     em::DeviceManagementResponse response;
    491     em::DeviceRegisterResponse* register_response =
    492         response.mutable_register_response();
    493     register_response->set_device_management_token(kDMToken);
    494     register_response->set_enrollment_type(
    495         em::DeviceRegisterResponse::ENTERPRISE);
    496     return PrepareDMServiceFetcher(kDMRegisterRequest, response);
    497   }
    498 
    499   net::TestURLFetcher* PrepareDMPolicyFetcher() {
    500     em::DeviceManagementResponse response;
    501     response.mutable_policy_response()->add_response();
    502     return PrepareDMServiceFetcher(kDMPolicyRequest, response);
    503   }
    504 
    505  protected:
    506   ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
    507 
    508   base::Closure fake_io_thread_work_;
    509   base::WaitableEvent fake_io_thread_completion_;
    510   base::Thread fake_io_thread_;
    511 
    512   base::MessageLoop loop_;
    513   TestingBrowserProcess* browser_process_;
    514   ScopedTestingLocalState local_state_;
    515 
    516   content::TestBrowserThread ui_thread_;
    517   content::TestBrowserThread db_thread_;
    518   content::TestBrowserThread file_thread_;
    519   scoped_ptr<content::TestBrowserThread> io_thread_;
    520   scoped_ptr<IOThread> io_thread_state_;
    521 
    522   MockDBusThreadManagerWithoutGMock mock_dbus_thread_manager_;
    523   input_method::MockInputMethodManager* mock_input_method_manager_;
    524   disks::MockDiskMountManager mock_disk_mount_manager_;
    525   net::TestURLFetcherFactory test_url_fetcher_factory_;
    526 
    527   cryptohome::MockAsyncMethodCaller* mock_async_method_caller_;
    528 
    529   policy::BrowserPolicyConnector* connector_;
    530   scoped_ptr<MockCryptohomeLibrary> cryptohome_;
    531 
    532   // Initialized after |mock_dbus_thread_manager_| and |cryptohome_| are set up.
    533   scoped_ptr<ScopedTestDeviceSettingsService> test_device_settings_service_;
    534   scoped_ptr<ScopedTestCrosSettings> test_cros_settings_;
    535   scoped_ptr<ScopedTestUserManager> test_user_manager_;
    536 
    537   Profile* prepared_profile_;
    538 
    539   base::Closure rlz_initialized_cb_;
    540 
    541  private:
    542   base::ScopedTempDir scoped_temp_dir_;
    543 
    544   std::string device_policy_;
    545   std::string user_policy_;
    546 
    547   DISALLOW_COPY_AND_ASSIGN(LoginUtilsTest);
    548 };
    549 
    550 class LoginUtilsBlockingLoginTest
    551     : public LoginUtilsTest,
    552       public testing::WithParamInterface<int> {};
    553 
    554 TEST_F(LoginUtilsTest, NormalLoginDoesntBlock) {
    555   UserManager* user_manager = UserManager::Get();
    556   EXPECT_FALSE(user_manager->IsUserLoggedIn());
    557   EXPECT_FALSE(connector_->IsEnterpriseManaged());
    558   EXPECT_FALSE(prepared_profile_);
    559   EXPECT_EQ(policy::USER_AFFILIATION_NONE,
    560             connector_->GetUserAffiliation(kUsername));
    561 
    562   // The profile will be created without waiting for a policy response.
    563   PrepareProfile(kUsername);
    564 
    565   EXPECT_TRUE(prepared_profile_);
    566   ASSERT_TRUE(user_manager->IsUserLoggedIn());
    567   EXPECT_EQ(kUsername, user_manager->GetLoggedInUser()->email());
    568 }
    569 
    570 TEST_F(LoginUtilsTest, EnterpriseLoginDoesntBlockForNormalUser) {
    571   UserManager* user_manager = UserManager::Get();
    572   EXPECT_FALSE(user_manager->IsUserLoggedIn());
    573   EXPECT_FALSE(connector_->IsEnterpriseManaged());
    574   EXPECT_FALSE(prepared_profile_);
    575 
    576   // Enroll the device.
    577   EnrollDevice(kUsername);
    578 
    579   EXPECT_FALSE(user_manager->IsUserLoggedIn());
    580   EXPECT_TRUE(connector_->IsEnterpriseManaged());
    581   EXPECT_EQ(kDomain, connector_->GetEnterpriseDomain());
    582   EXPECT_FALSE(prepared_profile_);
    583   EXPECT_EQ(policy::USER_AFFILIATION_NONE,
    584             connector_->GetUserAffiliation(kUsernameOtherDomain));
    585 
    586   // Login with a non-enterprise user shouldn't block.
    587   PrepareProfile(kUsernameOtherDomain);
    588 
    589   EXPECT_TRUE(prepared_profile_);
    590   ASSERT_TRUE(user_manager->IsUserLoggedIn());
    591   EXPECT_EQ(kUsernameOtherDomain, user_manager->GetLoggedInUser()->email());
    592 }
    593 
    594 #if defined(ENABLE_RLZ)
    595 TEST_F(LoginUtilsTest, RlzInitialized) {
    596   // No RLZ brand code set initially.
    597   EXPECT_FALSE(local_state_.Get()->HasPrefPath(prefs::kRLZBrand));
    598 
    599   base::RunLoop wait_for_rlz_init;
    600   rlz_initialized_cb_ = wait_for_rlz_init.QuitClosure();
    601 
    602   PrepareProfile(kUsername);
    603 
    604   wait_for_rlz_init.Run();
    605   // Wait for blocking RLZ tasks to complete.
    606   RunUntilIdle();
    607 
    608   // RLZ brand code has been set to empty string.
    609   EXPECT_TRUE(local_state_.Get()->HasPrefPath(prefs::kRLZBrand));
    610   EXPECT_EQ(std::string(), local_state_.Get()->GetString(prefs::kRLZBrand));
    611 
    612   // RLZ value for homepage access point should have been initialized.
    613   string16 rlz_string;
    614   EXPECT_TRUE(RLZTracker::GetAccessPointRlz(
    615       RLZTracker::CHROME_HOME_PAGE, &rlz_string));
    616   EXPECT_EQ(string16(), rlz_string);
    617 }
    618 #endif
    619 
    620 TEST_P(LoginUtilsBlockingLoginTest, EnterpriseLoginBlocksForEnterpriseUser) {
    621   UserManager* user_manager = UserManager::Get();
    622   EXPECT_FALSE(user_manager->IsUserLoggedIn());
    623   EXPECT_FALSE(connector_->IsEnterpriseManaged());
    624   EXPECT_FALSE(prepared_profile_);
    625 
    626   // Enroll the device.
    627   EnrollDevice(kUsername);
    628 
    629   EXPECT_FALSE(user_manager->IsUserLoggedIn());
    630   EXPECT_TRUE(connector_->IsEnterpriseManaged());
    631   EXPECT_EQ(kDomain, connector_->GetEnterpriseDomain());
    632   EXPECT_FALSE(prepared_profile_);
    633   EXPECT_EQ(policy::USER_AFFILIATION_MANAGED,
    634             connector_->GetUserAffiliation(kUsername));
    635   EXPECT_FALSE(user_manager->IsKnownUser(kUsername));
    636 
    637   // Login with a user of the enterprise domain waits for policy.
    638   PrepareProfile(kUsername);
    639 
    640   EXPECT_FALSE(prepared_profile_);
    641   ASSERT_TRUE(user_manager->IsUserLoggedIn());
    642   EXPECT_TRUE(user_manager->IsCurrentUserNew());
    643 
    644   GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
    645   net::TestURLFetcher* fetcher;
    646 
    647   // |steps| is the test parameter, and is the number of successful fetches.
    648   // The first incomplete fetch will fail. In any case, the profile creation
    649   // should resume.
    650   int steps = GetParam();
    651 
    652   // The next expected fetcher ID. This is used to make it fail.
    653   int next_expected_fetcher_id = 0;
    654 
    655   do {
    656     if (steps < 1) break;
    657 
    658     // Fake refresh token retrieval:
    659     fetcher = PrepareOAuthFetcher(gaia_urls->client_login_to_oauth2_url());
    660     ASSERT_TRUE(fetcher);
    661     net::ResponseCookies cookies;
    662     cookies.push_back(kOAuthTokenCookie);
    663     fetcher->set_cookies(cookies);
    664     fetcher->delegate()->OnURLFetchComplete(fetcher);
    665     if (steps < 2) break;
    666 
    667     // Fake OAuth2 token pair retrieval:
    668     fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url());
    669     ASSERT_TRUE(fetcher);
    670     fetcher->SetResponseString(kOAuth2TokenPairData);
    671     fetcher->delegate()->OnURLFetchComplete(fetcher);
    672     if (steps < 3) break;
    673 
    674     // Fake OAuth2 access token retrieval:
    675     fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url());
    676     ASSERT_TRUE(fetcher);
    677     fetcher->SetResponseString(kOAuth2AccessTokenData);
    678     fetcher->delegate()->OnURLFetchComplete(fetcher);
    679 
    680     // The cloud policy subsystem is now ready to fetch the dmtoken and the user
    681     // policy.
    682     next_expected_fetcher_id = policy::DeviceManagementService::kURLFetcherID;
    683     RunUntilIdle();
    684     if (steps < 4) break;
    685 
    686     fetcher = PrepareDMRegisterFetcher();
    687     ASSERT_TRUE(fetcher);
    688     fetcher->delegate()->OnURLFetchComplete(fetcher);
    689     // The policy fetch job has now been scheduled, run it:
    690     RunUntilIdle();
    691     if (steps < 5) break;
    692 
    693     // Verify that there is no profile prepared just before the policy fetch.
    694     EXPECT_FALSE(prepared_profile_);
    695 
    696     fetcher = PrepareDMPolicyFetcher();
    697     ASSERT_TRUE(fetcher);
    698     fetcher->delegate()->OnURLFetchComplete(fetcher);
    699     RunUntilIdle();
    700   } while (0);
    701 
    702   if (steps < 5) {
    703     // Verify that the profile hasn't been created yet.
    704     EXPECT_FALSE(prepared_profile_);
    705 
    706     // Make the current fetcher fail with a Gaia error.
    707     net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(
    708         next_expected_fetcher_id);
    709     ASSERT_TRUE(fetcher);
    710     EXPECT_TRUE(fetcher->delegate());
    711     fetcher->set_url(fetcher->GetOriginalURL());
    712     fetcher->set_response_code(401);
    713     // This response body is important to make the gaia fetcher skip its delayed
    714     // retry behavior, which makes testing harder. If this is sent to the policy
    715     // fetchers then it will make them fail too.
    716     fetcher->SetResponseString(kGaiaAccountDisabledResponse);
    717     fetcher->delegate()->OnURLFetchComplete(fetcher);
    718     RunUntilIdle();
    719   }
    720 
    721   // The profile is finally ready:
    722   EXPECT_TRUE(prepared_profile_);
    723 }
    724 
    725 INSTANTIATE_TEST_CASE_P(
    726     LoginUtilsBlockingLoginTestInstance,
    727     LoginUtilsBlockingLoginTest,
    728     testing::Values(0, 1, 2, 3, 4, 5));
    729 
    730 }  // namespace
    731 
    732 }  // namespace chromeos
    733