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