12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/component_cloud_policy_store.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/callback.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/memory/ref_counted.h" 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/test/test_simple_task_runner.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/policy_builder.h" 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/resource_cache.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/external_data_fetcher.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "crypto/sha2.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/chrome_extension_policy.pb.h" 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace em = enterprise_management; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Mock; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace policy { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestExtension[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestDownload[] = "http://example.com/getpolicy?id=123"; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestPolicy[] = 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "{" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"Name\": {" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"Value\": \"disabled\"" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " }," 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"Second\": {" 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"Value\": \"maybe\"," 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"Level\": \"Recommended\"" 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " }" 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "}"; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TestPolicyHash() { 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return crypto::SHA256HashString(kTestPolicy); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool NotEqual(const std::string& expected, const std::string& key) { 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return key != expected; 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool True(const std::string& ignored) { 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockComponentCloudPolicyStoreDelegate 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public ComponentCloudPolicyStore::Delegate { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~MockComponentCloudPolicyStoreDelegate() {} 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MOCK_METHOD0(OnComponentCloudPolicyStoreUpdated, void()); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ComponentCloudPolicyStoreTest : public testing::Test { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUp() OVERRIDE { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) cache_.reset(new ResourceCache( 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) temp_dir_.path(), 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) make_scoped_refptr(new base::TestSimpleTaskRunner))); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_.reset(new ComponentCloudPolicyStore(&store_delegate_, cache_.get())); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_->SetCredentials(ComponentPolicyBuilder::kFakeUsername, 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentPolicyBuilder::kFakeToken); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.policy_data().set_policy_type( 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dm_protocol::kChromeExtensionPolicyType); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.policy_data().set_settings_entity_id(kTestExtension); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.payload().set_download_url(kTestDownload); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.payload().set_secure_hash(TestPolicyHash()); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyMap& policy = expected_bundle_.Get(ns); 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) policy.Set("Name", 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) POLICY_LEVEL_MANDATORY, 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) POLICY_SCOPE_USER, 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new base::StringValue("disabled"), 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL); 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) policy.Set("Second", 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) POLICY_LEVEL_RECOMMENDED, 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) POLICY_SCOPE_USER, 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new base::StringValue("maybe"), 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true if the policy exposed by the |store_| is empty. 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool IsEmpty() { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return store_->policy().begin() == store_->policy().end(); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<em::PolicyFetchResponse> CreateResponse() { 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.Build(); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return make_scoped_ptr(new em::PolicyFetchResponse(builder_.policy())); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string CreateSerializedResponse() { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.Build(); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return builder_.GetBlob(); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ScopedTempDir temp_dir_; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceCache> cache_; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ComponentCloudPolicyStore> store_; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockComponentCloudPolicyStoreDelegate store_delegate_; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentPolicyBuilder builder_; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyBundle expected_bundle_; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, ValidatePolicy) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::ExternalPolicyData payload; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->ValidatePolicy(CreateResponse(), &ns, &payload)); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(POLICY_DOMAIN_EXTENSIONS, ns.domain); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kTestExtension, ns.component_id); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kTestDownload, payload.download_url()); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(TestPolicyHash(), payload.secure_hash()); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, ValidatePolicyWrongUsername) { 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.policy_data().set_username("anotheruser@example.com"); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::ExternalPolicyData payload; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->ValidatePolicy(CreateResponse(), &ns, &payload)); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, ValidatePolicyWrongDMToken) { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.policy_data().set_request_token("notmytoken"); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::ExternalPolicyData payload; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->ValidatePolicy(CreateResponse(), &ns, &payload)); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, ValidatePolicyBadType) { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.policy_data().set_policy_type(dm_protocol::kChromeUserPolicyType); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::ExternalPolicyData payload; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->ValidatePolicy(CreateResponse(), &ns, &payload)); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, ValidatePolicyBadDownloadUrl) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.payload().set_download_url("invalidurl"); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::ExternalPolicyData payload; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->ValidatePolicy(CreateResponse(), &ns, &payload)); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, ValidatePolicyEmptyDownloadUrl) { 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.payload().clear_download_url(); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.payload().clear_secure_hash(); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::ExternalPolicyData payload; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is valid; it's how "no policy" is signalled to the client. 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->ValidatePolicy(CreateResponse(), &ns, &payload)); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, ValidatePolicyBadPayload) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.clear_payload(); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.policy_data().set_policy_value("broken"); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::ExternalPolicyData payload; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->ValidatePolicy(CreateResponse(), &ns, &payload)); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, ValidateNoCredentials) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_.reset(new ComponentCloudPolicyStore(&store_delegate_, cache_.get())); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::ExternalPolicyData payload; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->ValidatePolicy(CreateResponse(), &ns, &payload)); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, ValidateWrongCredentials) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::ExternalPolicyData payload; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify that the default response validates with the right credentials. 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->ValidatePolicy(CreateResponse(), &ns, &payload)); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Now store that response. 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(store_delegate_, OnComponentCloudPolicyStoreUpdated()); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->Store( 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ns, CreateSerializedResponse(), TestPolicyHash(), kTestPolicy)); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&store_delegate_); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->policy().Equals(expected_bundle_)); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // And verify that the response data in the cache. 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<std::string, std::string> contents; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cache_->LoadAllSubkeys("extension-policy", &contents); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(contents.empty()); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Try loading the cached response data with wrong credentials. 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentCloudPolicyStore another_store(&store_delegate_, cache_.get()); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) another_store.SetCredentials("wrongdude@example.com", "wrongtoken"); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) another_store.Load(); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PolicyBundle empty_bundle; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(another_store.policy().Equals(empty_bundle)); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The failure to read wiped the cache. 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cache_->LoadAllSubkeys("extension-policy", &contents); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(contents.empty()); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, StoreAndLoad) { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initially empty. 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(IsEmpty()); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_->Load(); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(IsEmpty()); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Store policy for an unsupported domain. 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns(POLICY_DOMAIN_CHROME, kTestExtension); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.policy_data().set_policy_type(dm_protocol::kChromeUserPolicyType); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->Store( 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ns, CreateSerializedResponse(), TestPolicyHash(), kTestPolicy)); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Store policy with the wrong hash. 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.policy_data().set_policy_type( 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dm_protocol::kChromeExtensionPolicyType); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ns.domain = POLICY_DOMAIN_EXTENSIONS; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.payload().set_secure_hash("badash"); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->Store( 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ns, CreateSerializedResponse(), "badash", kTestPolicy)); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Store policy without a hash. 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.payload().clear_secure_hash(); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->Store( 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ns, CreateSerializedResponse(), std::string(), kTestPolicy)); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Store policy with invalid JSON data. 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const char kInvalidData[] = "{ not json }"; 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string invalid_data_hash = crypto::SHA256HashString(kInvalidData); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.payload().set_secure_hash(invalid_data_hash); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(store_->Store( 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ns, CreateSerializedResponse(), invalid_data_hash, kInvalidData)); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // All of those failed. 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(IsEmpty()); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(std::string(), store_->GetCachedHash(ns)); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Now store a valid policy. 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder_.payload().set_secure_hash(TestPolicyHash()); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(store_delegate_, OnComponentCloudPolicyStoreUpdated()); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->Store( 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ns, CreateSerializedResponse(), TestPolicyHash(), kTestPolicy)); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&store_delegate_); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(IsEmpty()); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->policy().Equals(expected_bundle_)); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(TestPolicyHash(), store_->GetCachedHash(ns)); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Loading from the cache validates the policy data again. 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentCloudPolicyStore another_store(&store_delegate_, cache_.get()); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) another_store.SetCredentials(ComponentPolicyBuilder::kFakeUsername, 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentPolicyBuilder::kFakeToken); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) another_store.Load(); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(another_store.policy().Equals(expected_bundle_)); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(TestPolicyHash(), another_store.GetCachedHash(ns)); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, Updates) { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Store some policies. 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(store_delegate_, OnComponentCloudPolicyStoreUpdated()); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->Store( 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ns, CreateSerializedResponse(), TestPolicyHash(), kTestPolicy)); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&store_delegate_); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(IsEmpty()); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->policy().Equals(expected_bundle_)); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Deleting a non-existant namespace doesn't trigger updates. 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns_fake(POLICY_DOMAIN_EXTENSIONS, "nosuchid"); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_->Delete(ns_fake); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&store_delegate_); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Deleting a namespace that has policies triggers an update. 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(store_delegate_, OnComponentCloudPolicyStoreUpdated()); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_->Delete(ns); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&store_delegate_); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyStoreTest, Purge) { 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Store a valid policy. 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(store_delegate_, OnComponentCloudPolicyStoreUpdated()); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->Store( 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ns, CreateSerializedResponse(), TestPolicyHash(), kTestPolicy)); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&store_delegate_); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(IsEmpty()); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->policy().Equals(expected_bundle_)); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Purge other components. 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_->Purge(POLICY_DOMAIN_EXTENSIONS, 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&NotEqual, kTestExtension)); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The policy for |ns| is still served. 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->policy().Equals(expected_bundle_)); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Loading the store again will still see |ns|. 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentCloudPolicyStore another_store(&store_delegate_, cache_.get()); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PolicyBundle empty_bundle; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(another_store.policy().Equals(empty_bundle)); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) another_store.SetCredentials(ComponentPolicyBuilder::kFakeUsername, 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentPolicyBuilder::kFakeToken); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) another_store.Load(); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(another_store.policy().Equals(expected_bundle_)); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Now purge everything. 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(store_delegate_, OnComponentCloudPolicyStoreUpdated()); 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_->Purge(POLICY_DOMAIN_EXTENSIONS, base::Bind(&True)); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&store_delegate_); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No policies are served anymore. 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(store_->policy().Equals(empty_bundle)); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // And they aren't loaded anymore either. 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentCloudPolicyStore yet_another_store(&store_delegate_, cache_.get()); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) yet_another_store.SetCredentials(ComponentPolicyBuilder::kFakeUsername, 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentPolicyBuilder::kFakeToken); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) yet_another_store.Load(); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(yet_another_store.policy().Equals(empty_bundle)); 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace policy 332