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 3 // found in the LICENSE file. 4 5 #include "components/policy/core/common/policy_bundle.h" 6 7 #include "base/callback.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/values.h" 10 #include "components/policy/core/common/external_data_fetcher.h" 11 #include "components/policy/core/common/policy_map.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 namespace policy { 15 16 namespace { 17 18 const char kPolicyClashing0[] = "policy-clashing-0"; 19 const char kPolicyClashing1[] = "policy-clashing-1"; 20 const char kPolicy0[] = "policy-0"; 21 const char kPolicy1[] = "policy-1"; 22 const char kPolicy2[] = "policy-2"; 23 const char kExtension0[] = "extension-0"; 24 const char kExtension1[] = "extension-1"; 25 const char kExtension2[] = "extension-2"; 26 const char kExtension3[] = "extension-3"; 27 28 // Adds test policies to |policy|. 29 void AddTestPolicies(PolicyMap* policy) { 30 policy->Set("mandatory-user", POLICY_LEVEL_MANDATORY, 31 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(123), NULL); 32 policy->Set("mandatory-machine", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, 33 base::Value::CreateStringValue("omg"), NULL); 34 policy->Set("recommended-user", POLICY_LEVEL_RECOMMENDED, 35 POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL); 36 base::DictionaryValue* dict = new base::DictionaryValue(); 37 dict->SetBoolean("false", false); 38 dict->SetInteger("int", 456); 39 dict->SetString("str", "bbq"); 40 policy->Set("recommended-machine", POLICY_LEVEL_RECOMMENDED, 41 POLICY_SCOPE_MACHINE, dict, NULL); 42 } 43 44 // Adds test policies to |policy| based on the parameters: 45 // - kPolicyClashing0 mapped to |value|, user mandatory 46 // - kPolicyClashing1 mapped to |value|, with |level| and |scope| 47 // - |name| mapped to |value|, user mandatory 48 void AddTestPoliciesWithParams(PolicyMap *policy, 49 const char* name, 50 int value, 51 PolicyLevel level, 52 PolicyScope scope) { 53 policy->Set(kPolicyClashing0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 54 base::Value::CreateIntegerValue(value), NULL); 55 policy->Set(kPolicyClashing1, level, scope, 56 base::Value::CreateIntegerValue(value), NULL); 57 policy->Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 58 base::Value::CreateIntegerValue(value), NULL); 59 } 60 61 // Returns true if |bundle| is empty. 62 bool IsEmpty(const PolicyBundle& bundle) { 63 return bundle.begin() == bundle.end(); 64 } 65 66 } // namespace 67 68 TEST(PolicyBundleTest, Get) { 69 PolicyBundle bundle; 70 EXPECT_TRUE(IsEmpty(bundle)); 71 72 AddTestPolicies(&bundle.Get( 73 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))); 74 EXPECT_FALSE(IsEmpty(bundle)); 75 76 PolicyMap policy; 77 AddTestPolicies(&policy); 78 EXPECT_TRUE(bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, 79 std::string())).Equals(policy)); 80 81 PolicyBundle::const_iterator it = bundle.begin(); 82 ASSERT_TRUE(it != bundle.end()); 83 EXPECT_EQ(POLICY_DOMAIN_CHROME, it->first.domain); 84 EXPECT_EQ("", it->first.component_id); 85 ASSERT_TRUE(it->second); 86 EXPECT_TRUE(it->second->Equals(policy)); 87 ++it; 88 EXPECT_TRUE(it == bundle.end()); 89 EXPECT_TRUE(bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, 90 kExtension0)).empty()); 91 92 EXPECT_FALSE(IsEmpty(bundle)); 93 bundle.Clear(); 94 EXPECT_TRUE(IsEmpty(bundle)); 95 } 96 97 TEST(PolicyBundleTest, SwapAndCopy) { 98 PolicyBundle bundle0; 99 PolicyBundle bundle1; 100 101 AddTestPolicies(&bundle0.Get( 102 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))); 103 AddTestPolicies(&bundle0.Get( 104 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension0))); 105 EXPECT_FALSE(IsEmpty(bundle0)); 106 EXPECT_TRUE(IsEmpty(bundle1)); 107 108 PolicyMap policy; 109 AddTestPolicies(&policy); 110 EXPECT_TRUE(bundle0.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, 111 std::string())).Equals(policy)); 112 EXPECT_TRUE(bundle0.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, 113 kExtension0)).Equals(policy)); 114 115 bundle0.Swap(&bundle1); 116 EXPECT_TRUE(IsEmpty(bundle0)); 117 EXPECT_FALSE(IsEmpty(bundle1)); 118 119 EXPECT_TRUE(bundle1.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, 120 std::string())).Equals(policy)); 121 EXPECT_TRUE(bundle1.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, 122 kExtension0)).Equals(policy)); 123 124 bundle0.CopyFrom(bundle1); 125 EXPECT_FALSE(IsEmpty(bundle0)); 126 EXPECT_FALSE(IsEmpty(bundle1)); 127 EXPECT_TRUE(bundle0.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, 128 std::string())).Equals(policy)); 129 EXPECT_TRUE(bundle0.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, 130 kExtension0)).Equals(policy)); 131 } 132 133 TEST(PolicyBundleTest, MergeFrom) { 134 // Each bundleN has kExtensionN. Each bundle also has policy for 135 // chrome and kExtension3. 136 // |bundle0| has the highest priority, |bundle2| the lowest. 137 PolicyBundle bundle0; 138 PolicyBundle bundle1; 139 PolicyBundle bundle2; 140 141 PolicyMap policy0; 142 AddTestPoliciesWithParams( 143 &policy0, kPolicy0, 0u, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER); 144 bundle0.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 145 .CopyFrom(policy0); 146 bundle0.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension0)) 147 .CopyFrom(policy0); 148 bundle0.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension3)) 149 .CopyFrom(policy0); 150 151 PolicyMap policy1; 152 AddTestPoliciesWithParams( 153 &policy1, kPolicy1, 1u, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE); 154 bundle1.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 155 .CopyFrom(policy1); 156 bundle1.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension1)) 157 .CopyFrom(policy1); 158 bundle1.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension3)) 159 .CopyFrom(policy1); 160 161 PolicyMap policy2; 162 AddTestPoliciesWithParams( 163 &policy2, kPolicy2, 2u, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER); 164 bundle2.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 165 .CopyFrom(policy2); 166 bundle2.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension2)) 167 .CopyFrom(policy2); 168 bundle2.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension3)) 169 .CopyFrom(policy2); 170 171 // Merge in order of decreasing priority. 172 PolicyBundle merged; 173 merged.MergeFrom(bundle0); 174 merged.MergeFrom(bundle1); 175 merged.MergeFrom(bundle2); 176 PolicyBundle empty_bundle; 177 merged.MergeFrom(empty_bundle); 178 179 // chrome and kExtension3 policies are merged: 180 // - kPolicyClashing0 comes from bundle0, which has the highest priority; 181 // - kPolicyClashing1 comes from bundle1, which has the highest level/scope 182 // combination; 183 // - kPolicyN are merged from each bundle. 184 PolicyMap expected; 185 expected.Set(kPolicyClashing0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 186 base::Value::CreateIntegerValue(0), NULL); 187 expected.Set(kPolicyClashing1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, 188 base::Value::CreateIntegerValue(1), NULL); 189 expected.Set(kPolicy0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 190 base::Value::CreateIntegerValue(0), NULL); 191 expected.Set(kPolicy1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 192 base::Value::CreateIntegerValue(1), NULL); 193 expected.Set(kPolicy2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 194 base::Value::CreateIntegerValue(2), NULL); 195 EXPECT_TRUE(merged.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, 196 std::string())).Equals(expected)); 197 EXPECT_TRUE(merged.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, 198 kExtension3)).Equals(expected)); 199 // extension0 comes only from bundle0. 200 EXPECT_TRUE(merged.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, 201 kExtension0)).Equals(policy0)); 202 // extension1 comes only from bundle1. 203 EXPECT_TRUE(merged.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, 204 kExtension1)).Equals(policy1)); 205 // extension2 comes only from bundle2. 206 EXPECT_TRUE(merged.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, 207 kExtension2)).Equals(policy2)); 208 } 209 210 TEST(PolicyBundleTest, Equals) { 211 PolicyBundle bundle; 212 AddTestPolicies(&bundle.Get( 213 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))); 214 AddTestPolicies(&bundle.Get( 215 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension0))); 216 217 PolicyBundle other; 218 EXPECT_FALSE(bundle.Equals(other)); 219 other.CopyFrom(bundle); 220 EXPECT_TRUE(bundle.Equals(other)); 221 222 AddTestPolicies(&bundle.Get( 223 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension1))); 224 EXPECT_FALSE(bundle.Equals(other)); 225 other.CopyFrom(bundle); 226 EXPECT_TRUE(bundle.Equals(other)); 227 AddTestPolicies(&other.Get( 228 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension2))); 229 EXPECT_FALSE(bundle.Equals(other)); 230 231 other.CopyFrom(bundle); 232 bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 233 .Set(kPolicy0, 234 POLICY_LEVEL_MANDATORY, 235 POLICY_SCOPE_USER, 236 base::Value::CreateIntegerValue(123), 237 NULL); 238 EXPECT_FALSE(bundle.Equals(other)); 239 other.CopyFrom(bundle); 240 EXPECT_TRUE(bundle.Equals(other)); 241 bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 242 .Set(kPolicy0, 243 POLICY_LEVEL_MANDATORY, 244 POLICY_SCOPE_MACHINE, 245 base::Value::CreateIntegerValue(123), 246 NULL); 247 EXPECT_FALSE(bundle.Equals(other)); 248 249 // Test non-const Get(). 250 bundle.Clear(); 251 other.Clear(); 252 PolicyMap& policy_map = 253 bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); 254 EXPECT_TRUE(bundle.Equals(other)); 255 policy_map.Set(kPolicy0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 256 base::Value::CreateIntegerValue(123), NULL); 257 EXPECT_FALSE(bundle.Equals(other)); 258 } 259 260 } // namespace policy 261