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