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