| OLD | NEW | 
 | (Empty) | 
|    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 "chrome/browser/policy/schema_map.h" |  | 
|    6  |  | 
|    7 #include "base/memory/weak_ptr.h" |  | 
|    8 #include "base/values.h" |  | 
|    9 #include "components/policy/core/common/external_data_fetcher.h" |  | 
|   10 #include "components/policy/core/common/external_data_manager.h" |  | 
|   11 #include "components/policy/core/common/policy_bundle.h" |  | 
|   12 #include "components/policy/core/common/policy_map.h" |  | 
|   13 #include "components/policy/core/common/schema.h" |  | 
|   14 #include "testing/gtest/include/gtest/gtest.h" |  | 
|   15  |  | 
|   16 namespace policy { |  | 
|   17  |  | 
|   18 namespace { |  | 
|   19  |  | 
|   20 const char kTestSchema[] = |  | 
|   21     "{" |  | 
|   22     "  \"type\": \"object\"," |  | 
|   23     "  \"properties\": {" |  | 
|   24     "    \"string\": { \"type\": \"string\" }," |  | 
|   25     "    \"integer\": { \"type\": \"integer\" }," |  | 
|   26     "    \"boolean\": { \"type\": \"boolean\" }," |  | 
|   27     "    \"null\": { \"type\": \"null\" }," |  | 
|   28     "    \"double\": { \"type\": \"number\" }," |  | 
|   29     "    \"list\": {" |  | 
|   30     "      \"type\": \"array\"," |  | 
|   31     "      \"items\": { \"type\": \"string\" }" |  | 
|   32     "    }," |  | 
|   33     "    \"object\": {" |  | 
|   34     "      \"type\": \"object\"," |  | 
|   35     "      \"properties\": {" |  | 
|   36     "        \"a\": { \"type\": \"string\" }," |  | 
|   37     "        \"b\": { \"type\": \"integer\" }" |  | 
|   38     "      }" |  | 
|   39     "    }" |  | 
|   40     "  }" |  | 
|   41     "}"; |  | 
|   42  |  | 
|   43 }  // namespace |  | 
|   44  |  | 
|   45 class SchemaMapTest : public testing::Test { |  | 
|   46  protected: |  | 
|   47   Schema CreateTestSchema() { |  | 
|   48     std::string error; |  | 
|   49     Schema schema = Schema::Parse(kTestSchema, &error); |  | 
|   50     if (!schema.valid()) |  | 
|   51       ADD_FAILURE() << error; |  | 
|   52     return schema; |  | 
|   53   } |  | 
|   54  |  | 
|   55   scoped_refptr<SchemaMap> CreateTestMap() { |  | 
|   56     Schema schema = CreateTestSchema(); |  | 
|   57     ComponentMap component_map; |  | 
|   58     component_map["extension-1"] = schema; |  | 
|   59     component_map["extension-2"] = schema; |  | 
|   60     component_map["legacy-extension"] = Schema(); |  | 
|   61  |  | 
|   62     DomainMap domain_map; |  | 
|   63     domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map; |  | 
|   64  |  | 
|   65     return new SchemaMap(domain_map); |  | 
|   66   } |  | 
|   67 }; |  | 
|   68  |  | 
|   69 TEST_F(SchemaMapTest, Empty) { |  | 
|   70   scoped_refptr<SchemaMap> map = new SchemaMap(); |  | 
|   71   EXPECT_TRUE(map->GetDomains().empty()); |  | 
|   72   EXPECT_FALSE(map->GetComponents(POLICY_DOMAIN_CHROME)); |  | 
|   73   EXPECT_FALSE(map->GetComponents(POLICY_DOMAIN_EXTENSIONS)); |  | 
|   74   EXPECT_FALSE(map->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, ""))); |  | 
|   75   EXPECT_FALSE(map->HasComponents()); |  | 
|   76 } |  | 
|   77  |  | 
|   78 TEST_F(SchemaMapTest, HasComponents) { |  | 
|   79   scoped_refptr<SchemaMap> map = new SchemaMap(); |  | 
|   80   EXPECT_FALSE(map->HasComponents()); |  | 
|   81  |  | 
|   82   // The Chrome schema does not count as a component. |  | 
|   83   Schema schema = CreateTestSchema(); |  | 
|   84   ComponentMap component_map; |  | 
|   85   component_map[""] = schema; |  | 
|   86   DomainMap domain_map; |  | 
|   87   domain_map[POLICY_DOMAIN_CHROME] = component_map; |  | 
|   88   map = new SchemaMap(domain_map); |  | 
|   89   EXPECT_FALSE(map->HasComponents()); |  | 
|   90  |  | 
|   91   // An extension schema does. |  | 
|   92   domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map; |  | 
|   93   map = new SchemaMap(domain_map); |  | 
|   94   EXPECT_TRUE(map->HasComponents()); |  | 
|   95 } |  | 
|   96  |  | 
|   97 TEST_F(SchemaMapTest, Lookups) { |  | 
|   98   scoped_refptr<SchemaMap> map = CreateTestMap(); |  | 
|   99   ASSERT_TRUE(map); |  | 
|  100   EXPECT_TRUE(map->HasComponents()); |  | 
|  101  |  | 
|  102   EXPECT_FALSE(map->GetSchema( |  | 
|  103       PolicyNamespace(POLICY_DOMAIN_CHROME, ""))); |  | 
|  104   EXPECT_FALSE(map->GetSchema( |  | 
|  105       PolicyNamespace(POLICY_DOMAIN_CHROME, "extension-1"))); |  | 
|  106   EXPECT_FALSE(map->GetSchema( |  | 
|  107       PolicyNamespace(POLICY_DOMAIN_CHROME, "legacy-extension"))); |  | 
|  108   EXPECT_FALSE(map->GetSchema( |  | 
|  109       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, ""))); |  | 
|  110   EXPECT_FALSE(map->GetSchema( |  | 
|  111       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "extension-3"))); |  | 
|  112  |  | 
|  113   const Schema* schema = |  | 
|  114       map->GetSchema(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "extension-1")); |  | 
|  115   ASSERT_TRUE(schema); |  | 
|  116   EXPECT_TRUE(schema->valid()); |  | 
|  117  |  | 
|  118   schema = map->GetSchema( |  | 
|  119       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "legacy-extension")); |  | 
|  120   ASSERT_TRUE(schema); |  | 
|  121   EXPECT_FALSE(schema->valid()); |  | 
|  122 } |  | 
|  123  |  | 
|  124 TEST_F(SchemaMapTest, FilterBundle) { |  | 
|  125   std::string error; |  | 
|  126   Schema schema = Schema::Parse(kTestSchema, &error); |  | 
|  127   ASSERT_TRUE(schema.valid()) << error; |  | 
|  128  |  | 
|  129   DomainMap domain_map; |  | 
|  130   domain_map[POLICY_DOMAIN_EXTENSIONS]["abc"] = schema; |  | 
|  131   scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map); |  | 
|  132  |  | 
|  133   PolicyBundle bundle; |  | 
|  134   schema_map->FilterBundle(&bundle); |  | 
|  135   const PolicyBundle empty_bundle; |  | 
|  136   EXPECT_TRUE(bundle.Equals(empty_bundle)); |  | 
|  137  |  | 
|  138   // The Chrome namespace isn't filtered. |  | 
|  139   PolicyBundle expected_bundle; |  | 
|  140   PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, ""); |  | 
|  141   expected_bundle.Get(chrome_ns).Set("ChromePolicy", |  | 
|  142                                      POLICY_LEVEL_MANDATORY, |  | 
|  143                                      POLICY_SCOPE_USER, |  | 
|  144                                      base::Value::CreateStringValue("value"), |  | 
|  145                                      NULL); |  | 
|  146   bundle.CopyFrom(expected_bundle); |  | 
|  147  |  | 
|  148   // Unknown components are filtered out. |  | 
|  149   PolicyNamespace another_extension_ns(POLICY_DOMAIN_EXTENSIONS, "xyz"); |  | 
|  150   bundle.Get(another_extension_ns).Set( |  | 
|  151       "AnotherExtensionPolicy", |  | 
|  152       POLICY_LEVEL_MANDATORY, |  | 
|  153       POLICY_SCOPE_USER, |  | 
|  154       base::Value::CreateStringValue("value"), |  | 
|  155       NULL); |  | 
|  156   schema_map->FilterBundle(&bundle); |  | 
|  157   EXPECT_TRUE(bundle.Equals(expected_bundle)); |  | 
|  158  |  | 
|  159   PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "abc"); |  | 
|  160   PolicyMap& map = expected_bundle.Get(extension_ns); |  | 
|  161   base::ListValue list; |  | 
|  162   list.AppendString("a"); |  | 
|  163   list.AppendString("b"); |  | 
|  164   map.Set("list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  165           list.DeepCopy(), NULL); |  | 
|  166   map.Set("boolean", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  167           base::Value::CreateBooleanValue(true), NULL); |  | 
|  168   map.Set("integer", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  169           base::Value::CreateIntegerValue(1), NULL); |  | 
|  170   map.Set("null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  171           base::Value::CreateNullValue(), NULL); |  | 
|  172   map.Set("double", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  173           base::Value::CreateDoubleValue(1.2), NULL); |  | 
|  174   base::DictionaryValue dict; |  | 
|  175   dict.SetString("a", "b"); |  | 
|  176   dict.SetInteger("b", 2); |  | 
|  177   map.Set("object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  178           dict.DeepCopy(), NULL); |  | 
|  179   map.Set("string", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  180           base::Value::CreateStringValue("value"), NULL); |  | 
|  181  |  | 
|  182   bundle.MergeFrom(expected_bundle); |  | 
|  183   bundle.Get(extension_ns).Set("Unexpected", |  | 
|  184                                POLICY_LEVEL_MANDATORY, |  | 
|  185                                POLICY_SCOPE_USER, |  | 
|  186                                base::Value::CreateStringValue("to-be-removed"), |  | 
|  187                                NULL); |  | 
|  188  |  | 
|  189   schema_map->FilterBundle(&bundle); |  | 
|  190   EXPECT_TRUE(bundle.Equals(expected_bundle)); |  | 
|  191  |  | 
|  192   // Mismatched types are also removed. |  | 
|  193   bundle.Clear(); |  | 
|  194   PolicyMap& badmap = bundle.Get(extension_ns); |  | 
|  195   badmap.Set("list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  196              base::Value::CreateBooleanValue(false), NULL); |  | 
|  197   badmap.Set("boolean", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  198              base::Value::CreateIntegerValue(0), NULL); |  | 
|  199   badmap.Set("integer", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  200              base::Value::CreateBooleanValue(false), NULL); |  | 
|  201   badmap.Set("null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  202              base::Value::CreateBooleanValue(false), NULL); |  | 
|  203   badmap.Set("double", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  204              base::Value::CreateBooleanValue(false), NULL); |  | 
|  205   badmap.Set("object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  206              base::Value::CreateBooleanValue(false), NULL); |  | 
|  207   badmap.Set("string", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |  | 
|  208              NULL, |  | 
|  209              new ExternalDataFetcher(base::WeakPtr<ExternalDataManager>(), |  | 
|  210                                      std::string())); |  | 
|  211  |  | 
|  212   schema_map->FilterBundle(&bundle); |  | 
|  213   EXPECT_TRUE(bundle.Equals(empty_bundle)); |  | 
|  214 } |  | 
|  215  |  | 
|  216 TEST_F(SchemaMapTest, LegacyComponents) { |  | 
|  217   std::string error; |  | 
|  218   Schema schema = Schema::Parse( |  | 
|  219       "{" |  | 
|  220       "  \"type\":\"object\"," |  | 
|  221       "  \"properties\": {" |  | 
|  222       "    \"String\": { \"type\": \"string\" }" |  | 
|  223       "  }" |  | 
|  224       "}", &error); |  | 
|  225   ASSERT_TRUE(schema.valid()) << error; |  | 
|  226  |  | 
|  227   DomainMap domain_map; |  | 
|  228   domain_map[POLICY_DOMAIN_EXTENSIONS]["with-schema"] = schema; |  | 
|  229   domain_map[POLICY_DOMAIN_EXTENSIONS]["without-schema"] = Schema(); |  | 
|  230   scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map); |  | 
|  231  |  | 
|  232   // |bundle| contains policies loaded by a policy provider. |  | 
|  233   PolicyBundle bundle; |  | 
|  234  |  | 
|  235   // Known components with schemas are filtered. |  | 
|  236   PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "with-schema"); |  | 
|  237   bundle.Get(extension_ns).Set("String", |  | 
|  238                                POLICY_LEVEL_MANDATORY, |  | 
|  239                                POLICY_SCOPE_USER, |  | 
|  240                                base::Value::CreateStringValue("value 1"), |  | 
|  241                                NULL); |  | 
|  242  |  | 
|  243   // Known components without a schema are not filtered. |  | 
|  244   PolicyNamespace without_schema_ns(POLICY_DOMAIN_EXTENSIONS, "without-schema"); |  | 
|  245   bundle.Get(without_schema_ns).Set("Schemaless", |  | 
|  246                                     POLICY_LEVEL_MANDATORY, |  | 
|  247                                     POLICY_SCOPE_USER, |  | 
|  248                                     base::Value::CreateStringValue("value 2"), |  | 
|  249                                     NULL); |  | 
|  250  |  | 
|  251   // The Chrome namespace isn't filtered. |  | 
|  252   PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, ""); |  | 
|  253   bundle.Get(chrome_ns).Set("ChromePolicy", |  | 
|  254                             POLICY_LEVEL_MANDATORY, |  | 
|  255                             POLICY_SCOPE_USER, |  | 
|  256                             base::Value::CreateStringValue("value 3"), |  | 
|  257                             NULL); |  | 
|  258  |  | 
|  259   PolicyBundle expected_bundle; |  | 
|  260   expected_bundle.MergeFrom(bundle); |  | 
|  261  |  | 
|  262   // Unknown policies of known components with a schema are removed. |  | 
|  263   bundle.Get(extension_ns).Set("Surprise", |  | 
|  264                                POLICY_LEVEL_MANDATORY, |  | 
|  265                                POLICY_SCOPE_USER, |  | 
|  266                                base::Value::CreateStringValue("value 4"), |  | 
|  267                                NULL); |  | 
|  268  |  | 
|  269   // Unknown components are removed. |  | 
|  270   PolicyNamespace unknown_ns(POLICY_DOMAIN_EXTENSIONS, "unknown"); |  | 
|  271   bundle.Get(unknown_ns).Set("Surprise", |  | 
|  272                              POLICY_LEVEL_MANDATORY, |  | 
|  273                              POLICY_SCOPE_USER, |  | 
|  274                              base::Value::CreateStringValue("value 5"), |  | 
|  275                              NULL); |  | 
|  276  |  | 
|  277   schema_map->FilterBundle(&bundle); |  | 
|  278   EXPECT_TRUE(bundle.Equals(expected_bundle)); |  | 
|  279 } |  | 
|  280  |  | 
|  281 TEST_F(SchemaMapTest, GetChanges) { |  | 
|  282   DomainMap map; |  | 
|  283   map[POLICY_DOMAIN_CHROME][""] = Schema(); |  | 
|  284   scoped_refptr<SchemaMap> older = new SchemaMap(map); |  | 
|  285   map[POLICY_DOMAIN_CHROME][""] = Schema(); |  | 
|  286   scoped_refptr<SchemaMap> newer = new SchemaMap(map); |  | 
|  287  |  | 
|  288   PolicyNamespaceList removed; |  | 
|  289   PolicyNamespaceList added; |  | 
|  290   newer->GetChanges(older, &removed, &added); |  | 
|  291   EXPECT_TRUE(removed.empty()); |  | 
|  292   EXPECT_TRUE(added.empty()); |  | 
|  293  |  | 
|  294   map[POLICY_DOMAIN_CHROME][""] = Schema(); |  | 
|  295   map[POLICY_DOMAIN_EXTENSIONS]["xyz"] = Schema(); |  | 
|  296   newer = new SchemaMap(map); |  | 
|  297   newer->GetChanges(older, &removed, &added); |  | 
|  298   EXPECT_TRUE(removed.empty()); |  | 
|  299   ASSERT_EQ(1u, added.size()); |  | 
|  300   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), added[0]); |  | 
|  301  |  | 
|  302   older = newer; |  | 
|  303   map[POLICY_DOMAIN_EXTENSIONS]["abc"] = Schema(); |  | 
|  304   newer = new SchemaMap(map); |  | 
|  305   newer->GetChanges(older, &removed, &added); |  | 
|  306   ASSERT_EQ(2u, removed.size()); |  | 
|  307   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_CHROME, ""), removed[0]); |  | 
|  308   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), removed[1]); |  | 
|  309   ASSERT_EQ(1u, added.size()); |  | 
|  310   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"), added[0]); |  | 
|  311 } |  | 
|  312  |  | 
|  313 }  // namespace policy |  | 
| OLD | NEW |