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