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