OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/policy/core/common/cloud/user_cloud_policy_store.h" | 5 #include "components/policy/core/common/cloud/user_cloud_policy_store.h" |
6 | 6 |
7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
8 #include "base/files/scoped_temp_dir.h" | 8 #include "base/files/scoped_temp_dir.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| 11 #include "base/test/scoped_task_environment.h" |
| 12 #include "base/threading/thread_task_runner_handle.h" |
11 #include "components/policy/core/common/cloud/cloud_policy_constants.h" | 13 #include "components/policy/core/common/cloud/cloud_policy_constants.h" |
12 #include "components/policy/core/common/cloud/mock_cloud_external_data_manager.h
" | 14 #include "components/policy/core/common/cloud/mock_cloud_external_data_manager.h
" |
13 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h" | 15 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h" |
14 #include "components/policy/core/common/cloud/policy_builder.h" | 16 #include "components/policy/core/common/cloud/policy_builder.h" |
15 #include "components/policy/core/common/policy_switches.h" | 17 #include "components/policy/core/common/policy_switches.h" |
16 #include "components/policy/policy_constants.h" | 18 #include "components/policy/policy_constants.h" |
17 #include "net/url_request/url_request_context_getter.h" | 19 #include "net/url_request/url_request_context_getter.h" |
18 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
20 | 22 |
(...skipping 24 matching lines...) Expand all Loading... |
45 return false; | 47 return false; |
46 } | 48 } |
47 | 49 |
48 return true; | 50 return true; |
49 } | 51 } |
50 | 52 |
51 } // namespace | 53 } // namespace |
52 | 54 |
53 class UserCloudPolicyStoreTest : public testing::Test { | 55 class UserCloudPolicyStoreTest : public testing::Test { |
54 public: | 56 public: |
55 UserCloudPolicyStoreTest() {} | 57 UserCloudPolicyStoreTest() |
| 58 : scoped_task_environment_( |
| 59 base::test::ScopedTaskEnvironment::MainThreadType::UI) {} |
56 | 60 |
57 void SetUp() override { | 61 void SetUp() override { |
58 ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir()); | 62 ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir()); |
59 store_.reset(new UserCloudPolicyStore(policy_file(), key_file(), | 63 store_.reset(new UserCloudPolicyStore(policy_file(), key_file(), |
60 loop_.task_runner())); | 64 base::ThreadTaskRunnerHandle::Get())); |
61 external_data_manager_.reset(new MockCloudExternalDataManager); | 65 external_data_manager_.reset(new MockCloudExternalDataManager); |
62 external_data_manager_->SetPolicyStore(store_.get()); | 66 external_data_manager_->SetPolicyStore(store_.get()); |
63 store_->SetSigninUsername(PolicyBuilder::kFakeUsername); | 67 store_->SetSigninUsername(PolicyBuilder::kFakeUsername); |
64 EXPECT_EQ(PolicyBuilder::kFakeUsername, store_->signin_username()); | 68 EXPECT_EQ(PolicyBuilder::kFakeUsername, store_->signin_username()); |
65 store_->AddObserver(&observer_); | 69 store_->AddObserver(&observer_); |
66 | 70 |
67 // Install an initial public key, so that by default the validation of | 71 // Install an initial public key, so that by default the validation of |
68 // the stored/loaded policy blob succeeds (it looks like a new key | 72 // the stored/loaded policy blob succeeds (it looks like a new key |
69 // provision). | 73 // provision). |
70 policy_.SetDefaultInitialSigningKey(); | 74 policy_.SetDefaultInitialSigningKey(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 Mock::VerifyAndClearExpectations(external_data_manager_.get()); | 127 Mock::VerifyAndClearExpectations(external_data_manager_.get()); |
124 Mock::VerifyAndClearExpectations(&observer_); | 128 Mock::VerifyAndClearExpectations(&observer_); |
125 ASSERT_TRUE(store_->policy()); | 129 ASSERT_TRUE(store_->policy()); |
126 } | 130 } |
127 | 131 |
128 UserPolicyBuilder policy_; | 132 UserPolicyBuilder policy_; |
129 MockCloudPolicyStoreObserver observer_; | 133 MockCloudPolicyStoreObserver observer_; |
130 std::unique_ptr<UserCloudPolicyStore> store_; | 134 std::unique_ptr<UserCloudPolicyStore> store_; |
131 std::unique_ptr<MockCloudExternalDataManager> external_data_manager_; | 135 std::unique_ptr<MockCloudExternalDataManager> external_data_manager_; |
132 | 136 |
133 // CloudPolicyValidator() requires a FILE thread so declare one here. Both | 137 base::test::ScopedTaskEnvironment scoped_task_environment_; |
134 // |ui_thread_| and |file_thread_| share the same MessageLoop |loop_| so | |
135 // callers can use RunLoop to manage both virtual threads. | |
136 base::MessageLoopForUI loop_; | |
137 | 138 |
138 base::ScopedTempDir tmp_dir_; | 139 base::ScopedTempDir tmp_dir_; |
139 | 140 |
140 private: | 141 private: |
141 DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreTest); | 142 DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreTest); |
142 }; | 143 }; |
143 | 144 |
144 TEST_F(UserCloudPolicyStoreTest, LoadWithNoFile) { | 145 TEST_F(UserCloudPolicyStoreTest, LoadWithNoFile) { |
145 EXPECT_FALSE(store_->policy()); | 146 EXPECT_FALSE(store_->policy()); |
146 EXPECT_TRUE(store_->policy_map().empty()); | 147 EXPECT_TRUE(store_->policy_map().empty()); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); | 347 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); |
347 } | 348 } |
348 | 349 |
349 TEST_F(UserCloudPolicyStoreTest, StoreThenLoad) { | 350 TEST_F(UserCloudPolicyStoreTest, StoreThenLoad) { |
350 // Store a simple policy and make sure it can be read back in. | 351 // Store a simple policy and make sure it can be read back in. |
351 // policy. | 352 // policy. |
352 StorePolicyAndEnsureLoaded(policy_.policy()); | 353 StorePolicyAndEnsureLoaded(policy_.policy()); |
353 EXPECT_FALSE(store_->policy_signature_public_key().empty()); | 354 EXPECT_FALSE(store_->policy_signature_public_key().empty()); |
354 | 355 |
355 // Now, make sure the policy can be read back in from a second store. | 356 // Now, make sure the policy can be read back in from a second store. |
356 std::unique_ptr<UserCloudPolicyStore> store2( | 357 std::unique_ptr<UserCloudPolicyStore> store2(new UserCloudPolicyStore( |
357 new UserCloudPolicyStore(policy_file(), key_file(), loop_.task_runner())); | 358 policy_file(), key_file(), base::ThreadTaskRunnerHandle::Get())); |
358 store2->SetSigninUsername(PolicyBuilder::kFakeUsername); | 359 store2->SetSigninUsername(PolicyBuilder::kFakeUsername); |
359 store2->AddObserver(&observer_); | 360 store2->AddObserver(&observer_); |
360 EXPECT_CALL(observer_, OnStoreLoaded(store2.get())); | 361 EXPECT_CALL(observer_, OnStoreLoaded(store2.get())); |
361 store2->Load(); | 362 store2->Load(); |
362 RunUntilIdle(); | 363 RunUntilIdle(); |
363 | 364 |
364 ASSERT_TRUE(store2->policy()); | 365 ASSERT_TRUE(store2->policy()); |
365 EXPECT_EQ(policy_.policy_data().SerializeAsString(), | 366 EXPECT_EQ(policy_.policy_data().SerializeAsString(), |
366 store2->policy()->SerializeAsString()); | 367 store2->policy()->SerializeAsString()); |
367 VerifyPolicyMap(store2.get()); | 368 VerifyPolicyMap(store2.get()); |
368 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store2->status()); | 369 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store2->status()); |
369 store2->RemoveObserver(&observer_); | 370 store2->RemoveObserver(&observer_); |
370 // Make sure that we properly resurrected the keys. | 371 // Make sure that we properly resurrected the keys. |
371 EXPECT_EQ(store2->policy_signature_public_key(), | 372 EXPECT_EQ(store2->policy_signature_public_key(), |
372 store_->policy_signature_public_key()); | 373 store_->policy_signature_public_key()); |
373 } | 374 } |
374 | 375 |
375 TEST_F(UserCloudPolicyStoreTest, StoreThenLoadImmediately) { | 376 TEST_F(UserCloudPolicyStoreTest, StoreThenLoadImmediately) { |
376 // Store a simple policy and make sure it can be read back in. | 377 // Store a simple policy and make sure it can be read back in. |
377 // policy. | 378 // policy. |
378 StorePolicyAndEnsureLoaded(policy_.policy()); | 379 StorePolicyAndEnsureLoaded(policy_.policy()); |
379 | 380 |
380 // Now, make sure the policy can be read back in from a second store. | 381 // Now, make sure the policy can be read back in from a second store. |
381 std::unique_ptr<UserCloudPolicyStore> store2( | 382 std::unique_ptr<UserCloudPolicyStore> store2(new UserCloudPolicyStore( |
382 new UserCloudPolicyStore(policy_file(), key_file(), loop_.task_runner())); | 383 policy_file(), key_file(), base::ThreadTaskRunnerHandle::Get())); |
383 store2->SetSigninUsername(PolicyBuilder::kFakeUsername); | 384 store2->SetSigninUsername(PolicyBuilder::kFakeUsername); |
384 store2->AddObserver(&observer_); | 385 store2->AddObserver(&observer_); |
385 EXPECT_CALL(observer_, OnStoreLoaded(store2.get())); | 386 EXPECT_CALL(observer_, OnStoreLoaded(store2.get())); |
386 store2->LoadImmediately(); // Should load without running the message loop. | 387 store2->LoadImmediately(); // Should load without running the message loop. |
387 | 388 |
388 ASSERT_TRUE(store2->policy()); | 389 ASSERT_TRUE(store2->policy()); |
389 EXPECT_EQ(policy_.policy_data().SerializeAsString(), | 390 EXPECT_EQ(policy_.policy_data().SerializeAsString(), |
390 store2->policy()->SerializeAsString()); | 391 store2->policy()->SerializeAsString()); |
391 VerifyPolicyMap(store2.get()); | 392 VerifyPolicyMap(store2.get()); |
392 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store2->status()); | 393 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store2->status()); |
(...skipping 22 matching lines...) Expand all Loading... |
415 RunUntilIdle(); | 416 RunUntilIdle(); |
416 ASSERT_FALSE(store_->policy()); | 417 ASSERT_FALSE(store_->policy()); |
417 } | 418 } |
418 | 419 |
419 TEST_F(UserCloudPolicyStoreTest, LoadValidationError) { | 420 TEST_F(UserCloudPolicyStoreTest, LoadValidationError) { |
420 // Force a validation error by changing the username after policy is stored. | 421 // Force a validation error by changing the username after policy is stored. |
421 StorePolicyAndEnsureLoaded(policy_.policy()); | 422 StorePolicyAndEnsureLoaded(policy_.policy()); |
422 | 423 |
423 // Sign out, and sign back in as a different user, and try to load the profile | 424 // Sign out, and sign back in as a different user, and try to load the profile |
424 // data (should fail due to mismatched username). | 425 // data (should fail due to mismatched username). |
425 std::unique_ptr<UserCloudPolicyStore> store2( | 426 std::unique_ptr<UserCloudPolicyStore> store2(new UserCloudPolicyStore( |
426 new UserCloudPolicyStore(policy_file(), key_file(), loop_.task_runner())); | 427 policy_file(), key_file(), base::ThreadTaskRunnerHandle::Get())); |
427 store2->SetSigninUsername("foobar@foobar.com"); | 428 store2->SetSigninUsername("foobar@foobar.com"); |
428 store2->AddObserver(&observer_); | 429 store2->AddObserver(&observer_); |
429 ExpectError(store2.get(), CloudPolicyStore::STATUS_VALIDATION_ERROR); | 430 ExpectError(store2.get(), CloudPolicyStore::STATUS_VALIDATION_ERROR); |
430 store2->Load(); | 431 store2->Load(); |
431 RunUntilIdle(); | 432 RunUntilIdle(); |
432 | 433 |
433 ASSERT_FALSE(store2->policy()); | 434 ASSERT_FALSE(store2->policy()); |
434 store2->RemoveObserver(&observer_); | 435 store2->RemoveObserver(&observer_); |
435 | 436 |
436 // Sign out - we should be able to load the policy (don't check usernames | 437 // Sign out - we should be able to load the policy (don't check usernames |
437 // when signed out). | 438 // when signed out). |
438 std::unique_ptr<UserCloudPolicyStore> store3( | 439 std::unique_ptr<UserCloudPolicyStore> store3(new UserCloudPolicyStore( |
439 new UserCloudPolicyStore(policy_file(), key_file(), loop_.task_runner())); | 440 policy_file(), key_file(), base::ThreadTaskRunnerHandle::Get())); |
440 store3->AddObserver(&observer_); | 441 store3->AddObserver(&observer_); |
441 EXPECT_CALL(observer_, OnStoreLoaded(store3.get())); | 442 EXPECT_CALL(observer_, OnStoreLoaded(store3.get())); |
442 store3->Load(); | 443 store3->Load(); |
443 RunUntilIdle(); | 444 RunUntilIdle(); |
444 | 445 |
445 ASSERT_TRUE(store3->policy()); | 446 ASSERT_TRUE(store3->policy()); |
446 store3->RemoveObserver(&observer_); | 447 store3->RemoveObserver(&observer_); |
447 | 448 |
448 // Now start a signin as a different user - this should fail validation. | 449 // Now start a signin as a different user - this should fail validation. |
449 std::unique_ptr<UserCloudPolicyStore> store4( | 450 std::unique_ptr<UserCloudPolicyStore> store4(new UserCloudPolicyStore( |
450 new UserCloudPolicyStore(policy_file(), key_file(), loop_.task_runner())); | 451 policy_file(), key_file(), base::ThreadTaskRunnerHandle::Get())); |
451 store4->SetSigninUsername("foobar@foobar.com"); | 452 store4->SetSigninUsername("foobar@foobar.com"); |
452 store4->AddObserver(&observer_); | 453 store4->AddObserver(&observer_); |
453 ExpectError(store4.get(), CloudPolicyStore::STATUS_VALIDATION_ERROR); | 454 ExpectError(store4.get(), CloudPolicyStore::STATUS_VALIDATION_ERROR); |
454 store4->Load(); | 455 store4->Load(); |
455 RunUntilIdle(); | 456 RunUntilIdle(); |
456 | 457 |
457 ASSERT_FALSE(store4->policy()); | 458 ASSERT_FALSE(store4->policy()); |
458 store4->RemoveObserver(&observer_); | 459 store4->RemoveObserver(&observer_); |
459 } | 460 } |
460 | 461 |
461 TEST_F(UserCloudPolicyStoreTest, KeyRotation) { | 462 TEST_F(UserCloudPolicyStoreTest, KeyRotation) { |
462 // Make sure when we load data from disk with a different key, that we trigger | 463 // Make sure when we load data from disk with a different key, that we trigger |
463 // a server-side key rotation. | 464 // a server-side key rotation. |
464 StorePolicyAndEnsureLoaded(policy_.policy()); | 465 StorePolicyAndEnsureLoaded(policy_.policy()); |
465 ASSERT_TRUE(store_->policy()->has_public_key_version()); | 466 ASSERT_TRUE(store_->policy()->has_public_key_version()); |
466 | 467 |
467 std::string key_data; | 468 std::string key_data; |
468 enterprise_management::PolicySigningKey key; | 469 enterprise_management::PolicySigningKey key; |
469 ASSERT_TRUE(base::ReadFileToString(key_file(), &key_data)); | 470 ASSERT_TRUE(base::ReadFileToString(key_file(), &key_data)); |
470 ASSERT_TRUE(key.ParseFromString(key_data)); | 471 ASSERT_TRUE(key.ParseFromString(key_data)); |
471 key.set_verification_key("different_key"); | 472 key.set_verification_key("different_key"); |
472 key.SerializeToString(&key_data); | 473 key.SerializeToString(&key_data); |
473 WriteStringToFile(key_file(), key_data); | 474 WriteStringToFile(key_file(), key_data); |
474 | 475 |
475 // Now load this in a new store - this should trigger key rotation. The keys | 476 // Now load this in a new store - this should trigger key rotation. The keys |
476 // will still verify using the existing verification key. | 477 // will still verify using the existing verification key. |
477 std::unique_ptr<UserCloudPolicyStore> store2( | 478 std::unique_ptr<UserCloudPolicyStore> store2(new UserCloudPolicyStore( |
478 new UserCloudPolicyStore(policy_file(), key_file(), loop_.task_runner())); | 479 policy_file(), key_file(), base::ThreadTaskRunnerHandle::Get())); |
479 store2->SetSigninUsername(PolicyBuilder::kFakeUsername); | 480 store2->SetSigninUsername(PolicyBuilder::kFakeUsername); |
480 store2->AddObserver(&observer_); | 481 store2->AddObserver(&observer_); |
481 EXPECT_CALL(observer_, OnStoreLoaded(store2.get())); | 482 EXPECT_CALL(observer_, OnStoreLoaded(store2.get())); |
482 store2->Load(); | 483 store2->Load(); |
483 RunUntilIdle(); | 484 RunUntilIdle(); |
484 ASSERT_TRUE(store2->policy()); | 485 ASSERT_TRUE(store2->policy()); |
485 ASSERT_FALSE(store2->policy()->has_public_key_version()); | 486 ASSERT_FALSE(store2->policy()->has_public_key_version()); |
486 store2->RemoveObserver(&observer_); | 487 store2->RemoveObserver(&observer_); |
487 } | 488 } |
488 | 489 |
489 TEST_F(UserCloudPolicyStoreTest, InvalidCachedVerificationSignature) { | 490 TEST_F(UserCloudPolicyStoreTest, InvalidCachedVerificationSignature) { |
490 // Make sure that we reject code with an invalid key. | 491 // Make sure that we reject code with an invalid key. |
491 StorePolicyAndEnsureLoaded(policy_.policy()); | 492 StorePolicyAndEnsureLoaded(policy_.policy()); |
492 | 493 |
493 std::string key_data; | 494 std::string key_data; |
494 enterprise_management::PolicySigningKey key; | 495 enterprise_management::PolicySigningKey key; |
495 ASSERT_TRUE(base::ReadFileToString(key_file(), &key_data)); | 496 ASSERT_TRUE(base::ReadFileToString(key_file(), &key_data)); |
496 ASSERT_TRUE(key.ParseFromString(key_data)); | 497 ASSERT_TRUE(key.ParseFromString(key_data)); |
497 key.set_signing_key_signature("different_key"); | 498 key.set_signing_key_signature("different_key"); |
498 key.SerializeToString(&key_data); | 499 key.SerializeToString(&key_data); |
499 WriteStringToFile(key_file(), key_data); | 500 WriteStringToFile(key_file(), key_data); |
500 | 501 |
501 // Now load this in a new store - this should cause a validation error because | 502 // Now load this in a new store - this should cause a validation error because |
502 // the key won't verify. | 503 // the key won't verify. |
503 std::unique_ptr<UserCloudPolicyStore> store2( | 504 std::unique_ptr<UserCloudPolicyStore> store2(new UserCloudPolicyStore( |
504 new UserCloudPolicyStore(policy_file(), key_file(), loop_.task_runner())); | 505 policy_file(), key_file(), base::ThreadTaskRunnerHandle::Get())); |
505 store2->SetSigninUsername(PolicyBuilder::kFakeUsername); | 506 store2->SetSigninUsername(PolicyBuilder::kFakeUsername); |
506 store2->AddObserver(&observer_); | 507 store2->AddObserver(&observer_); |
507 ExpectError(store2.get(), CloudPolicyStore::STATUS_VALIDATION_ERROR); | 508 ExpectError(store2.get(), CloudPolicyStore::STATUS_VALIDATION_ERROR); |
508 store2->Load(); | 509 store2->Load(); |
509 RunUntilIdle(); | 510 RunUntilIdle(); |
510 store2->RemoveObserver(&observer_); | 511 store2->RemoveObserver(&observer_); |
511 } | 512 } |
512 | 513 |
513 } // namespace policy | 514 } // namespace policy |
OLD | NEW |