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 80 using ::testing::AnyNumber; 81 82 namespace chromeos { 83 84 namespace { 85 86 namespace em = enterprise_management; 87 88 using ::testing::DoAll; 89 using ::testing::Return; 90 using ::testing::SaveArg; 91 using ::testing::SetArgPointee; 92 using ::testing::_; 93 using content::BrowserThread; 94 95 const char kDomain[] = "domain.com"; 96 const char kUsername[] = "user (at) domain.com"; 97 const char kDeviceId[] = "100200300"; 98 const char kUsernameOtherDomain[] = "user (at) other.com"; 99 100 const char kOAuthTokenCookie[] = "oauth_token=1234"; 101 102 const char kGaiaAccountDisabledResponse[] = "Error=AccountDeleted"; 103 104 const char kOAuth2TokenPairData[] = 105 "{" 106 " \"refresh_token\": \"1234\"," 107 " \"access_token\": \"5678\"," 108 " \"expires_in\": 3600" 109 "}"; 110 111 const char kOAuth2AccessTokenData[] = 112 "{" 113 " \"access_token\": \"5678\"," 114 " \"expires_in\": 3600" 115 "}"; 116 117 const char kDMServer[] = "http://server/device_management"; 118 const char kDMRegisterRequest[] = 119 "http://server/device_management?request=register"; 120 const char kDMPolicyRequest[] = 121 "http://server/device_management?request=policy"; 122 123 const 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. 129 void BlockLoop(base::WaitableEvent* completion, base::Callback<bool()> work) { 130 do { 131 completion->Wait(); 132 } while (work.Run()); 133 base::MessageLoop::current()->QuitNow(); 134 } 135 136 void CopyLockResult(base::RunLoop* loop, 137 policy::EnterpriseInstallAttributes::LockResult* out, 138 policy::EnterpriseInstallAttributes::LockResult result) { 139 *out = result; 140 loop->Quit(); 141 } 142 143 class 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 524 class LoginUtilsBlockingLoginTest 525 : public LoginUtilsTest, 526 public testing::WithParamInterface<int> {}; 527 528 TEST_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 544 TEST_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) 569 TEST_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 594 TEST_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 699 INSTANTIATE_TEST_CASE_P( 700 LoginUtilsBlockingLoginTestInstance, 701 LoginUtilsBlockingLoginTest, 702 testing::Values(0, 1, 2, 3, 4, 5)); 703 704 } // namespace 705 706 } // namespace chromeos 707