Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: chrome/browser/policy/policy_loader_win_unittest.cc

Issue 10656046: Use a schema to decode 3rd party policy on windows, when present. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: More conversions, more tests, use additionalProperties, addressed comments Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/policy/policy_loader_win.h" 5 #include "chrome/browser/policy/policy_loader_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/string16.h" 10 #include "base/string16.h"
11 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
12 #include "base/string_util.h"
12 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
13 #include "base/win/registry.h" 14 #include "base/win/registry.h"
14 #include "chrome/browser/policy/async_policy_provider.h" 15 #include "chrome/browser/policy/async_policy_provider.h"
15 #include "chrome/browser/policy/configuration_policy_provider_test.h" 16 #include "chrome/browser/policy/configuration_policy_provider_test.h"
16 #include "chrome/browser/policy/policy_bundle.h" 17 #include "chrome/browser/policy/policy_bundle.h"
17 #include "chrome/browser/policy/policy_map.h" 18 #include "chrome/browser/policy/policy_map.h"
18 #include "policy/policy_constants.h" 19 #include "policy/policy_constants.h"
19 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
20 21
21 using base::win::RegKey; 22 using base::win::RegKey;
22 23
23 namespace policy { 24 namespace policy {
24 25
25 namespace { 26 namespace {
26 27
27 const wchar_t kUnitTestRegistrySubKey[] = L"SOFTWARE\\Chromium Unit Tests"; 28 const wchar_t kUnitTestRegistrySubKey[] = L"SOFTWARE\\Chromium Unit Tests";
28 const wchar_t kUnitTestMachineOverrideSubKey[] = 29 const wchar_t kUnitTestMachineOverrideSubKey[] =
29 L"SOFTWARE\\Chromium Unit Tests\\HKLM Override"; 30 L"SOFTWARE\\Chromium Unit Tests\\HKLM Override";
30 const wchar_t kUnitTestUserOverrideSubKey[] = 31 const wchar_t kUnitTestUserOverrideSubKey[] =
31 L"SOFTWARE\\Chromium Unit Tests\\HKCU Override"; 32 L"SOFTWARE\\Chromium Unit Tests\\HKCU Override";
32 33
33 // Installs |dict| at the given |path|, in the given |hive|. Currently only 34 const wchar_t kPathSep[] = L"\\";
34 // string, int and dictionary types are converted; other types cause a failure. 35
35 // Returns false if there was any failure, and true if |dict| was successfully 36 // Registry key where 3rd party policy is stored.
36 // written. 37 const wchar_t kThirdParty[] = L"3rdparty";
37 // TODO(joaodasilva): generate a schema for |dict| too, so that all types can 38
38 // be retrieved. 39 // Keys for mandatory and recommended policy and schema under the registry key
39 bool InstallDictionary(const base::DictionaryValue& dict, 40 // for a component.
40 HKEY hive, 41 const wchar_t kMandatory[] = L"policy";
41 const string16& path) { 42 const wchar_t kRecommended[] = L"recommended";
43 const wchar_t kSchema[] = L"schema";
44
45 // JSON-schema key that indicates an entry's type.
46 const char kType[] = "type";
47 // JSON-schema key that indicates an object entry's properties.
48 const char kProperties[] = "properties";
49 // JSON-schema key that indicates an object entry's default schema.
50 const char kAdditionalProperties[] = "additionalProperties";
51 // JSON-schema key that indicates the schema for the items of an array entry.
52 const char kItems[] = "items";
Mattias Nissler (ping if slow) 2012/06/27 14:52:10 nit: You could convert these to static members in
Joao da Silva 2012/06/27 16:55:28 I've added them to a namespace within ::policy, so
Mattias Nissler (ping if slow) 2012/06/28 10:00:28 I think that's a fair solution. I'm not sure wheth
53
54 // Installs |value| in the given registry |path| and |hive|, under the key
55 // |name|. Returns false on errors.
56 // Some of the possible Value types are stored after a conversion (e.g. doubles
57 // are stored as strings), and can only be retrieved if a corresponding schema
58 // is written.
59 bool InstallValue(const base::Value& value,
60 HKEY hive,
61 const string16& path,
62 const string16& name) {
42 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet. 63 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet.
43 RegKey key(hive, path.c_str(), KEY_ALL_ACCESS); 64 RegKey key(hive, path.c_str(), KEY_ALL_ACCESS);
44 const string16 kPathSep = ASCIIToUTF16("\\"); 65 switch (value.GetType()) {
66 case base::Value::TYPE_NULL:
67 return key.WriteValue(name.c_str(), L"") == ERROR_SUCCESS;
45 68
46 for (base::DictionaryValue::Iterator it(dict); it.HasNext(); it.Advance()) { 69 case base::Value::TYPE_BOOLEAN: {
47 string16 name(UTF8ToUTF16(it.key())); 70 bool bool_value;
48 switch (it.value().GetType()) { 71 if (!value.GetAsBoolean(&bool_value))
49 case base::Value::TYPE_STRING: { 72 return false;
50 string16 value; 73 return key.WriteValue(name.c_str(), bool_value ? 1 : 0) == ERROR_SUCCESS;
51 if (!it.value().GetAsString(&value)) 74 }
75
76 case base::Value::TYPE_INTEGER: {
77 int int_value;
78 if (!value.GetAsInteger(&int_value))
79 return false;
80 return key.WriteValue(name.c_str(), int_value) == ERROR_SUCCESS;
81 }
82
83 case base::Value::TYPE_DOUBLE: {
84 double double_value;
85 if (!value.GetAsDouble(&double_value))
86 return false;
87 string16 str_value = UTF8ToUTF16(base::DoubleToString(double_value));
88 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
89 }
90
91 case base::Value::TYPE_STRING: {
92 string16 str_value;
93 if (!value.GetAsString(&str_value))
94 return false;
95 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
96 }
97
98 case base::Value::TYPE_DICTIONARY: {
99 const base::DictionaryValue* sub_dict = NULL;
100 if (!value.GetAsDictionary(&sub_dict))
101 return false;
102 for (base::DictionaryValue::Iterator it(*sub_dict);
103 it.HasNext(); it.Advance()) {
104 if (!InstallValue(it.value(), hive, path + kPathSep + name,
105 UTF8ToUTF16(it.key()))) {
52 return false; 106 return false;
53 if (key.WriteValue(name.c_str(), value.c_str()) != ERROR_SUCCESS) 107 }
108 }
109 return true;
110 }
111
112 case base::Value::TYPE_LIST: {
113 const base::ListValue* list = NULL;
114 if (!value.GetAsList(&list))
115 return false;
116 for (size_t i = 0; i < list->GetSize(); ++i) {
117 base::Value* item;
118 if (!list->Get(i, &item))
54 return false; 119 return false;
55 break; 120 if (!InstallValue(*item, hive, path + kPathSep + name,
121 base::UintToString16(i + 1))) {
122 return false;
123 }
56 } 124 }
125 return true;
126 }
57 127
58 case base::Value::TYPE_INTEGER: { 128 case base::Value::TYPE_BINARY:
59 int value; 129 return false;
60 if (!it.value().GetAsInteger(&value)) 130 }
61 return false; 131 NOTREACHED();
62 if (key.WriteValue(name.c_str(), value) != ERROR_SUCCESS) 132 return false;
63 return false; 133 }
64 break; 134
135 // Builds a JSON schema that represents the types contained in |value|.
136 // Ownership is transferred to the caller.
137 base::DictionaryValue* BuildSchema(const base::Value& value) {
138 base::DictionaryValue* schema = new base::DictionaryValue();
139 switch (value.GetType()) {
140 case base::Value::TYPE_NULL:
141 schema->SetString(kType, "null");
142 break;
143 case base::Value::TYPE_BOOLEAN:
144 schema->SetString(kType, "boolean");
145 break;
146 case base::Value::TYPE_INTEGER:
147 schema->SetString(kType, "integer");
148 break;
149 case base::Value::TYPE_DOUBLE:
150 schema->SetString(kType, "number");
151 break;
152 case base::Value::TYPE_STRING:
153 schema->SetString(kType, "string");
154 break;
155
156 case base::Value::TYPE_LIST: {
157 // Assumes every list element has the same type.
158 const base::ListValue* list = NULL;
159 if (value.GetAsList(&list) && !list->empty()) {
160 schema->SetString(kType, "array");
161 schema->Set(kItems, BuildSchema(**list->begin()));
65 } 162 }
163 break;
164 }
66 165
67 case base::Value::TYPE_DICTIONARY: { 166 case base::Value::TYPE_DICTIONARY: {
68 const base::DictionaryValue* sub_dict = NULL; 167 const base::DictionaryValue* dict = NULL;
69 if (!it.value().GetAsDictionary(&sub_dict)) 168 if (value.GetAsDictionary(&dict)) {
70 return false; 169 base::DictionaryValue* properties = new base::DictionaryValue();
71 if (!InstallDictionary(*sub_dict, hive, path + kPathSep + name)) 170 for (base::DictionaryValue::Iterator it(*dict);
72 return false; 171 it.HasNext(); it.Advance()) {
73 break; 172 properties->Set(it.key(), BuildSchema(it.value()));
173 }
174 schema->SetString(kType, "object");
175 schema->Set(kProperties, properties);
74 } 176 }
177 break;
178 }
75 179
76 default: 180 case base::Value::TYPE_BINARY:
77 return false; 181 break;
78 }
79 } 182 }
80 return true; 183 return schema;
184 }
185
186 // Writes a JSON |schema| at the registry entry |name| at |path|
187 // in the given |hive|. Returns false on failure.
188 bool WriteSchema(const base::DictionaryValue& schema,
189 HKEY hive,
190 const string16& path,
191 const string16& name) {
192 std::string encoded;
193 base::JSONWriter::Write(&schema, &encoded);
194 if (encoded.empty())
195 return false;
196 string16 encoded16 = UTF8ToUTF16(encoded);
197 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet.
198 RegKey key(hive, path.c_str(), KEY_ALL_ACCESS);
199 return key.WriteValue(name.c_str(), encoded16.c_str()) == ERROR_SUCCESS;
200 }
201
202 // Builds a JSON schema for |value| and writes it at the registry entry |name|
203 // at |path| in the given |hive|. Returns false on failure.
204 bool InstallSchema(const base::Value& value,
205 HKEY hive,
206 const string16& path,
207 const string16& name) {
208 scoped_ptr<base::DictionaryValue> schema_dict(BuildSchema(value));
209 return WriteSchema(*schema_dict, hive, path, name);
81 } 210 }
82 211
83 // This class provides sandboxing and mocking for the parts of the Windows 212 // This class provides sandboxing and mocking for the parts of the Windows
84 // Registry implementing Group Policy. It prepares two temporary sandbox keys 213 // Registry implementing Group Policy. It prepares two temporary sandbox keys
85 // in |kUnitTestRegistrySubKey|, one for HKLM and one for HKCU. A test's calls 214 // in |kUnitTestRegistrySubKey|, one for HKLM and one for HKCU. A test's calls
86 // to the registry are redirected by Windows to these sandboxes, allowing the 215 // to the registry are redirected by Windows to these sandboxes, allowing the
87 // tests to manipulate and access policy as if it were active, but without 216 // tests to manipulate and access policy as if it were active, but without
88 // actually changing the parts of the Registry that are managed by Group 217 // actually changing the parts of the Registry that are managed by Group
89 // Policy. 218 // Policy.
90 class ScopedGroupPolicyRegistrySandbox { 219 class ScopedGroupPolicyRegistrySandbox {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 virtual void InstallIntegerPolicy(const std::string& policy_name, 252 virtual void InstallIntegerPolicy(const std::string& policy_name,
124 int policy_value) OVERRIDE; 253 int policy_value) OVERRIDE;
125 virtual void InstallBooleanPolicy(const std::string& policy_name, 254 virtual void InstallBooleanPolicy(const std::string& policy_name,
126 bool policy_value) OVERRIDE; 255 bool policy_value) OVERRIDE;
127 virtual void InstallStringListPolicy( 256 virtual void InstallStringListPolicy(
128 const std::string& policy_name, 257 const std::string& policy_name,
129 const base::ListValue* policy_value) OVERRIDE; 258 const base::ListValue* policy_value) OVERRIDE;
130 virtual void InstallDictionaryPolicy( 259 virtual void InstallDictionaryPolicy(
131 const std::string& policy_name, 260 const std::string& policy_name,
132 const base::DictionaryValue* policy_value) OVERRIDE; 261 const base::DictionaryValue* policy_value) OVERRIDE;
262 virtual void Install3rdPartyPolicy(
263 const base::DictionaryValue* policies) OVERRIDE;
133 264
134 // Creates a harness instance that will install policy in HKCU or HKLM, 265 // Creates a harness instance that will install policy in HKCU or HKLM,
135 // respectively. 266 // respectively.
136 static PolicyProviderTestHarness* CreateHKCU(); 267 static PolicyProviderTestHarness* CreateHKCU();
137 static PolicyProviderTestHarness* CreateHKLM(); 268 static PolicyProviderTestHarness* CreateHKLM();
138 269
139 private: 270 private:
140 HKEY hive_; 271 HKEY hive_;
141 272
142 ScopedGroupPolicyRegistrySandbox registry_sandbox_; 273 ScopedGroupPolicyRegistrySandbox registry_sandbox_;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 void TestHarness::InstallDictionaryPolicy( 371 void TestHarness::InstallDictionaryPolicy(
241 const std::string& policy_name, 372 const std::string& policy_name,
242 const base::DictionaryValue* policy_value) { 373 const base::DictionaryValue* policy_value) {
243 std::string json; 374 std::string json;
244 base::JSONWriter::Write(policy_value, &json); 375 base::JSONWriter::Write(policy_value, &json);
245 RegKey key(hive_, kRegistryMandatorySubKey, KEY_ALL_ACCESS); 376 RegKey key(hive_, kRegistryMandatorySubKey, KEY_ALL_ACCESS);
246 key.WriteValue(UTF8ToUTF16(policy_name).c_str(), 377 key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
247 UTF8ToUTF16(json).c_str()); 378 UTF8ToUTF16(json).c_str());
248 } 379 }
249 380
381 void TestHarness::Install3rdPartyPolicy(const base::DictionaryValue* policies) {
382 // The first level entries are domains, and the second level entries map
383 // components to their policy.
384 const string16 kPathPrefix = string16(kRegistryMandatorySubKey) + kPathSep +
385 kThirdParty + kPathSep;
386 for (base::DictionaryValue::Iterator domain(*policies);
387 domain.HasNext(); domain.Advance()) {
388 const base::DictionaryValue* components = NULL;
389 if (!domain.value().GetAsDictionary(&components)) {
390 ADD_FAILURE();
391 continue;
392 }
393 for (base::DictionaryValue::Iterator component(*components);
394 component.HasNext(); component.Advance()) {
395 const string16 path = string16(kRegistryMandatorySubKey) + kPathSep +
396 kThirdParty + kPathSep +
397 UTF8ToUTF16(domain.key()) + kPathSep +
398 UTF8ToUTF16(component.key());
399 InstallValue(component.value(), hive_, path, kMandatory);
400 EXPECT_TRUE(InstallSchema(component.value(), hive_, path, kSchema));
401 }
402 }
403 }
404
250 // static 405 // static
251 PolicyProviderTestHarness* TestHarness::CreateHKCU() { 406 PolicyProviderTestHarness* TestHarness::CreateHKCU() {
252 return new TestHarness(HKEY_CURRENT_USER, POLICY_SCOPE_USER); 407 return new TestHarness(HKEY_CURRENT_USER, POLICY_SCOPE_USER);
253 } 408 }
254 409
255 // static 410 // static
256 PolicyProviderTestHarness* TestHarness::CreateHKLM() { 411 PolicyProviderTestHarness* TestHarness::CreateHKLM() {
257 return new TestHarness(HKEY_LOCAL_MACHINE, POLICY_SCOPE_MACHINE); 412 return new TestHarness(HKEY_LOCAL_MACHINE, POLICY_SCOPE_MACHINE);
258 } 413 }
259 414
260 } // namespace 415 } // namespace
261 416
262 // Instantiate abstract test case for basic policy reading tests. 417 // Instantiate abstract test case for basic policy reading tests.
263 INSTANTIATE_TEST_CASE_P( 418 INSTANTIATE_TEST_CASE_P(
264 PolicyProviderWinTest, 419 PolicyProviderWinTest,
265 ConfigurationPolicyProviderTest, 420 ConfigurationPolicyProviderTest,
266 testing::Values(TestHarness::CreateHKCU, TestHarness::CreateHKLM)); 421 testing::Values(TestHarness::CreateHKCU, TestHarness::CreateHKLM));
267 422
423 // Instantiate abstract test case for 3rd party policy reading tests.
424 INSTANTIATE_TEST_CASE_P(
425 ThirdPartyPolicyProviderWinTest,
426 Configuration3rdPartyPolicyProviderTest,
427 testing::Values(TestHarness::CreateHKCU, TestHarness::CreateHKLM));
428
268 // Test cases for windows policy provider specific functionality. 429 // Test cases for windows policy provider specific functionality.
269 class PolicyLoaderWinTest : public PolicyTestBase { 430 class PolicyLoaderWinTest : public PolicyTestBase {
270 protected: 431 protected:
271 PolicyLoaderWinTest() {} 432 PolicyLoaderWinTest() {}
272 virtual ~PolicyLoaderWinTest() {} 433 virtual ~PolicyLoaderWinTest() {}
273 434
435 bool Matches(const PolicyBundle& expected) {
436 PolicyLoaderWin loader(&test_policy_definitions::kList);
437 scoped_ptr<PolicyBundle> loaded(loader.Load());
438 return loaded->Equals(expected);
439 }
440
274 ScopedGroupPolicyRegistrySandbox registry_sandbox_; 441 ScopedGroupPolicyRegistrySandbox registry_sandbox_;
275 }; 442 };
276 443
277 TEST_F(PolicyLoaderWinTest, HKLMOverHKCU) { 444 TEST_F(PolicyLoaderWinTest, HKLMOverHKCU) {
278 RegKey hklm_key(HKEY_LOCAL_MACHINE, kRegistryMandatorySubKey, KEY_ALL_ACCESS); 445 RegKey hklm_key(HKEY_LOCAL_MACHINE, kRegistryMandatorySubKey, KEY_ALL_ACCESS);
279 hklm_key.WriteValue(UTF8ToUTF16(test_policy_definitions::kKeyString).c_str(), 446 hklm_key.WriteValue(UTF8ToUTF16(test_policy_definitions::kKeyString).c_str(),
280 UTF8ToUTF16("hklm").c_str()); 447 UTF8ToUTF16("hklm").c_str());
281 RegKey hkcu_key(HKEY_CURRENT_USER, kRegistryMandatorySubKey, KEY_ALL_ACCESS); 448 RegKey hkcu_key(HKEY_CURRENT_USER, kRegistryMandatorySubKey, KEY_ALL_ACCESS);
282 hkcu_key.WriteValue(UTF8ToUTF16(test_policy_definitions::kKeyString).c_str(), 449 hkcu_key.WriteValue(UTF8ToUTF16(test_policy_definitions::kKeyString).c_str(),
283 UTF8ToUTF16("hkcu").c_str()); 450 UTF8ToUTF16("hkcu").c_str());
284 451
285 PolicyLoaderWin loader(&test_policy_definitions::kList); 452 PolicyBundle expected;
286 scoped_ptr<PolicyBundle> bundle(loader.Load()); 453 expected.Get(POLICY_DOMAIN_CHROME, "")
287
288 PolicyBundle expected_bundle;
289 expected_bundle.Get(POLICY_DOMAIN_CHROME, "")
290 .Set(test_policy_definitions::kKeyString, 454 .Set(test_policy_definitions::kKeyString,
291 POLICY_LEVEL_MANDATORY, 455 POLICY_LEVEL_MANDATORY,
292 POLICY_SCOPE_MACHINE, 456 POLICY_SCOPE_MACHINE,
293 base::Value::CreateStringValue("hklm")); 457 base::Value::CreateStringValue("hklm"));
294 EXPECT_TRUE(bundle->Equals(expected_bundle)); 458 EXPECT_TRUE(Matches(expected));
295 } 459 }
296 460
297 // TODO(joaodasilva): share tests for 3rd party policy with 461 TEST_F(PolicyLoaderWinTest, Load3rdPartyWithoutSchema) {
298 // ConfigDirPolicyProvider once PolicyLoaderWin is able to load all types.
299 TEST_F(PolicyLoaderWinTest, Load3rdParty) {
300 base::DictionaryValue dict; 462 base::DictionaryValue dict;
301 dict.SetString("str", "string value"); 463 dict.SetString("str", "string value");
302 dict.SetInteger("int", 123); 464 dict.SetInteger("int", 123);
303 dict.Set("subdict", dict.DeepCopy()); 465 dict.Set("subdict", dict.DeepCopy());
304 dict.Set("subsubdict", dict.DeepCopy()); 466 dict.Set("subsubdict", dict.DeepCopy());
305 dict.Set("subsubsubdict", dict.DeepCopy()); 467 dict.Set("subsubsubdict", dict.DeepCopy());
306 468
307 base::DictionaryValue policy_dict; 469 base::DictionaryValue policy_dict;
308 policy_dict.Set("3rdparty.extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.policy", 470 policy_dict.Set("extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.policy",
309 dict.DeepCopy()); 471 dict.DeepCopy());
310 policy_dict.Set("3rdparty.extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.policy", 472 policy_dict.Set("extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.policy",
311 dict.DeepCopy()); 473 dict.DeepCopy());
312 EXPECT_TRUE(InstallDictionary(policy_dict, HKEY_LOCAL_MACHINE, 474 EXPECT_TRUE(InstallValue(policy_dict, HKEY_LOCAL_MACHINE,
313 kRegistryMandatorySubKey)); 475 kRegistryMandatorySubKey, kThirdParty));
314 476
315 PolicyBundle expected; 477 PolicyBundle expected;
316 expected.Get(POLICY_DOMAIN_EXTENSIONS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") 478 expected.Get(POLICY_DOMAIN_EXTENSIONS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
317 .LoadFrom(&dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE); 479 .LoadFrom(&dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE);
318 expected.Get(POLICY_DOMAIN_EXTENSIONS, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") 480 expected.Get(POLICY_DOMAIN_EXTENSIONS, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
319 .LoadFrom(&dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE); 481 .LoadFrom(&dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE);
320 482 EXPECT_TRUE(Matches(expected));
321 PolicyLoaderWin loader(&test_policy_definitions::kList);
322 scoped_ptr<PolicyBundle> loaded(loader.Load());
323 EXPECT_TRUE(loaded->Equals(expected));
324 } 483 }
325 484
326 TEST_F(PolicyLoaderWinTest, Merge3rdPartyPolicies) { 485 TEST_F(PolicyLoaderWinTest, Merge3rdPartyPolicies) {
327 // Policy for the same extension will be provided at the 4 level/scope 486 // Policy for the same extension will be provided at the 4 level/scope
328 // combinations, to verify that they overlap as expected. 487 // combinations, to verify that they overlap as expected.
329 488
330 const string16 kPathSuffix = 489 const string16 kPathSuffix =
331 kRegistryMandatorySubKey + ASCIIToUTF16("\\3rdparty\\extensions\\merge"); 490 kRegistryMandatorySubKey + ASCIIToUTF16("\\3rdparty\\extensions\\merge");
332 const string16 kMandatoryPath = kPathSuffix + ASCIIToUTF16("\\policy");
333 const string16 kRecommendedPath = kPathSuffix + ASCIIToUTF16("\\recommended");
334 491
335 const char kUserMandatory[] = "user-mandatory"; 492 const char kUserMandatory[] = "user-mandatory";
336 const char kUserRecommended[] = "user-recommended"; 493 const char kUserRecommended[] = "user-recommended";
337 const char kMachineMandatory[] = "machine-mandatory"; 494 const char kMachineMandatory[] = "machine-mandatory";
338 const char kMachineRecommended[] = "machine-recommended"; 495 const char kMachineRecommended[] = "machine-recommended";
339 496
340 base::DictionaryValue policy; 497 base::DictionaryValue policy;
341 policy.SetString("a", kMachineMandatory); 498 policy.SetString("a", kMachineMandatory);
342 EXPECT_TRUE(InstallDictionary(policy, HKEY_LOCAL_MACHINE, kMandatoryPath)); 499 EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE,
500 kPathSuffix, kMandatory));
343 policy.SetString("a", kUserMandatory); 501 policy.SetString("a", kUserMandatory);
344 policy.SetString("b", kUserMandatory); 502 policy.SetString("b", kUserMandatory);
345 EXPECT_TRUE(InstallDictionary(policy, HKEY_CURRENT_USER, kMandatoryPath)); 503 EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER,
504 kPathSuffix, kMandatory));
346 policy.SetString("a", kMachineRecommended); 505 policy.SetString("a", kMachineRecommended);
347 policy.SetString("b", kMachineRecommended); 506 policy.SetString("b", kMachineRecommended);
348 policy.SetString("c", kMachineRecommended); 507 policy.SetString("c", kMachineRecommended);
349 EXPECT_TRUE(InstallDictionary(policy, HKEY_LOCAL_MACHINE, kRecommendedPath)); 508 EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE,
509 kPathSuffix, kRecommended));
350 policy.SetString("a", kUserRecommended); 510 policy.SetString("a", kUserRecommended);
351 policy.SetString("b", kUserRecommended); 511 policy.SetString("b", kUserRecommended);
352 policy.SetString("c", kUserRecommended); 512 policy.SetString("c", kUserRecommended);
353 policy.SetString("d", kUserRecommended); 513 policy.SetString("d", kUserRecommended);
354 EXPECT_TRUE(InstallDictionary(policy, HKEY_CURRENT_USER, kRecommendedPath)); 514 EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER,
515 kPathSuffix, kRecommended));
355 516
356 PolicyBundle expected; 517 PolicyBundle expected;
357 PolicyMap& expected_policy = expected.Get(POLICY_DOMAIN_EXTENSIONS, "merge"); 518 PolicyMap& expected_policy = expected.Get(POLICY_DOMAIN_EXTENSIONS, "merge");
358 expected_policy.Set("a", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, 519 expected_policy.Set("a", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
359 base::Value::CreateStringValue(kMachineMandatory)); 520 base::Value::CreateStringValue(kMachineMandatory));
360 expected_policy.Set("b", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 521 expected_policy.Set("b", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
361 base::Value::CreateStringValue(kUserMandatory)); 522 base::Value::CreateStringValue(kUserMandatory));
362 expected_policy.Set("c", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, 523 expected_policy.Set("c", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
363 base::Value::CreateStringValue(kMachineRecommended)); 524 base::Value::CreateStringValue(kMachineRecommended));
364 expected_policy.Set("d", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, 525 expected_policy.Set("d", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
365 base::Value::CreateStringValue(kUserRecommended)); 526 base::Value::CreateStringValue(kUserRecommended));
527 EXPECT_TRUE(Matches(expected));
528 }
366 529
367 PolicyLoaderWin loader(&test_policy_definitions::kList); 530 TEST_F(PolicyLoaderWinTest, LoadStringEncodedValues) {
368 scoped_ptr<PolicyBundle> loaded(loader.Load()); 531 // Create a dictionary with all the types that can be stored encoded in a
369 EXPECT_TRUE(loaded->Equals(expected)); 532 // string, to pass to InstallSchema(). Also build an equivalent dictionary
533 // with the encoded values, to pass to InstallValue().
534 base::DictionaryValue policy;
535 policy.Set("null", base::Value::CreateNullValue());
536 policy.SetBoolean("bool", true);
537 policy.SetInteger("int", -123);
538 policy.SetDouble("double", 456.78e9);
539 base::ListValue list;
540 list.Append(policy.DeepCopy());
541 list.Append(policy.DeepCopy());
542 policy.Set("list", list.DeepCopy());
543 // Encode |policy| before adding the "dict" entry.
544 std::string encoded_dict;
545 base::JSONWriter::Write(&policy, &encoded_dict);
546 ASSERT_FALSE(encoded_dict.empty());
547 policy.Set("dict", policy.DeepCopy());
548
549 std::string encoded_list;
550 base::JSONWriter::Write(&list, &encoded_list);
551 ASSERT_FALSE(encoded_list.empty());
552 base::DictionaryValue encoded_policy;
553 encoded_policy.SetString("null", "");
554 encoded_policy.SetString("bool", "1");
555 encoded_policy.SetString("int", "-123");
556 encoded_policy.SetString("double", "456.78e9");
557 encoded_policy.SetString("list", encoded_list);
558 encoded_policy.SetString("dict", encoded_dict);
559
560 const string16 kPathSuffix =
561 kRegistryMandatorySubKey + ASCIIToUTF16("\\3rdparty\\extensions\\string");
562 EXPECT_TRUE(InstallSchema(policy, HKEY_CURRENT_USER, kPathSuffix, kSchema));
563 EXPECT_TRUE(
564 InstallValue(encoded_policy, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
565
566 PolicyBundle expected;
567 expected.Get(POLICY_DOMAIN_EXTENSIONS, "string")
568 .LoadFrom(&policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
569 EXPECT_TRUE(Matches(expected));
570 }
571
572 TEST_F(PolicyLoaderWinTest, LoadIntegerEncodedValues) {
573 base::DictionaryValue policy;
574 policy.SetBoolean("bool", true);
575 policy.SetInteger("int", 123);
576 policy.SetDouble("double", 456.0);
577
578 base::DictionaryValue encoded_policy;
579 encoded_policy.SetInteger("bool", 1);
580 encoded_policy.SetInteger("int", 123);
581 encoded_policy.SetInteger("double", 456);
582
583 const string16 kPathSuffix =
584 kRegistryMandatorySubKey + ASCIIToUTF16("\\3rdparty\\extensions\\int");
585 EXPECT_TRUE(InstallSchema(policy, HKEY_CURRENT_USER, kPathSuffix, kSchema));
586 EXPECT_TRUE(
587 InstallValue(encoded_policy, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
588
589 PolicyBundle expected;
590 expected.Get(POLICY_DOMAIN_EXTENSIONS, "int")
591 .LoadFrom(&policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
592 EXPECT_TRUE(Matches(expected));
593 }
594
595 TEST_F(PolicyLoaderWinTest, DefaultPropertySchemaType) {
596 // Build a schema for an "object" with a default schema for its properties.
597 base::DictionaryValue default_schema;
598 default_schema.SetString(kType, "number");
599 base::DictionaryValue integer_schema;
600 integer_schema.SetString(kType, "integer");
601 base::DictionaryValue properties;
602 properties.Set("special-int1", integer_schema.DeepCopy());
603 properties.Set("special-int2", integer_schema.DeepCopy());
604 base::DictionaryValue schema;
605 schema.SetString(kType, "object");
606 schema.Set(kProperties, properties.DeepCopy());
607 schema.Set(kAdditionalProperties, default_schema.DeepCopy());
608
609 const string16 kPathSuffix =
610 kRegistryMandatorySubKey + ASCIIToUTF16("\\3rdparty\\extensions\\test");
611 EXPECT_TRUE(WriteSchema(schema, HKEY_CURRENT_USER, kPathSuffix, kSchema));
612
613 // Write some test values.
614 base::DictionaryValue policy;
615 // These special values have a specific schema for them.
616 policy.SetInteger("special-int1", 123);
617 policy.SetString("special-int2", "-456");
618 // Other values default to be loaded as doubles.
619 policy.SetInteger("double1", 789.0);
620 policy.SetString("double2", "123.456e7");
621 policy.SetString("invalid", "omg");
622 EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
623
624 base::DictionaryValue expected_policy;
625 expected_policy.SetInteger("special-int1", 123);
626 expected_policy.SetInteger("special-int2", -456);
627 expected_policy.SetDouble("double1", 789.0);
628 expected_policy.SetDouble("double2", 123.456e7);
629 PolicyBundle expected;
630 expected.Get(POLICY_DOMAIN_EXTENSIONS, "test")
631 .LoadFrom(&expected_policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
632 EXPECT_TRUE(Matches(expected));
370 } 633 }
371 634
372 } // namespace policy 635 } // namespace policy
OLDNEW
« chrome/browser/policy/policy_loader_win.cc ('K') | « chrome/browser/policy/policy_loader_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698