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