device_local_account_browsertest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1// Copyright (c) 2013 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 <map> 6#include <string> 7 8#include "base/basictypes.h" 9#include "base/bind.h" 10#include "base/callback.h" 11#include "base/command_line.h" 12#include "base/file_util.h" 13#include "base/files/file_path.h" 14#include "base/files/scoped_temp_dir.h" 15#include "base/message_loop.h" 16#include "base/path_service.h" 17#include "base/run_loop.h" 18#include "base/stl_util.h" 19#include "base/string_util.h" 20#include "base/utf_string_conversions.h" 21#include "chrome/browser/browser_process.h" 22#include "chrome/browser/chromeos/login/existing_user_controller.h" 23#include "chrome/browser/chromeos/login/user.h" 24#include "chrome/browser/chromeos/login/user_manager.h" 25#include "chrome/browser/chromeos/login/wizard_controller.h" 26#include "chrome/browser/chromeos/policy/device_policy_builder.h" 27#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 28#include "chrome/browser/lifetime/application_lifetime.h" 29#include "chrome/browser/policy/cloud/cloud_policy_constants.h" 30#include "chrome/browser/policy/cloud/policy_builder.h" 31#include "chrome/browser/policy/policy_service.h" 32#include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" 33#include "chrome/browser/policy/proto/chromeos/install_attributes.pb.h" 34#include "chrome/browser/policy/test/local_policy_test_server.h" 35#include "chrome/browser/prefs/session_startup_pref.h" 36#include "chrome/browser/ui/browser.h" 37#include "chrome/browser/ui/browser_finder.h" 38#include "chrome/browser/ui/host_desktop.h" 39#include "chrome/browser/ui/tabs/tab_strip_model.h" 40#include "chrome/common/chrome_notification_types.h" 41#include "chrome/common/chrome_switches.h" 42#include "chrome/test/base/in_process_browser_test.h" 43#include "chromeos/chromeos_paths.h" 44#include "chromeos/chromeos_switches.h" 45#include "chromeos/dbus/cryptohome_client.h" 46#include "chromeos/dbus/dbus_method_call_status.h" 47#include "chromeos/dbus/dbus_thread_manager.h" 48#include "chromeos/dbus/mock_dbus_thread_manager.h" 49#include "chromeos/dbus/mock_update_engine_client.h" 50#include "chromeos/dbus/session_manager_client.h" 51#include "content/public/browser/notification_observer.h" 52#include "content/public/browser/notification_registrar.h" 53#include "content/public/browser/notification_service.h" 54#include "content/public/browser/web_contents.h" 55#include "testing/gmock/include/gmock/gmock.h" 56#include "third_party/cros_system_api/dbus/service_constants.h" 57 58namespace em = enterprise_management; 59 60using testing::Return; 61 62namespace policy { 63 64namespace { 65 66const char kAccountId1[] = "dla1@example.com"; 67const char kAccountId2[] = "dla2@example.com"; 68const char kDisplayName1[] = "display name for account 1"; 69const char kDisplayName2[] = "display name for account 2"; 70const char* kStartupURLs[] = { 71 "chrome://policy", 72 "chrome://about", 73}; 74 75// Observes a specific notification type and quits the message loop once a 76// condition holds. 77class NotificationWatcher : public content::NotificationObserver { 78 public: 79 // Callback invoked on notifications. Should return true when the condition 80 // that the caller is waiting for is satisfied. 81 typedef base::Callback<bool(void)> ConditionTestCallback; 82 83 explicit NotificationWatcher(int notification_type, 84 const ConditionTestCallback& callback) 85 : type_(notification_type), 86 callback_(callback) {} 87 88 void Run() { 89 if (callback_.Run()) 90 return; 91 92 content::NotificationRegistrar registrar; 93 registrar.Add(this, type_, content::NotificationService::AllSources()); 94 run_loop_.Run(); 95 } 96 97 // content::NotificationObserver: 98 virtual void Observe(int type, 99 const content::NotificationSource& source, 100 const content::NotificationDetails& details) OVERRIDE { 101 if (callback_.Run()) 102 run_loop_.Quit(); 103 } 104 105 private: 106 int type_; 107 ConditionTestCallback callback_; 108 base::RunLoop run_loop_; 109 110 DISALLOW_COPY_AND_ASSIGN(NotificationWatcher); 111}; 112 113// A fake implementation of session_manager. Accepts policy blobs to be set and 114// returns them unmodified. 115class FakeSessionManagerClient : public chromeos::SessionManagerClient { 116 public: 117 FakeSessionManagerClient() {} 118 virtual ~FakeSessionManagerClient() {} 119 120 // SessionManagerClient: 121 virtual void AddObserver(Observer* observer) OVERRIDE {} 122 virtual void RemoveObserver(Observer* observer) OVERRIDE {} 123 virtual bool HasObserver(Observer* observer) OVERRIDE { return false; } 124 virtual void EmitLoginPromptReady() OVERRIDE {} 125 virtual void EmitLoginPromptVisible() OVERRIDE {} 126 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {} 127 virtual void RestartEntd() OVERRIDE {} 128 virtual void StartSession(const std::string& user_email) OVERRIDE {} 129 virtual void StopSession() OVERRIDE {} 130 virtual void StartDeviceWipe() OVERRIDE {} 131 virtual void RequestLockScreen() OVERRIDE {} 132 virtual void NotifyLockScreenShown() OVERRIDE {} 133 virtual void RequestUnlockScreen() OVERRIDE {} 134 virtual void NotifyLockScreenDismissed() OVERRIDE {} 135 virtual void RetrieveDevicePolicy( 136 const RetrievePolicyCallback& callback) OVERRIDE { 137 MessageLoop::current()->PostTask(FROM_HERE, 138 base::Bind(callback, device_policy_)); 139 } 140 virtual void RetrieveUserPolicy( 141 const RetrievePolicyCallback& callback) OVERRIDE { 142 MessageLoop::current()->PostTask(FROM_HERE, 143 base::Bind(callback, user_policy_)); 144 } 145 virtual void RetrieveDeviceLocalAccountPolicy( 146 const std::string& account_id, 147 const RetrievePolicyCallback& callback) OVERRIDE { 148 MessageLoop::current()->PostTask( 149 FROM_HERE, 150 base::Bind(callback, device_local_account_policy_[account_id])); 151 } 152 virtual void StoreDevicePolicy(const std::string& policy_blob, 153 const StorePolicyCallback& callback) OVERRIDE { 154 device_policy_ = policy_blob; 155 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); 156 } 157 virtual void StoreUserPolicy(const std::string& policy_blob, 158 const StorePolicyCallback& callback) OVERRIDE { 159 user_policy_ = policy_blob; 160 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); 161 } 162 virtual void StoreDeviceLocalAccountPolicy( 163 const std::string& account_id, 164 const std::string& policy_blob, 165 const StorePolicyCallback& callback) OVERRIDE { 166 device_local_account_policy_[account_id] = policy_blob; 167 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); 168 } 169 170 const std::string& device_policy() const { 171 return device_policy_; 172 } 173 void set_device_policy(const std::string& policy_blob) { 174 device_policy_ = policy_blob; 175 } 176 177 const std::string& user_policy() const { 178 return user_policy_; 179 } 180 void set_user_policy(const std::string& policy_blob) { 181 user_policy_ = policy_blob; 182 } 183 184 const std::string& device_local_account_policy( 185 const std::string& account_id) const { 186 std::map<std::string, std::string>::const_iterator entry = 187 device_local_account_policy_.find(account_id); 188 return entry != device_local_account_policy_.end() ? entry->second 189 : EmptyString(); 190 } 191 void set_device_local_account_policy(const std::string& account_id, 192 const std::string& policy_blob) { 193 device_local_account_policy_[account_id] = policy_blob; 194 } 195 196 private: 197 std::string device_policy_; 198 std::string user_policy_; 199 std::map<std::string, std::string> device_local_account_policy_; 200 201 DISALLOW_COPY_AND_ASSIGN(FakeSessionManagerClient); 202}; 203 204class FakeCryptohomeClient : public chromeos::CryptohomeClient { 205 public: 206 using chromeos::CryptohomeClient::AsyncMethodCallback; 207 using chromeos::CryptohomeClient::AsyncCallStatusHandler; 208 using chromeos::CryptohomeClient::AsyncCallStatusWithDataHandler; 209 210 FakeCryptohomeClient() {} 211 virtual ~FakeCryptohomeClient() {} 212 213 virtual void SetAsyncCallStatusHandlers( 214 const AsyncCallStatusHandler& handler, 215 const AsyncCallStatusWithDataHandler& data_handler) OVERRIDE { 216 handler_ = handler; 217 data_handler_ = data_handler; 218 } 219 virtual void ResetAsyncCallStatusHandlers() OVERRIDE { 220 handler_.Reset(); 221 data_handler_.Reset(); 222 } 223 virtual void IsMounted( 224 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 225 virtual bool Unmount(bool* success) OVERRIDE { 226 *success = true; 227 return true; 228 } 229 virtual void AsyncCheckKey(const std::string& username, 230 const std::string& key, 231 const AsyncMethodCallback& callback) OVERRIDE {} 232 virtual void AsyncMigrateKey(const std::string& username, 233 const std::string& from_key, 234 const std::string& to_key, 235 const AsyncMethodCallback& callback) OVERRIDE {} 236 virtual void AsyncRemove(const std::string& username, 237 const AsyncMethodCallback& callback) OVERRIDE {} 238 virtual bool GetSystemSalt(std::vector<uint8>* salt) OVERRIDE { 239 const char kFakeSystemSalt[] = "fake_system_salt"; 240 salt->assign(kFakeSystemSalt, 241 kFakeSystemSalt + arraysize(kFakeSystemSalt) - 1); 242 return true; 243 } 244 virtual void GetSanitizedUsername( 245 const std::string& username, 246 const chromeos::StringDBusMethodCallback& callback) OVERRIDE { 247 MessageLoop::current()->PostTask( 248 FROM_HERE, 249 base::Bind(callback, 250 chromeos::DBUS_METHOD_CALL_SUCCESS, 251 username)); 252 MessageLoop::current()->PostTask( 253 FROM_HERE, base::Bind(data_handler_, 1, true, username)); 254 } 255 virtual void AsyncMount(const std::string& username, 256 const std::string& key, 257 int flags, 258 const AsyncMethodCallback& callback) OVERRIDE { 259 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, 1)); 260 MessageLoop::current()->PostTask( 261 FROM_HERE, base::Bind(handler_, 1, true, cryptohome::MOUNT_ERROR_NONE)); 262 } 263 virtual void AsyncMountGuest(const AsyncMethodCallback& callback) OVERRIDE {} 264 virtual void TpmIsReady( 265 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 266 virtual void TpmIsEnabled( 267 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 268 virtual bool CallTpmIsEnabledAndBlock(bool* enabled) OVERRIDE { 269 return false; 270 } 271 virtual void TpmGetPassword( 272 const chromeos::StringDBusMethodCallback& callback) OVERRIDE {} 273 virtual void TpmIsOwned( 274 const chromeos::BoolDBusMethodCallback& kallback) OVERRIDE {} 275 virtual bool CallTpmIsOwnedAndBlock(bool* owned) OVERRIDE { 276 return false; 277 } 278 virtual void TpmIsBeingOwned( 279 const chromeos::BoolDBusMethodCallback& kallback) OVERRIDE {} 280 virtual bool CallTpmIsBeingOwnedAndBlock(bool* owning) OVERRIDE { 281 return false; 282 } 283 virtual void TpmCanAttemptOwnership( 284 const chromeos::VoidDBusMethodCallback& callback) OVERRIDE {} 285 virtual bool CallTpmClearStoredPasswordAndBlock() OVERRIDE { 286 return false; 287 } 288 virtual void TpmClearStoredPassword( 289 const chromeos::VoidDBusMethodCallback& kallback) OVERRIDE {} 290 virtual void Pkcs11IsTpmTokenReady( 291 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 292 virtual void Pkcs11GetTpmTokenInfo( 293 const Pkcs11GetTpmTokenInfoCallback& callback) OVERRIDE {} 294 virtual bool InstallAttributesGet(const std::string& name, 295 std::vector<uint8>* value, 296 bool* successful) OVERRIDE { 297 return false; 298 } 299 virtual bool InstallAttributesSet(const std::string& name, 300 const std::vector<uint8>& value, 301 bool* successful) OVERRIDE { 302 return false; 303 } 304 virtual bool InstallAttributesFinalize(bool* successful) OVERRIDE { 305 return false; 306 } 307 virtual void InstallAttributesIsReady( 308 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 309 virtual bool InstallAttributesIsInvalid(bool* is_invalid) OVERRIDE { 310 return true; 311 } 312 virtual bool InstallAttributesIsFirstInstall( 313 bool* is_first_install) OVERRIDE { 314 return false; 315 } 316 virtual void TpmAttestationIsPrepared( 317 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 318 virtual void TpmAttestationIsEnrolled( 319 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 320 virtual void AsyncTpmAttestationCreateEnrollRequest( 321 const AsyncMethodCallback& callback) OVERRIDE {} 322 virtual void AsyncTpmAttestationEnroll( 323 const std::string& pca_response, 324 const AsyncMethodCallback& callback) OVERRIDE {} 325 virtual void AsyncTpmAttestationCreateCertRequest( 326 int options, 327 const AsyncMethodCallback& callback) OVERRIDE {} 328 virtual void AsyncTpmAttestationFinishCertRequest( 329 const std::string& pca_response, 330 chromeos::attestation::AttestationKeyType key_type, 331 const std::string& key_name, 332 const AsyncMethodCallback& callback) OVERRIDE {} 333 virtual void TpmAttestationDoesKeyExist( 334 chromeos::attestation::AttestationKeyType key_type, 335 const std::string& key_name, 336 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 337 virtual void TpmAttestationGetCertificate( 338 chromeos::attestation::AttestationKeyType key_type, 339 const std::string& key_name, 340 const DataMethodCallback& callback) OVERRIDE {} 341 virtual void TpmAttestationGetPublicKey( 342 chromeos::attestation::AttestationKeyType key_type, 343 const std::string& key_name, 344 const DataMethodCallback& callback) OVERRIDE {} 345 virtual void TpmAttestationRegisterKey( 346 chromeos::attestation::AttestationKeyType key_type, 347 const std::string& key_name, 348 const AsyncMethodCallback& callback) OVERRIDE {} 349 virtual void TpmAttestationSignEnterpriseChallenge( 350 chromeos::attestation::AttestationKeyType key_type, 351 const std::string& key_name, 352 const std::string& domain, 353 const std::string& device_id, 354 chromeos::attestation::AttestationChallengeOptions options, 355 const std::string& challenge, 356 const AsyncMethodCallback& callback) OVERRIDE {} 357 virtual void TpmAttestationSignSimpleChallenge( 358 chromeos::attestation::AttestationKeyType key_type, 359 const std::string& key_name, 360 const std::string& challenge, 361 const AsyncMethodCallback& callback) OVERRIDE {} 362 virtual void TpmAttestationGetKeyPayload( 363 chromeos::attestation::AttestationKeyType key_type, 364 const std::string& key_name, 365 const DataMethodCallback& callback) OVERRIDE {} 366 virtual void TpmAttestationSetKeyPayload( 367 chromeos::attestation::AttestationKeyType key_type, 368 const std::string& key_name, 369 const std::string& payload, 370 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 371 372 private: 373 AsyncCallStatusHandler handler_; 374 AsyncCallStatusWithDataHandler data_handler_; 375 376 DISALLOW_COPY_AND_ASSIGN(FakeCryptohomeClient); 377}; 378 379} // namespace 380 381class DeviceLocalAccountTest : public InProcessBrowserTest { 382 protected: 383 DeviceLocalAccountTest() {} 384 virtual ~DeviceLocalAccountTest() {} 385 386 virtual void SetUp() OVERRIDE { 387 // Configure and start the test server. 388 scoped_ptr<crypto::RSAPrivateKey> signing_key( 389 PolicyBuilder::CreateTestSigningKey()); 390 ASSERT_TRUE(test_server_.SetSigningKey(signing_key.get())); 391 signing_key.reset(); 392 test_server_.RegisterClient(PolicyBuilder::kFakeToken, 393 PolicyBuilder::kFakeDeviceId); 394 ASSERT_TRUE(test_server_.Start()); 395 396 InProcessBrowserTest::SetUp(); 397 } 398 399 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 400 command_line->AppendSwitch(chromeos::switches::kLoginManager); 401 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); 402 command_line->AppendSwitchASCII( 403 chromeos::switches::kLoginScreen, 404 chromeos::WizardController::kLoginScreenName); 405 command_line->AppendSwitchASCII( 406 switches::kDeviceManagementUrl, test_server_.GetServiceURL().spec()); 407 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); 408 } 409 410 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 411 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 412 413 // Clear command-line arguments (but keep command-line switches) so the 414 // startup pages policy takes effect. 415 CommandLine* command_line = CommandLine::ForCurrentProcess(); 416 CommandLine::StringVector argv(command_line->argv()); 417 argv.erase(argv.begin() + argv.size() - command_line->GetArgs().size(), 418 argv.end()); 419 command_line->InitFromArgv(argv); 420 421 // Mark the device enterprise-enrolled. 422 SetUpInstallAttributes(); 423 424 SetUpPolicy(); 425 426 // Redirect session_manager DBus calls to FakeSessionManagerClient. 427 chromeos::MockDBusThreadManager* dbus_thread_manager = 428 new chromeos::MockDBusThreadManager(); 429 EXPECT_CALL(*dbus_thread_manager, GetSessionManagerClient()) 430 .WillRepeatedly(Return(&session_manager_client_)); 431 chromeos::DBusThreadManager::InitializeForTesting(dbus_thread_manager); 432 433 // Mock out cryptohome mount calls to succeed immediately. 434 EXPECT_CALL(*dbus_thread_manager, GetCryptohomeClient()) 435 .WillRepeatedly(Return(&cryptohome_client_)); 436 } 437 438 virtual void CleanUpOnMainThread() OVERRIDE { 439 // This shuts down the login UI. 440 MessageLoop::current()->PostTask(FROM_HERE, 441 base::Bind(&chrome::AttemptExit)); 442 base::RunLoop().RunUntilIdle(); 443 } 444 445 void SetUpInstallAttributes() { 446 cryptohome::SerializedInstallAttributes install_attrs_proto; 447 cryptohome::SerializedInstallAttributes::Attribute* attribute = NULL; 448 449 attribute = install_attrs_proto.add_attributes(); 450 attribute->set_name(EnterpriseInstallAttributes::kAttrEnterpriseOwned); 451 attribute->set_value("true"); 452 453 attribute = install_attrs_proto.add_attributes(); 454 attribute->set_name(EnterpriseInstallAttributes::kAttrEnterpriseUser); 455 attribute->set_value(PolicyBuilder::kFakeUsername); 456 457 base::FilePath install_attrs_file = 458 temp_dir_.path().AppendASCII("install_attributes.pb"); 459 const std::string install_attrs_blob( 460 install_attrs_proto.SerializeAsString()); 461 ASSERT_EQ(static_cast<int>(install_attrs_blob.size()), 462 file_util::WriteFile(install_attrs_file, 463 install_attrs_blob.c_str(), 464 install_attrs_blob.size())); 465 ASSERT_TRUE(PathService::Override(chromeos::FILE_INSTALL_ATTRIBUTES, 466 install_attrs_file)); 467 } 468 469 void SetUpPolicy() { 470 // Configure two device-local accounts in device settings. 471 DevicePolicyBuilder device_policy; 472 device_policy.policy_data().set_public_key_version(1); 473 em::ChromeDeviceSettingsProto& proto(device_policy.payload()); 474 proto.mutable_show_user_names()->set_show_user_names(true); 475 em::DeviceLocalAccountInfoProto* account1 = 476 proto.mutable_device_local_accounts()->add_account(); 477 account1->set_account_id(kAccountId1); 478 account1->set_type( 479 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); 480 em::DeviceLocalAccountInfoProto* account2 = 481 proto.mutable_device_local_accounts()->add_account(); 482 account2->set_account_id(kAccountId2); 483 account2->set_type( 484 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); 485 device_policy.Build(); 486 session_manager_client_.set_device_policy(device_policy.GetBlob()); 487 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, 488 std::string(), proto.SerializeAsString()); 489 490 // Install the owner key. 491 base::FilePath owner_key_file = temp_dir_.path().AppendASCII("owner.key"); 492 std::vector<uint8> owner_key_bits; 493 ASSERT_TRUE(device_policy.signing_key()->ExportPublicKey(&owner_key_bits)); 494 ASSERT_EQ( 495 static_cast<int>(owner_key_bits.size()), 496 file_util::WriteFile( 497 owner_key_file, 498 reinterpret_cast<const char*>(vector_as_array(&owner_key_bits)), 499 owner_key_bits.size())); 500 ASSERT_TRUE( 501 PathService::Override(chromeos::FILE_OWNER_KEY, owner_key_file)); 502 503 // Configure device-local account policy for the first device-local account. 504 UserPolicyBuilder device_local_account_policy; 505 device_local_account_policy.policy_data().set_policy_type( 506 dm_protocol::kChromePublicAccountPolicyType); 507 device_local_account_policy.policy_data().set_username(kAccountId1); 508 device_local_account_policy.policy_data().set_settings_entity_id( 509 kAccountId1); 510 device_local_account_policy.policy_data().set_public_key_version(1); 511 device_local_account_policy.payload().mutable_restoreonstartup()->set_value( 512 SessionStartupPref::kPrefValueURLs); 513 em::StringListPolicyProto* startup_urls_proto = 514 device_local_account_policy.payload().mutable_restoreonstartupurls(); 515 for (size_t i = 0; i < arraysize(kStartupURLs); ++i) 516 startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]); 517 device_local_account_policy.payload().mutable_userdisplayname()->set_value( 518 kDisplayName1); 519 device_local_account_policy.Build(); 520 session_manager_client_.set_device_local_account_policy( 521 kAccountId1, device_local_account_policy.GetBlob()); 522 test_server_.UpdatePolicy( 523 dm_protocol::kChromePublicAccountPolicyType, kAccountId1, 524 device_local_account_policy.payload().SerializeAsString()); 525 526 // Make policy for the second account available from the server. 527 device_local_account_policy.payload().mutable_userdisplayname()->set_value( 528 kDisplayName2); 529 test_server_.UpdatePolicy( 530 dm_protocol::kChromePublicAccountPolicyType, kAccountId2, 531 device_local_account_policy.payload().SerializeAsString()); 532 533 // Don't install policy for |kAccountId2| yet so initial download gets 534 // test coverage. 535 ASSERT_TRUE(session_manager_client_.device_local_account_policy( 536 kAccountId2).empty()); 537 } 538 539 void CheckPublicSessionPresent(const std::string& id) { 540 const chromeos::User* user = chromeos::UserManager::Get()->FindUser(id); 541 ASSERT_TRUE(user); 542 EXPECT_EQ(id, user->email()); 543 EXPECT_EQ(chromeos::User::USER_TYPE_PUBLIC_ACCOUNT, user->GetType()); 544 } 545 546 LocalPolicyTestServer test_server_; 547 base::ScopedTempDir temp_dir_; 548 549 FakeSessionManagerClient session_manager_client_; 550 FakeCryptohomeClient cryptohome_client_; 551}; 552 553static bool IsKnownUser(const std::string& account_id) { 554 return chromeos::UserManager::Get()->IsKnownUser(account_id); 555} 556 557IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) { 558 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 559 base::Bind(&IsKnownUser, kAccountId1)).Run(); 560 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 561 base::Bind(&IsKnownUser, kAccountId2)).Run(); 562 563 CheckPublicSessionPresent(kAccountId1); 564 CheckPublicSessionPresent(kAccountId2); 565} 566 567static bool DisplayNameMatches(const std::string& account_id, 568 const std::string& display_name) { 569 const chromeos::User* user = 570 chromeos::UserManager::Get()->FindUser(account_id); 571 if (!user || user->display_name().empty()) 572 return false; 573 EXPECT_EQ(UTF8ToUTF16(display_name), user->display_name()); 574 return true; 575} 576 577IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { 578 NotificationWatcher( 579 chrome::NOTIFICATION_USER_LIST_CHANGED, 580 base::Bind(&DisplayNameMatches, kAccountId1, kDisplayName1)).Run(); 581} 582 583IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyDownload) { 584 // Policy for kAccountId2 is not installed in session_manager_client, make 585 // sure it gets fetched from the server. Note that the test setup doesn't set 586 // up policy for kAccountId2, so the presence of the display name can be used 587 // as signal to indicate successful policy download. 588 NotificationWatcher( 589 chrome::NOTIFICATION_USER_LIST_CHANGED, 590 base::Bind(&DisplayNameMatches, kAccountId2, kDisplayName2)).Run(); 591 592 // Sanity check: The policy should be present now. 593 ASSERT_FALSE(session_manager_client_.device_local_account_policy( 594 kAccountId2).empty()); 595} 596 597static bool IsNotKnownUser(const std::string& account_id) { 598 return !IsKnownUser(account_id); 599} 600 601IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DevicePolicyChange) { 602 // Wait until the login screen is up. 603 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 604 base::Bind(&IsKnownUser, kAccountId1)).Run(); 605 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 606 base::Bind(&IsKnownUser, kAccountId2)).Run(); 607 608 // Update policy to remove kAccountId2. 609 em::ChromeDeviceSettingsProto policy; 610 policy.mutable_show_user_names()->set_show_user_names(true); 611 em::DeviceLocalAccountInfoProto* account1 = 612 policy.mutable_device_local_accounts()->add_account(); 613 account1->set_account_id(kAccountId1); 614 account1->set_type( 615 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); 616 617 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, std::string(), 618 policy.SerializeAsString()); 619 g_browser_process->policy_service()->RefreshPolicies(base::Closure()); 620 621 // Make sure the second device-local account disappears. 622 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 623 base::Bind(&IsNotKnownUser, kAccountId2)).Run(); 624} 625 626static bool IsSessionStarted() { 627 return chromeos::UserManager::Get()->IsSessionStarted(); 628} 629 630IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, StartSession) { 631 // This observes the display name becoming available as this indicates 632 // device-local account policy is fully loaded, which is a prerequisite for 633 // successful login. 634 NotificationWatcher( 635 chrome::NOTIFICATION_USER_LIST_CHANGED, 636 base::Bind(&DisplayNameMatches, kAccountId1, kDisplayName1)).Run(); 637 638 chromeos::ExistingUserController* controller = 639 chromeos::ExistingUserController::current_controller(); 640 ASSERT_TRUE(controller); 641 controller->LoginAsPublicAccount(kAccountId1); 642 643 // Wait for the session to start. 644 NotificationWatcher(chrome::NOTIFICATION_SESSION_STARTED, 645 base::Bind(IsSessionStarted)).Run(); 646 647 // Check that the startup pages specified in policy were opened. 648 EXPECT_EQ(1U, chrome::GetTotalBrowserCount()); 649 Browser* browser = 650 chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH); 651 ASSERT_TRUE(browser); 652 653 TabStripModel* tabs = browser->tab_strip_model(); 654 ASSERT_TRUE(tabs); 655 int expected_tab_count = static_cast<int>(arraysize(kStartupURLs)); 656 EXPECT_EQ(expected_tab_count, tabs->count()); 657 for (int i = 0; i < expected_tab_count && i < tabs->count(); ++i) 658 EXPECT_EQ(GURL(kStartupURLs[i]), tabs->GetWebContentsAt(i)->GetURL()); 659} 660 661} // namespace policy 662