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