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