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/policy/user_cloud_policy_store_chromeos.h" 6 7 #include <vector> 8 9 #include "base/basictypes.h" 10 #include "base/bind.h" 11 #include "base/file_util.h" 12 #include "base/files/scoped_temp_dir.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/message_loop/message_loop.h" 15 #include "base/threading/sequenced_worker_pool.h" 16 #include "chromeos/dbus/mock_cryptohome_client.h" 17 #include "chromeos/dbus/mock_session_manager_client.h" 18 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 19 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h" 20 #include "components/policy/core/common/cloud/policy_builder.h" 21 #include "policy/policy_constants.h" 22 #include "policy/proto/cloud_policy.pb.h" 23 #include "policy/proto/device_management_local.pb.h" 24 #include "testing/gmock/include/gmock/gmock.h" 25 #include "testing/gtest/include/gtest/gtest.h" 26 27 namespace em = enterprise_management; 28 29 using testing::AllOf; 30 using testing::AnyNumber; 31 using testing::Eq; 32 using testing::Mock; 33 using testing::Property; 34 using testing::Return; 35 using testing::SaveArg; 36 using testing::_; 37 38 namespace policy { 39 40 namespace { 41 42 const char kLegacyDeviceId[] = "legacy-device-id"; 43 const char kLegacyToken[] = "legacy-token"; 44 const char kSanitizedUsername[] = "0123456789ABCDEF0123456789ABCDEF012345678"; 45 const char kDefaultHomepage[] = "http://chromium.org"; 46 47 ACTION_P2(SendSanitizedUsername, call_status, sanitized_username) { 48 base::MessageLoop::current()->PostTask( 49 FROM_HERE, base::Bind(arg1, call_status, sanitized_username)); 50 } 51 52 class UserCloudPolicyStoreChromeOSTest : public testing::Test { 53 protected: 54 UserCloudPolicyStoreChromeOSTest() 55 : loop_(base::MessageLoop::TYPE_UI) {} 56 57 virtual void SetUp() OVERRIDE { 58 EXPECT_CALL(cryptohome_client_, 59 GetSanitizedUsername(PolicyBuilder::kFakeUsername, _)) 60 .Times(AnyNumber()) 61 .WillRepeatedly( 62 SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_SUCCESS, 63 kSanitizedUsername)); 64 65 ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir()); 66 store_.reset(new UserCloudPolicyStoreChromeOS(&cryptohome_client_, 67 &session_manager_client_, 68 loop_.message_loop_proxy(), 69 PolicyBuilder::kFakeUsername, 70 user_policy_dir(), 71 token_file(), 72 policy_file())); 73 store_->AddObserver(&observer_); 74 75 // Install the initial public key, so that by default the validation of 76 // the stored/loaded policy blob succeeds. 77 std::vector<uint8> public_key; 78 ASSERT_TRUE(policy_.GetSigningKey()->ExportPublicKey(&public_key)); 79 StoreUserPolicyKey(public_key); 80 81 policy_.payload().mutable_homepagelocation()->set_value(kDefaultHomepage); 82 policy_.Build(); 83 } 84 85 virtual void TearDown() OVERRIDE { 86 store_->RemoveObserver(&observer_); 87 store_.reset(); 88 RunUntilIdle(); 89 } 90 91 // Install an expectation on |observer_| for an error code. 92 void ExpectError(CloudPolicyStore::Status error) { 93 EXPECT_CALL(observer_, 94 OnStoreError(AllOf(Eq(store_.get()), 95 Property(&CloudPolicyStore::status, 96 Eq(error))))); 97 } 98 99 // Triggers a store_->Load() operation, handles the expected call to 100 // |session_manager_client_| and sends |response|. 101 void PerformPolicyLoad(const std::string& response) { 102 // Issue a load command. 103 chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback; 104 EXPECT_CALL(session_manager_client_, 105 RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _)) 106 .WillOnce(SaveArg<1>(&retrieve_callback)); 107 store_->Load(); 108 RunUntilIdle(); 109 Mock::VerifyAndClearExpectations(&session_manager_client_); 110 ASSERT_FALSE(retrieve_callback.is_null()); 111 112 // Run the callback. 113 retrieve_callback.Run(response); 114 RunUntilIdle(); 115 } 116 117 // Verifies that store_->policy_map() has the HomepageLocation entry with 118 // the |expected_value|. 119 void VerifyPolicyMap(const char* expected_value) { 120 EXPECT_EQ(1U, store_->policy_map().size()); 121 const PolicyMap::Entry* entry = 122 store_->policy_map().Get(key::kHomepageLocation); 123 ASSERT_TRUE(entry); 124 EXPECT_TRUE(base::StringValue(expected_value).Equals(entry->value)); 125 } 126 127 void StoreUserPolicyKey(const std::vector<uint8>& public_key) { 128 ASSERT_TRUE(base::CreateDirectory(user_policy_key_file().DirName())); 129 ASSERT_TRUE( 130 file_util::WriteFile(user_policy_key_file(), 131 reinterpret_cast<const char*>(public_key.data()), 132 public_key.size())); 133 } 134 135 // Stores the current |policy_| and verifies that it is published. 136 // If |new_public_key| is set then it will be persisted after storing but 137 // before loading the policy, so that the signature validation can succeed. 138 // If |previous_value| is set then a previously existing policy with that 139 // value will be expected; otherwise no previous policy is expected. 140 // If |new_value| is set then a new policy with that value is expected after 141 // storing the |policy_| blob. 142 void PerformStorePolicy(const std::vector<uint8>* new_public_key, 143 const char* previous_value, 144 const char* new_value) { 145 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 146 EXPECT_CALL(session_manager_client_, 147 StorePolicyForUser(PolicyBuilder::kFakeUsername, 148 policy_.GetBlob(), _, _)) 149 .WillOnce(SaveArg<3>(&store_callback)); 150 store_->Store(policy_.policy()); 151 RunUntilIdle(); 152 Mock::VerifyAndClearExpectations(&session_manager_client_); 153 ASSERT_FALSE(store_callback.is_null()); 154 155 // The new policy shouldn't be present yet. 156 PolicyMap previous_policy; 157 EXPECT_EQ(previous_value != NULL, store_->policy() != NULL); 158 if (previous_value) { 159 previous_policy.Set(key::kHomepageLocation, 160 POLICY_LEVEL_MANDATORY, 161 POLICY_SCOPE_USER, 162 base::Value::CreateStringValue(previous_value), NULL); 163 } 164 EXPECT_TRUE(previous_policy.Equals(store_->policy_map())); 165 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 166 167 // Store the new public key so that the validation after the retrieve 168 // operation completes can verify the signature. 169 if (new_public_key) 170 StoreUserPolicyKey(*new_public_key); 171 172 // Let the store operation complete. 173 chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback; 174 EXPECT_CALL(session_manager_client_, 175 RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _)) 176 .WillOnce(SaveArg<1>(&retrieve_callback)); 177 store_callback.Run(true); 178 RunUntilIdle(); 179 EXPECT_TRUE(previous_policy.Equals(store_->policy_map())); 180 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 181 Mock::VerifyAndClearExpectations(&session_manager_client_); 182 ASSERT_FALSE(retrieve_callback.is_null()); 183 184 // Finish the retrieve callback. 185 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 186 retrieve_callback.Run(policy_.GetBlob()); 187 RunUntilIdle(); 188 ASSERT_TRUE(store_->policy()); 189 EXPECT_EQ(policy_.policy_data().SerializeAsString(), 190 store_->policy()->SerializeAsString()); 191 VerifyPolicyMap(new_value); 192 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 193 } 194 195 void VerifyStoreHasValidationError() { 196 EXPECT_FALSE(store_->policy()); 197 EXPECT_TRUE(store_->policy_map().empty()); 198 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status()); 199 } 200 201 void RunUntilIdle() { 202 loop_.RunUntilIdle(); 203 loop_.RunUntilIdle(); 204 } 205 206 base::FilePath user_policy_dir() { 207 return tmp_dir_.path().AppendASCII("var_run_user_policy"); 208 } 209 210 base::FilePath user_policy_key_file() { 211 return user_policy_dir().AppendASCII(kSanitizedUsername) 212 .AppendASCII("policy.pub"); 213 } 214 215 base::FilePath token_file() { 216 return tmp_dir_.path().AppendASCII("token"); 217 } 218 219 base::FilePath policy_file() { 220 return tmp_dir_.path().AppendASCII("policy"); 221 } 222 223 base::MessageLoop loop_; 224 chromeos::MockCryptohomeClient cryptohome_client_; 225 chromeos::MockSessionManagerClient session_manager_client_; 226 UserPolicyBuilder policy_; 227 MockCloudPolicyStoreObserver observer_; 228 scoped_ptr<UserCloudPolicyStoreChromeOS> store_; 229 230 private: 231 base::ScopedTempDir tmp_dir_; 232 233 DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreChromeOSTest); 234 }; 235 236 TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStore) { 237 // Start without any public key to trigger the initial key checks. 238 ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false)); 239 // Make the policy blob contain a new public key. 240 policy_.SetDefaultNewSigningKey(); 241 policy_.Build(); 242 std::vector<uint8> new_public_key; 243 ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key)); 244 ASSERT_NO_FATAL_FAILURE( 245 PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage)); 246 } 247 248 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithExistingKey) { 249 ASSERT_NO_FATAL_FAILURE( 250 PerformStorePolicy(NULL, NULL, kDefaultHomepage)); 251 } 252 253 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithRotation) { 254 // Make the policy blob contain a new public key. 255 policy_.SetDefaultNewSigningKey(); 256 policy_.Build(); 257 std::vector<uint8> new_public_key; 258 ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key)); 259 ASSERT_NO_FATAL_FAILURE( 260 PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage)); 261 } 262 263 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreFail) { 264 // Store policy. 265 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 266 EXPECT_CALL(session_manager_client_, 267 StorePolicyForUser(PolicyBuilder::kFakeUsername, 268 policy_.GetBlob(), _, _)) 269 .WillOnce(SaveArg<3>(&store_callback)); 270 store_->Store(policy_.policy()); 271 RunUntilIdle(); 272 Mock::VerifyAndClearExpectations(&session_manager_client_); 273 ASSERT_FALSE(store_callback.is_null()); 274 275 // Let the store operation complete. 276 ExpectError(CloudPolicyStore::STATUS_STORE_ERROR); 277 store_callback.Run(false); 278 RunUntilIdle(); 279 EXPECT_FALSE(store_->policy()); 280 EXPECT_TRUE(store_->policy_map().empty()); 281 EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR, store_->status()); 282 } 283 284 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreValidationError) { 285 policy_.policy_data().clear_policy_type(); 286 policy_.Build(); 287 288 // Store policy. 289 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 290 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 291 EXPECT_CALL(session_manager_client_, 292 StorePolicyForUser(PolicyBuilder::kFakeUsername, 293 policy_.GetBlob(), _, _)) 294 .Times(0); 295 store_->Store(policy_.policy()); 296 RunUntilIdle(); 297 Mock::VerifyAndClearExpectations(&session_manager_client_); 298 } 299 300 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithoutPolicyKey) { 301 // Make the dbus call to cryptohome fail. 302 Mock::VerifyAndClearExpectations(&cryptohome_client_); 303 EXPECT_CALL(cryptohome_client_, 304 GetSanitizedUsername(PolicyBuilder::kFakeUsername, _)) 305 .Times(AnyNumber()) 306 .WillRepeatedly(SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_FAILURE, 307 std::string())); 308 309 // Store policy. 310 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 311 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 312 EXPECT_CALL(session_manager_client_, 313 StorePolicyForUser(PolicyBuilder::kFakeUsername, 314 policy_.GetBlob(), _, _)) 315 .Times(0); 316 store_->Store(policy_.policy()); 317 RunUntilIdle(); 318 Mock::VerifyAndClearExpectations(&session_manager_client_); 319 } 320 321 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithInvalidSignature) { 322 // Break the signature. 323 policy_.policy().mutable_policy_data_signature()->append("garbage"); 324 325 // Store policy. 326 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 327 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 328 EXPECT_CALL(session_manager_client_, 329 StorePolicyForUser(PolicyBuilder::kFakeUsername, 330 policy_.GetBlob(), _, _)) 331 .Times(0); 332 store_->Store(policy_.policy()); 333 RunUntilIdle(); 334 Mock::VerifyAndClearExpectations(&session_manager_client_); 335 } 336 337 TEST_F(UserCloudPolicyStoreChromeOSTest, Load) { 338 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 339 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob())); 340 Mock::VerifyAndClearExpectations(&observer_); 341 342 // Verify that the policy has been loaded. 343 ASSERT_TRUE(store_->policy()); 344 EXPECT_EQ(policy_.policy_data().SerializeAsString(), 345 store_->policy()->SerializeAsString()); 346 VerifyPolicyMap(kDefaultHomepage); 347 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 348 } 349 350 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoPolicy) { 351 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 352 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 353 Mock::VerifyAndClearExpectations(&observer_); 354 355 // Verify no policy has been installed. 356 EXPECT_FALSE(store_->policy()); 357 EXPECT_TRUE(store_->policy_map().empty()); 358 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 359 } 360 361 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidPolicy) { 362 ExpectError(CloudPolicyStore::STATUS_PARSE_ERROR); 363 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("invalid")); 364 365 // Verify no policy has been installed. 366 EXPECT_FALSE(store_->policy()); 367 EXPECT_TRUE(store_->policy_map().empty()); 368 EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status()); 369 } 370 371 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadValidationError) { 372 policy_.policy_data().clear_policy_type(); 373 policy_.Build(); 374 375 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 376 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob())); 377 VerifyStoreHasValidationError(); 378 } 379 380 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoKey) { 381 // The loaded policy can't be verified without the public key. 382 ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false)); 383 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 384 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob())); 385 VerifyStoreHasValidationError(); 386 } 387 388 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidSignature) { 389 // Break the signature. 390 policy_.policy().mutable_policy_data_signature()->append("garbage"); 391 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 392 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob())); 393 VerifyStoreHasValidationError(); 394 } 395 396 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationFull) { 397 std::string data; 398 399 em::DeviceCredentials credentials; 400 credentials.set_device_token(kLegacyToken); 401 credentials.set_device_id(kLegacyDeviceId); 402 ASSERT_TRUE(credentials.SerializeToString(&data)); 403 ASSERT_NE(-1, file_util::WriteFile(token_file(), data.c_str(), data.size())); 404 405 em::CachedCloudPolicyResponse cached_policy; 406 cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy()); 407 ASSERT_TRUE(cached_policy.SerializeToString(&data)); 408 ASSERT_NE(-1, file_util::WriteFile(policy_file(), data.c_str(), data.size())); 409 410 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 411 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 412 Mock::VerifyAndClearExpectations(&observer_); 413 414 // Verify that legacy user policy and token have been loaded. 415 em::PolicyData expected_policy_data; 416 EXPECT_TRUE(expected_policy_data.ParseFromString( 417 cached_policy.cloud_policy().policy_data())); 418 expected_policy_data.clear_public_key_version(); 419 expected_policy_data.set_request_token(kLegacyToken); 420 expected_policy_data.set_device_id(kLegacyDeviceId); 421 ASSERT_TRUE(store_->policy()); 422 EXPECT_EQ(expected_policy_data.SerializeAsString(), 423 store_->policy()->SerializeAsString()); 424 VerifyPolicyMap(kDefaultHomepage); 425 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 426 } 427 428 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoToken) { 429 std::string data; 430 testing::Sequence seq; 431 432 em::CachedCloudPolicyResponse cached_policy; 433 cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy()); 434 ASSERT_TRUE(cached_policy.SerializeToString(&data)); 435 ASSERT_NE(-1, file_util::WriteFile(policy_file(), data.c_str(), data.size())); 436 437 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 438 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 439 Mock::VerifyAndClearExpectations(&observer_); 440 441 // Verify the legacy cache has been loaded. 442 em::PolicyData expected_policy_data; 443 EXPECT_TRUE(expected_policy_data.ParseFromString( 444 cached_policy.cloud_policy().policy_data())); 445 expected_policy_data.clear_public_key_version(); 446 ASSERT_TRUE(store_->policy()); 447 EXPECT_EQ(expected_policy_data.SerializeAsString(), 448 store_->policy()->SerializeAsString()); 449 VerifyPolicyMap(kDefaultHomepage); 450 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 451 } 452 453 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoPolicy) { 454 std::string data; 455 456 em::DeviceCredentials credentials; 457 credentials.set_device_token(kLegacyToken); 458 credentials.set_device_id(kLegacyDeviceId); 459 ASSERT_TRUE(credentials.SerializeToString(&data)); 460 ASSERT_NE(-1, file_util::WriteFile(token_file(), data.c_str(), data.size())); 461 462 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 463 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 464 Mock::VerifyAndClearExpectations(&observer_); 465 466 // Verify that legacy user policy and token have been loaded. 467 em::PolicyData expected_policy_data; 468 expected_policy_data.set_request_token(kLegacyToken); 469 expected_policy_data.set_device_id(kLegacyDeviceId); 470 ASSERT_TRUE(store_->policy()); 471 EXPECT_EQ(expected_policy_data.SerializeAsString(), 472 store_->policy()->SerializeAsString()); 473 EXPECT_TRUE(store_->policy_map().empty()); 474 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 475 } 476 477 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationAndStoreNew) { 478 // Start without an existing public key. 479 ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false)); 480 481 std::string data; 482 em::CachedCloudPolicyResponse cached_policy; 483 cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy()); 484 ASSERT_TRUE(cached_policy.SerializeToString(&data)); 485 ASSERT_NE(-1, file_util::WriteFile(policy_file(), data.c_str(), data.size())); 486 487 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 488 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 489 Mock::VerifyAndClearExpectations(&observer_); 490 491 // Verify the legacy cache has been loaded. 492 em::PolicyData expected_policy_data; 493 EXPECT_TRUE(expected_policy_data.ParseFromString( 494 cached_policy.cloud_policy().policy_data())); 495 expected_policy_data.clear_public_key_version(); 496 ASSERT_TRUE(store_->policy()); 497 EXPECT_EQ(expected_policy_data.SerializeAsString(), 498 store_->policy()->SerializeAsString()); 499 VerifyPolicyMap(kDefaultHomepage); 500 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 501 EXPECT_TRUE(base::PathExists(policy_file())); 502 503 // Now store a new policy using the new homepage location. 504 const char kNewHomepage[] = "http://google.com"; 505 policy_.payload().mutable_homepagelocation()->set_value(kNewHomepage); 506 policy_.SetDefaultNewSigningKey(); 507 policy_.Build(); 508 std::vector<uint8> new_public_key; 509 ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key)); 510 ASSERT_NO_FATAL_FAILURE( 511 PerformStorePolicy(&new_public_key, kDefaultHomepage, kNewHomepage)); 512 VerifyPolicyMap(kNewHomepage); 513 514 // Verify that the legacy cache has been removed. 515 EXPECT_FALSE(base::PathExists(policy_file())); 516 } 517 518 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediately) { 519 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 520 EXPECT_CALL(session_manager_client_, 521 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 522 .WillOnce(Return(policy_.GetBlob())); 523 EXPECT_CALL(cryptohome_client_, 524 BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername)) 525 .WillOnce(Return(kSanitizedUsername)); 526 527 EXPECT_FALSE(store_->policy()); 528 store_->LoadImmediately(); 529 // Note: verify that the |observer_| got notified synchronously, without 530 // having to spin the current loop. TearDown() will flush the loop so this 531 // must be done within the test. 532 Mock::VerifyAndClearExpectations(&observer_); 533 Mock::VerifyAndClearExpectations(&session_manager_client_); 534 Mock::VerifyAndClearExpectations(&cryptohome_client_); 535 536 // The policy should become available without having to spin any loops. 537 ASSERT_TRUE(store_->policy()); 538 EXPECT_EQ(policy_.policy_data().SerializeAsString(), 539 store_->policy()->SerializeAsString()); 540 VerifyPolicyMap(kDefaultHomepage); 541 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 542 } 543 544 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoPolicy) { 545 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 546 EXPECT_CALL(session_manager_client_, 547 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 548 .WillOnce(Return("")); 549 550 EXPECT_FALSE(store_->policy()); 551 store_->LoadImmediately(); 552 Mock::VerifyAndClearExpectations(&observer_); 553 Mock::VerifyAndClearExpectations(&session_manager_client_); 554 555 EXPECT_FALSE(store_->policy()); 556 EXPECT_TRUE(store_->policy_map().empty()); 557 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 558 } 559 560 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyInvalidBlob) { 561 EXPECT_CALL(observer_, OnStoreError(store_.get())); 562 EXPECT_CALL(session_manager_client_, 563 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 564 .WillOnce(Return("le blob")); 565 566 EXPECT_FALSE(store_->policy()); 567 store_->LoadImmediately(); 568 Mock::VerifyAndClearExpectations(&observer_); 569 Mock::VerifyAndClearExpectations(&session_manager_client_); 570 571 EXPECT_FALSE(store_->policy()); 572 EXPECT_TRUE(store_->policy_map().empty()); 573 EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status()); 574 } 575 576 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyDBusFailure) { 577 EXPECT_CALL(observer_, OnStoreError(store_.get())); 578 EXPECT_CALL(session_manager_client_, 579 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 580 .WillOnce(Return(policy_.GetBlob())); 581 EXPECT_CALL(cryptohome_client_, 582 BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername)) 583 .WillOnce(Return("")); 584 585 EXPECT_FALSE(store_->policy()); 586 store_->LoadImmediately(); 587 Mock::VerifyAndClearExpectations(&observer_); 588 Mock::VerifyAndClearExpectations(&session_manager_client_); 589 Mock::VerifyAndClearExpectations(&cryptohome_client_); 590 591 EXPECT_FALSE(store_->policy()); 592 EXPECT_TRUE(store_->policy_map().empty()); 593 EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR, store_->status()); 594 } 595 596 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoUserPolicyKey) { 597 EXPECT_CALL(observer_, OnStoreError(store_.get())); 598 EXPECT_CALL(session_manager_client_, 599 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 600 .WillOnce(Return(policy_.GetBlob())); 601 EXPECT_CALL(cryptohome_client_, 602 BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername)) 603 .WillOnce(Return("wrong")); 604 605 EXPECT_FALSE(store_->policy()); 606 store_->LoadImmediately(); 607 Mock::VerifyAndClearExpectations(&observer_); 608 Mock::VerifyAndClearExpectations(&session_manager_client_); 609 Mock::VerifyAndClearExpectations(&cryptohome_client_); 610 611 EXPECT_FALSE(store_->policy()); 612 EXPECT_TRUE(store_->policy_map().empty()); 613 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status()); 614 } 615 616 } // namespace 617 618 } // namespace policy 619