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