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