| 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 |