login_utils_browsertest.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_utils.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/files/scoped_temp_dir.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop/message_loop.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/run_loop.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/string_util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/input_method_configuration.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/authenticator.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/login_status_consumer.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_service.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_test_helper.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/mock_owner_key_util.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/io_thread.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/net/predictor.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/browser_policy_connector.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/cloud/device_management_service.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/policy_service.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/rlz/rlz.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#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/system_salt_getter.h" 47#include "chromeos/dbus/fake_dbus_thread_manager.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 "chromeos/system/mock_statistics_provider.h" 53#include "chromeos/system/statistics_provider.h" 54#include "content/public/browser/browser_thread.h" 55#include "content/public/test/test_browser_thread.h" 56#include "content/public/test/test_utils.h" 57#include "google_apis/gaia/gaia_auth_consumer.h" 58#include "google_apis/gaia/gaia_urls.h" 59#include "net/url_request/test_url_fetcher_factory.h" 60#include "net/url_request/url_fetcher_delegate.h" 61#include "net/url_request/url_request.h" 62#include "net/url_request/url_request_context_getter.h" 63#include "net/url_request/url_request_status.h" 64#include "net/url_request/url_request_test_util.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 kDomain[] = "domain.com"; 88const char kUsername[] = "user@domain.com"; 89const char kDeviceId[] = "100200300"; 90const char kUsernameOtherDomain[] = "user@other.com"; 91 92const char kOAuthTokenCookie[] = "oauth_token=1234"; 93 94const char kGaiaAccountDisabledResponse[] = "Error=AccountDeleted"; 95 96const char kOAuth2TokenPairData[] = 97 "{" 98 " \"refresh_token\": \"1234\"," 99 " \"access_token\": \"5678\"," 100 " \"expires_in\": 3600" 101 "}"; 102 103const char kOAuth2AccessTokenData[] = 104 "{" 105 " \"access_token\": \"5678\"," 106 " \"expires_in\": 3600" 107 "}"; 108 109const char kDMServer[] = "http://server/device_management"; 110const char kDMRegisterRequest[] = 111 "http://server/device_management?request=register"; 112const char kDMPolicyRequest[] = 113 "http://server/device_management?request=policy"; 114 115const char kDMToken[] = "1234"; 116 117// Used to mark |flag|, indicating that RefreshPolicies() has executed its 118// callback. 119void SetFlag(bool* flag) { 120 *flag = true; 121} 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 loop_(base::MessageLoop::TYPE_IO), 157 browser_process_(TestingBrowserProcess::GetGlobal()), 158 local_state_(browser_process_), 159 ui_thread_(BrowserThread::UI, &loop_), 160 db_thread_(BrowserThread::DB, &loop_), 161 file_thread_(BrowserThread::FILE, &loop_), 162 mock_input_method_manager_(NULL), 163 mock_async_method_caller_(NULL), 164 connector_(NULL), 165 prepared_profile_(NULL) {} 166 167 virtual void SetUp() OVERRIDE { 168 // This test is not a full blown InProcessBrowserTest, and doesn't have 169 // all the usual threads running. However a lot of subsystems pulled from 170 // ProfileImpl post to IO (usually from ProfileIOData), and DCHECK that 171 // those tasks were posted. Those tasks in turn depend on a lot of other 172 // components that aren't there during this test, so this kludge is used to 173 // have a running IO loop that doesn't really execute any tasks. 174 // 175 // See InvokeOnIO() below for a way to perform specific tasks on IO, when 176 // that's necessary. 177 178 // A thread is needed to create a new MessageLoop, since there can be only 179 // one loop per thread. 180 fake_io_thread_.StartWithOptions( 181 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 182 base::MessageLoop* fake_io_loop = fake_io_thread_.message_loop(); 183 // Make this loop enter the single task, BlockLoop(). Pass in the completion 184 // event and the work callback. 185 fake_io_thread_.StopSoon(); 186 fake_io_loop->PostTask( 187 FROM_HERE, 188 base::Bind( 189 BlockLoop, 190 &fake_io_thread_completion_, 191 base::Bind(&LoginUtilsTest::DoIOWork, base::Unretained(this)))); 192 // Map BrowserThread::IO to this loop. This allows posting to IO but nothing 193 // will be executed. 194 io_thread_.reset( 195 new content::TestBrowserThread(BrowserThread::IO, fake_io_loop)); 196 197 ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); 198 199 CommandLine* command_line = CommandLine::ForCurrentProcess(); 200 command_line->AppendSwitchASCII( 201 ::switches::kDeviceManagementUrl, kDMServer); 202 command_line->AppendSwitchASCII(switches::kLoginProfile, "user"); 203 204 // DBusThreadManager should be initialized before io_thread_state_, as 205 // DBusThreadManager is used from chromeos::ProxyConfigServiceImpl, 206 // which is part of io_thread_state_. 207 DBusThreadManager::InitializeForTesting(&fake_dbus_thread_manager_); 208 209 SystemSaltGetter::Initialize(); 210 LoginState::Initialize(); 211 212 EXPECT_CALL(mock_statistics_provider_, GetMachineStatistic(_, _)) 213 .WillRepeatedly(Return(false)); 214 chromeos::system::StatisticsProvider::SetTestProvider( 215 &mock_statistics_provider_); 216 217 mock_input_method_manager_ = new input_method::MockInputMethodManager(); 218 input_method::InitializeForTesting(mock_input_method_manager_); 219 disks::DiskMountManager::InitializeForTesting(&mock_disk_mount_manager_); 220 mock_disk_mount_manager_.SetupDefaultReplies(); 221 222 mock_async_method_caller_ = new cryptohome::MockAsyncMethodCaller; 223 cryptohome::AsyncMethodCaller::InitializeForTesting( 224 mock_async_method_caller_); 225 226 test_device_settings_service_.reset(new ScopedTestDeviceSettingsService); 227 test_cros_settings_.reset(new ScopedTestCrosSettings); 228 test_user_manager_.reset(new ScopedTestUserManager); 229 230 // IOThread creates ProxyConfigServiceImpl and 231 // BrowserPolicyConnector::Init() creates a NetworkConfigurationUpdater, 232 // which both access NetworkHandler. Thus initialize it here before creating 233 // IOThread and before calling BrowserPolicyConnector::Init(). 234 NetworkHandler::Initialize(); 235 236 browser_process_->SetProfileManager( 237 new ProfileManagerWithoutInit(scoped_temp_dir_.path())); 238 browser_process_->SetSystemRequestContext( 239 new net::TestURLRequestContextGetter( 240 base::MessageLoopProxy::current())); 241 connector_ = browser_process_->browser_policy_connector(); 242 connector_->Init(local_state_.Get(), 243 browser_process_->system_request_context()); 244 245 io_thread_state_.reset(new IOThread(local_state_.Get(), 246 browser_process_->policy_service(), 247 NULL, NULL)); 248 browser_process_->SetIOThread(io_thread_state_.get()); 249 250#if defined(ENABLE_RLZ) 251 rlz_initialized_cb_ = base::Bind(&base::DoNothing); 252 rlz_lib::testing::SetRlzStoreDirectory(scoped_temp_dir_.path()); 253 RLZTracker::EnableZeroDelayForTesting(); 254#endif 255 256 RunUntilIdle(); 257 } 258 259 virtual void TearDown() OVERRIDE { 260 cryptohome::AsyncMethodCaller::Shutdown(); 261 mock_async_method_caller_ = NULL; 262 263 test_user_manager_.reset(); 264 265 InvokeOnIO( 266 base::Bind(&LoginUtilsTest::TearDownOnIO, base::Unretained(this))); 267 268 // LoginUtils instance must not outlive Profile instances. 269 LoginUtils::Set(NULL); 270 271 input_method::Shutdown(); 272 LoginState::Shutdown(); 273 SystemSaltGetter::Shutdown(); 274 275 // These trigger some tasks that have to run while BrowserThread::UI 276 // exists. Delete all the profiles before deleting the connector. 277 browser_process_->SetProfileManager(NULL); 278 connector_ = NULL; 279 browser_process_->SetBrowserPolicyConnector(NULL); 280 QuitIOLoop(); 281 RunUntilIdle(); 282 } 283 284 void TearDownOnIO() { 285 // chrome_browser_net::Predictor usually skips its shutdown routines on 286 // unit_tests, but does the full thing when 287 // g_browser_process->profile_manager() is valid during initialization. 288 // That includes a WaitableEvent on UI waiting for a task on IO, so that 289 // task must execute. Do it directly from here now. 290 std::vector<Profile*> profiles = 291 browser_process_->profile_manager()->GetLoadedProfiles(); 292 for (size_t i = 0; i < profiles.size(); ++i) { 293 chrome_browser_net::Predictor* predictor = 294 profiles[i]->GetNetworkPredictor(); 295 if (predictor) { 296 predictor->EnablePredictorOnIOThread(false); 297 predictor->Shutdown(); 298 } 299 } 300 } 301 302 void RunUntilIdle() { 303 loop_.RunUntilIdle(); 304 BrowserThread::GetBlockingPool()->FlushForTesting(); 305 loop_.RunUntilIdle(); 306 } 307 308 // Invokes |task| on the IO loop and returns after it has executed. 309 void InvokeOnIO(const base::Closure& task) { 310 fake_io_thread_work_ = task; 311 fake_io_thread_completion_.Signal(); 312 content::RunMessageLoop(); 313 } 314 315 // Makes the fake IO loop return. 316 void QuitIOLoop() { 317 fake_io_thread_completion_.Signal(); 318 content::RunMessageLoop(); 319 } 320 321 // Helper for BlockLoop, InvokeOnIO and QuitIOLoop. 322 bool DoIOWork() { 323 bool has_work = !fake_io_thread_work_.is_null(); 324 if (has_work) 325 fake_io_thread_work_.Run(); 326 fake_io_thread_work_.Reset(); 327 BrowserThread::PostTask( 328 BrowserThread::UI, FROM_HERE, 329 base::MessageLoop::QuitWhenIdleClosure()); 330 // If there was work then keep waiting for more work. 331 // If there was no work then quit the fake IO loop. 332 return has_work; 333 } 334 335 virtual void OnProfilePrepared(Profile* profile) OVERRIDE { 336 EXPECT_FALSE(prepared_profile_); 337 prepared_profile_ = profile; 338 } 339 340#if defined(ENABLE_RLZ) 341 virtual void OnRlzInitialized(Profile* profile) OVERRIDE { 342 rlz_initialized_cb_.Run(); 343 } 344#endif 345 346 virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE { 347 FAIL() << "OnLoginFailure not expected"; 348 } 349 350 virtual void OnLoginSuccess(const UserContext& user_context) OVERRIDE { 351 FAIL() << "OnLoginSuccess not expected"; 352 } 353 354 void EnrollDevice(const std::string& username) { 355 base::RunLoop loop; 356 policy::EnterpriseInstallAttributes::LockResult result; 357 connector_->GetInstallAttributes()->LockDevice( 358 username, policy::DEVICE_MODE_ENTERPRISE, kDeviceId, 359 base::Bind(&CopyLockResult, &loop, &result)); 360 loop.Run(); 361 EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS, result); 362 RunUntilIdle(); 363 } 364 365 void PrepareProfile(const std::string& username) { 366 // Normally this would happen during browser startup, but for tests 367 // we need to trigger creation of Profile-related services. 368 ChromeBrowserMainExtraPartsProfiles:: 369 EnsureBrowserContextKeyedServiceFactoriesBuilt(); 370 ProfileManager::AllowGetDefaultProfile(); 371 372 DeviceSettingsTestHelper device_settings_test_helper; 373 DeviceSettingsService::Get()->SetSessionManager( 374 &device_settings_test_helper, new MockOwnerKeyUtil()); 375 376 EXPECT_CALL(*mock_async_method_caller_, AsyncMount(_, _, _, _)) 377 .WillRepeatedly(Return()); 378 EXPECT_CALL(*mock_async_method_caller_, AsyncGetSanitizedUsername(_, _)) 379 .WillRepeatedly(Return()); 380 381 scoped_refptr<Authenticator> authenticator = 382 LoginUtils::Get()->CreateAuthenticator(this); 383 authenticator->CompleteLogin(ProfileManager::GetDefaultProfile(), 384 UserContext(username, 385 "password", 386 std::string(), 387 username)); // username_hash 388 389 const bool kUsingOAuth = true; 390 // Setting |kHasCookies| to false prevents ProfileAuthData::Transfer from 391 // waiting for an IO task before proceeding. 392 const bool kHasCookies = false; 393 const bool kHasActiveSession = false; 394 LoginUtils::Get()->PrepareProfile( 395 UserContext(username, "password", std::string(), username, kUsingOAuth), 396 std::string(), kHasCookies, kHasActiveSession, this); 397 device_settings_test_helper.Flush(); 398 RunUntilIdle(); 399 400 DeviceSettingsService::Get()->UnsetSessionManager(); 401 } 402 403 net::TestURLFetcher* PrepareOAuthFetcher(const GURL& expected_url) { 404 net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0); 405 EXPECT_TRUE(fetcher); 406 if (!fetcher) 407 return NULL; 408 EXPECT_TRUE(fetcher->delegate()); 409 EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(), 410 expected_url.spec(), 411 true)); 412 fetcher->set_url(fetcher->GetOriginalURL()); 413 fetcher->set_response_code(200); 414 fetcher->set_status(net::URLRequestStatus()); 415 return fetcher; 416 } 417 418 net::TestURLFetcher* PrepareDMServiceFetcher( 419 const std::string& expected_url, 420 const em::DeviceManagementResponse& response) { 421 net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID( 422 policy::DeviceManagementService::kURLFetcherID); 423 EXPECT_TRUE(fetcher); 424 if (!fetcher) 425 return NULL; 426 EXPECT_TRUE(fetcher->delegate()); 427 EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(), 428 expected_url, 429 true)); 430 fetcher->set_url(fetcher->GetOriginalURL()); 431 fetcher->set_response_code(200); 432 fetcher->set_status(net::URLRequestStatus()); 433 std::string data; 434 EXPECT_TRUE(response.SerializeToString(&data)); 435 fetcher->SetResponseString(data); 436 return fetcher; 437 } 438 439 net::TestURLFetcher* PrepareDMRegisterFetcher() { 440 em::DeviceManagementResponse response; 441 em::DeviceRegisterResponse* register_response = 442 response.mutable_register_response(); 443 register_response->set_device_management_token(kDMToken); 444 register_response->set_enrollment_type( 445 em::DeviceRegisterResponse::ENTERPRISE); 446 return PrepareDMServiceFetcher(kDMRegisterRequest, response); 447 } 448 449 net::TestURLFetcher* PrepareDMPolicyFetcher() { 450 em::DeviceManagementResponse response; 451 response.mutable_policy_response()->add_response(); 452 return PrepareDMServiceFetcher(kDMPolicyRequest, response); 453 } 454 455 protected: 456 base::Closure fake_io_thread_work_; 457 base::WaitableEvent fake_io_thread_completion_; 458 base::Thread fake_io_thread_; 459 460 base::MessageLoop loop_; 461 TestingBrowserProcess* browser_process_; 462 ScopedTestingLocalState local_state_; 463 464 content::TestBrowserThread ui_thread_; 465 content::TestBrowserThread db_thread_; 466 content::TestBrowserThread file_thread_; 467 scoped_ptr<content::TestBrowserThread> io_thread_; 468 scoped_ptr<IOThread> io_thread_state_; 469 470 FakeDBusThreadManager fake_dbus_thread_manager_; 471 input_method::MockInputMethodManager* mock_input_method_manager_; 472 disks::MockDiskMountManager mock_disk_mount_manager_; 473 net::TestURLFetcherFactory test_url_fetcher_factory_; 474 475 cryptohome::MockAsyncMethodCaller* mock_async_method_caller_; 476 477 chromeos::system::MockStatisticsProvider mock_statistics_provider_; 478 479 policy::BrowserPolicyConnector* connector_; 480 481 // Initialized after |fake_dbus_thread_manager_| is set up. 482 scoped_ptr<ScopedTestDeviceSettingsService> test_device_settings_service_; 483 scoped_ptr<ScopedTestCrosSettings> test_cros_settings_; 484 scoped_ptr<ScopedTestUserManager> test_user_manager_; 485 486 Profile* prepared_profile_; 487 488 base::Closure rlz_initialized_cb_; 489 490 private: 491 base::ScopedTempDir scoped_temp_dir_; 492 493 std::string device_policy_; 494 std::string user_policy_; 495 496 DISALLOW_COPY_AND_ASSIGN(LoginUtilsTest); 497}; 498 499class LoginUtilsBlockingLoginTest 500 : public LoginUtilsTest, 501 public testing::WithParamInterface<int> {}; 502 503TEST_F(LoginUtilsTest, NormalLoginDoesntBlock) { 504 UserManager* user_manager = UserManager::Get(); 505 EXPECT_FALSE(user_manager->IsUserLoggedIn()); 506 EXPECT_FALSE(connector_->IsEnterpriseManaged()); 507 EXPECT_FALSE(prepared_profile_); 508 EXPECT_EQ(policy::USER_AFFILIATION_NONE, 509 connector_->GetUserAffiliation(kUsername)); 510 511 // The profile will be created without waiting for a policy response. 512 PrepareProfile(kUsername); 513 514 EXPECT_TRUE(prepared_profile_); 515 ASSERT_TRUE(user_manager->IsUserLoggedIn()); 516 EXPECT_EQ(kUsername, user_manager->GetLoggedInUser()->email()); 517} 518 519TEST_F(LoginUtilsTest, EnterpriseLoginDoesntBlockForNormalUser) { 520 UserManager* user_manager = UserManager::Get(); 521 EXPECT_FALSE(user_manager->IsUserLoggedIn()); 522 EXPECT_FALSE(connector_->IsEnterpriseManaged()); 523 EXPECT_FALSE(prepared_profile_); 524 525 // Enroll the device. 526 EnrollDevice(kUsername); 527 528 EXPECT_FALSE(user_manager->IsUserLoggedIn()); 529 EXPECT_TRUE(connector_->IsEnterpriseManaged()); 530 EXPECT_EQ(kDomain, connector_->GetEnterpriseDomain()); 531 EXPECT_FALSE(prepared_profile_); 532 EXPECT_EQ(policy::USER_AFFILIATION_NONE, 533 connector_->GetUserAffiliation(kUsernameOtherDomain)); 534 535 // Login with a non-enterprise user shouldn't block. 536 PrepareProfile(kUsernameOtherDomain); 537 538 EXPECT_TRUE(prepared_profile_); 539 ASSERT_TRUE(user_manager->IsUserLoggedIn()); 540 EXPECT_EQ(kUsernameOtherDomain, user_manager->GetLoggedInUser()->email()); 541} 542 543#if defined(ENABLE_RLZ) 544TEST_F(LoginUtilsTest, RlzInitialized) { 545 // No RLZ brand code set initially. 546 EXPECT_FALSE(local_state_.Get()->HasPrefPath(prefs::kRLZBrand)); 547 548 base::RunLoop wait_for_rlz_init; 549 rlz_initialized_cb_ = wait_for_rlz_init.QuitClosure(); 550 551 PrepareProfile(kUsername); 552 553 wait_for_rlz_init.Run(); 554 // Wait for blocking RLZ tasks to complete. 555 RunUntilIdle(); 556 557 // RLZ brand code has been set to empty string. 558 EXPECT_TRUE(local_state_.Get()->HasPrefPath(prefs::kRLZBrand)); 559 EXPECT_EQ(std::string(), local_state_.Get()->GetString(prefs::kRLZBrand)); 560 561 // RLZ value for homepage access point should have been initialized. 562 string16 rlz_string; 563 EXPECT_TRUE(RLZTracker::GetAccessPointRlz( 564 RLZTracker::CHROME_HOME_PAGE, &rlz_string)); 565 EXPECT_EQ(string16(), rlz_string); 566} 567#endif 568 569TEST_P(LoginUtilsBlockingLoginTest, EnterpriseLoginBlocksForEnterpriseUser) { 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_MANAGED, 583 connector_->GetUserAffiliation(kUsername)); 584 EXPECT_FALSE(user_manager->IsKnownUser(kUsername)); 585 586 // Login with a user of the enterprise domain waits for policy. 587 PrepareProfile(kUsername); 588 589 EXPECT_FALSE(prepared_profile_); 590 ASSERT_TRUE(user_manager->IsUserLoggedIn()); 591 EXPECT_TRUE(user_manager->IsCurrentUserNew()); 592 593 GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); 594 net::TestURLFetcher* fetcher; 595 596 // |steps| is the test parameter, and is the number of successful fetches. 597 // The first incomplete fetch will fail. In any case, the profile creation 598 // should resume. 599 int steps = GetParam(); 600 601 // The next expected fetcher ID. This is used to make it fail. 602 int next_expected_fetcher_id = 0; 603 604 do { 605 if (steps < 1) break; 606 607 // Fake refresh token retrieval: 608 fetcher = PrepareOAuthFetcher(gaia_urls->client_login_to_oauth2_url()); 609 ASSERT_TRUE(fetcher); 610 net::ResponseCookies cookies; 611 cookies.push_back(kOAuthTokenCookie); 612 fetcher->set_cookies(cookies); 613 fetcher->delegate()->OnURLFetchComplete(fetcher); 614 if (steps < 2) break; 615 616 // Fake OAuth2 token pair retrieval: 617 fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url()); 618 ASSERT_TRUE(fetcher); 619 fetcher->SetResponseString(kOAuth2TokenPairData); 620 fetcher->delegate()->OnURLFetchComplete(fetcher); 621 if (steps < 3) break; 622 623 // Fake OAuth2 access token retrieval: 624 fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url()); 625 ASSERT_TRUE(fetcher); 626 fetcher->SetResponseString(kOAuth2AccessTokenData); 627 fetcher->delegate()->OnURLFetchComplete(fetcher); 628 629 // The cloud policy subsystem is now ready to fetch the dmtoken and the user 630 // policy. 631 next_expected_fetcher_id = policy::DeviceManagementService::kURLFetcherID; 632 RunUntilIdle(); 633 if (steps < 4) break; 634 635 fetcher = PrepareDMRegisterFetcher(); 636 ASSERT_TRUE(fetcher); 637 fetcher->delegate()->OnURLFetchComplete(fetcher); 638 // The policy fetch job has now been scheduled, run it: 639 RunUntilIdle(); 640 if (steps < 5) break; 641 642 // Verify that there is no profile prepared just before the policy fetch. 643 EXPECT_FALSE(prepared_profile_); 644 645 fetcher = PrepareDMPolicyFetcher(); 646 ASSERT_TRUE(fetcher); 647 fetcher->delegate()->OnURLFetchComplete(fetcher); 648 RunUntilIdle(); 649 } while (0); 650 651 if (steps < 5) { 652 // Verify that the profile hasn't been created yet. 653 EXPECT_FALSE(prepared_profile_); 654 655 // Make the current fetcher fail with a Gaia error. 656 net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID( 657 next_expected_fetcher_id); 658 ASSERT_TRUE(fetcher); 659 EXPECT_TRUE(fetcher->delegate()); 660 fetcher->set_url(fetcher->GetOriginalURL()); 661 fetcher->set_response_code(401); 662 // This response body is important to make the gaia fetcher skip its delayed 663 // retry behavior, which makes testing harder. If this is sent to the policy 664 // fetchers then it will make them fail too. 665 fetcher->SetResponseString(kGaiaAccountDisabledResponse); 666 fetcher->delegate()->OnURLFetchComplete(fetcher); 667 RunUntilIdle(); 668 } 669 670 // The profile is finally ready: 671 EXPECT_TRUE(prepared_profile_); 672} 673 674INSTANTIATE_TEST_CASE_P( 675 LoginUtilsBlockingLoginTestInstance, 676 LoginUtilsBlockingLoginTest, 677 testing::Values(0, 1, 2, 3, 4, 5)); 678 679} // namespace 680 681} // namespace chromeos 682