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

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