Home | History | Annotate | Download | only in common
      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