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