Ignore title parameter for navigator.registerProtocolHandler
[chromium-blink-merge.git] / components / policy / core / common / policy_loader_win_unittest.cc
blob7ddc783af700c429a13388d6dd43c0695a7e0b8a
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
3 // found in the LICENSE file.
5 #include "components/policy/core/common/policy_loader_win.h"
7 #include <windows.h>
8 #include <userenv.h>
10 #include <algorithm>
11 #include <cstring>
12 #include <functional>
13 #include <iterator>
14 #include <vector>
16 #include "base/base_paths.h"
17 #include "base/callback.h"
18 #include "base/file_util.h"
19 #include "base/files/file_path.h"
20 #include "base/files/scoped_temp_dir.h"
21 #include "base/json/json_writer.h"
22 #include "base/path_service.h"
23 #include "base/process/process.h"
24 #include "base/strings/string16.h"
25 #include "base/strings/string_number_conversions.h"
26 #include "base/strings/string_util.h"
27 #include "base/strings/stringprintf.h"
28 #include "base/strings/utf_string_conversions.h"
29 #include "base/sys_byteorder.h"
30 #include "base/win/registry.h"
31 #include "base/win/win_util.h"
32 #include "components/policy/core/common/async_policy_provider.h"
33 #include "components/policy/core/common/configuration_policy_provider_test.h"
34 #include "components/policy/core/common/external_data_fetcher.h"
35 #include "components/policy/core/common/policy_bundle.h"
36 #include "components/policy/core/common/policy_map.h"
37 #include "components/policy/core/common/preg_parser_win.h"
38 #include "components/policy/core/common/schema_map.h"
39 #include "testing/gtest/include/gtest/gtest.h"
41 using base::UTF8ToUTF16;
42 using base::UTF16ToUTF8;
43 using base::win::RegKey;
45 namespace policy {
47 namespace {
49 // Constants for registry key names.
50 const wchar_t kPathSep[] = L"\\";
51 const wchar_t kThirdParty[] = L"3rdparty";
52 const wchar_t kMandatory[] = L"policy";
53 const wchar_t kRecommended[] = L"recommended";
54 const char kSchema[] = "schema";
55 const wchar_t kTestPolicyKey[] = L"chrome.policy.key";
57 // Installs |value| in the given registry |path| and |hive|, under the key
58 // |name|. Returns false on errors.
59 // Some of the possible Value types are stored after a conversion (e.g. doubles
60 // are stored as strings), and can only be retrieved if a corresponding schema
61 // is written.
62 bool InstallValue(const base::Value& value,
63 HKEY hive,
64 const base::string16& path,
65 const base::string16& name) {
66 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet.
67 RegKey key(hive, path.c_str(), KEY_ALL_ACCESS);
68 EXPECT_TRUE(key.Valid());
69 switch (value.GetType()) {
70 case base::Value::TYPE_NULL:
71 return key.WriteValue(name.c_str(), L"") == ERROR_SUCCESS;
73 case base::Value::TYPE_BOOLEAN: {
74 bool bool_value;
75 if (!value.GetAsBoolean(&bool_value))
76 return false;
77 return key.WriteValue(name.c_str(), bool_value ? 1 : 0) == ERROR_SUCCESS;
80 case base::Value::TYPE_INTEGER: {
81 int int_value;
82 if (!value.GetAsInteger(&int_value))
83 return false;
84 return key.WriteValue(name.c_str(), int_value) == ERROR_SUCCESS;
87 case base::Value::TYPE_DOUBLE: {
88 double double_value;
89 if (!value.GetAsDouble(&double_value))
90 return false;
91 base::string16 str_value =
92 UTF8ToUTF16(base::DoubleToString(double_value));
93 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
96 case base::Value::TYPE_STRING: {
97 base::string16 str_value;
98 if (!value.GetAsString(&str_value))
99 return false;
100 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
103 case base::Value::TYPE_DICTIONARY: {
104 const base::DictionaryValue* sub_dict = NULL;
105 if (!value.GetAsDictionary(&sub_dict))
106 return false;
107 for (base::DictionaryValue::Iterator it(*sub_dict);
108 !it.IsAtEnd(); it.Advance()) {
109 if (!InstallValue(it.value(), hive, path + kPathSep + name,
110 UTF8ToUTF16(it.key()))) {
111 return false;
114 return true;
117 case base::Value::TYPE_LIST: {
118 const base::ListValue* list = NULL;
119 if (!value.GetAsList(&list))
120 return false;
121 for (size_t i = 0; i < list->GetSize(); ++i) {
122 const base::Value* item;
123 if (!list->Get(i, &item))
124 return false;
125 if (!InstallValue(*item, hive, path + kPathSep + name,
126 base::UintToString16(i + 1))) {
127 return false;
130 return true;
133 case base::Value::TYPE_BINARY:
134 return false;
136 NOTREACHED();
137 return false;
140 // This class provides sandboxing and mocking for the parts of the Windows
141 // Registry implementing Group Policy. It prepares two temporary sandbox keys,
142 // one for HKLM and one for HKCU. A test's calls to the registry are redirected
143 // by Windows to these sandboxes, allowing the tests to manipulate and access
144 // policy as if it were active, but without actually changing the parts of the
145 // Registry that are managed by Group Policy.
146 class ScopedGroupPolicyRegistrySandbox {
147 public:
148 ScopedGroupPolicyRegistrySandbox();
149 ~ScopedGroupPolicyRegistrySandbox();
151 private:
152 void ActivateOverrides();
153 void RemoveOverrides();
155 // Deletes the sandbox keys.
156 void DeleteKeys();
158 std::wstring key_name_;
160 // Keys are created for the lifetime of a test to contain
161 // the sandboxed HKCU and HKLM hives, respectively.
162 RegKey temp_hkcu_hive_key_;
163 RegKey temp_hklm_hive_key_;
165 DISALLOW_COPY_AND_ASSIGN(ScopedGroupPolicyRegistrySandbox);
168 // A test harness that feeds policy via the Chrome GPO registry subtree.
169 class RegistryTestHarness : public PolicyProviderTestHarness,
170 public AppliedGPOListProvider {
171 public:
172 RegistryTestHarness(HKEY hive, PolicyScope scope);
173 virtual ~RegistryTestHarness();
175 // PolicyProviderTestHarness:
176 virtual void SetUp() OVERRIDE;
178 virtual ConfigurationPolicyProvider* CreateProvider(
179 SchemaRegistry* registry,
180 scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
182 virtual void InstallEmptyPolicy() OVERRIDE;
183 virtual void InstallStringPolicy(const std::string& policy_name,
184 const std::string& policy_value) OVERRIDE;
185 virtual void InstallIntegerPolicy(const std::string& policy_name,
186 int policy_value) OVERRIDE;
187 virtual void InstallBooleanPolicy(const std::string& policy_name,
188 bool policy_value) OVERRIDE;
189 virtual void InstallStringListPolicy(
190 const std::string& policy_name,
191 const base::ListValue* policy_value) OVERRIDE;
192 virtual void InstallDictionaryPolicy(
193 const std::string& policy_name,
194 const base::DictionaryValue* policy_value) OVERRIDE;
195 virtual void Install3rdPartyPolicy(
196 const base::DictionaryValue* policies) OVERRIDE;
198 // AppliedGPOListProvider:
199 virtual DWORD GetAppliedGPOList(DWORD flags,
200 LPCTSTR machine_name,
201 PSID sid_user,
202 GUID* extension_guid,
203 PGROUP_POLICY_OBJECT* gpo_list) OVERRIDE;
204 virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) OVERRIDE;
206 // Creates a harness instance that will install policy in HKCU or HKLM,
207 // respectively.
208 static PolicyProviderTestHarness* CreateHKCU();
209 static PolicyProviderTestHarness* CreateHKLM();
211 private:
212 HKEY hive_;
214 ScopedGroupPolicyRegistrySandbox registry_sandbox_;
216 DISALLOW_COPY_AND_ASSIGN(RegistryTestHarness);
219 // A test harness that generates PReg files for the provider to read.
220 class PRegTestHarness : public PolicyProviderTestHarness,
221 public AppliedGPOListProvider {
222 public:
223 PRegTestHarness();
224 virtual ~PRegTestHarness();
226 // PolicyProviderTestHarness:
227 virtual void SetUp() OVERRIDE;
229 virtual ConfigurationPolicyProvider* CreateProvider(
230 SchemaRegistry* registry,
231 scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
233 virtual void InstallEmptyPolicy() OVERRIDE;
234 virtual void InstallStringPolicy(const std::string& policy_name,
235 const std::string& policy_value) OVERRIDE;
236 virtual void InstallIntegerPolicy(const std::string& policy_name,
237 int policy_value) OVERRIDE;
238 virtual void InstallBooleanPolicy(const std::string& policy_name,
239 bool policy_value) OVERRIDE;
240 virtual void InstallStringListPolicy(
241 const std::string& policy_name,
242 const base::ListValue* policy_value) OVERRIDE;
243 virtual void InstallDictionaryPolicy(
244 const std::string& policy_name,
245 const base::DictionaryValue* policy_value) OVERRIDE;
246 virtual void Install3rdPartyPolicy(
247 const base::DictionaryValue* policies) OVERRIDE;
249 // AppliedGPOListProvider:
250 virtual DWORD GetAppliedGPOList(DWORD flags,
251 LPCTSTR machine_name,
252 PSID sid_user,
253 GUID* extension_guid,
254 PGROUP_POLICY_OBJECT* gpo_list) OVERRIDE;
255 virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) OVERRIDE;
257 // Creates a harness instance.
258 static PolicyProviderTestHarness* Create();
260 private:
261 // Helper to append a base::string16 to an uint8 buffer.
262 static void AppendChars(std::vector<uint8>* buffer,
263 const base::string16& chars);
265 // Appends a record with the given fields to the PReg file.
266 void AppendRecordToPRegFile(const base::string16& path,
267 const std::string& key,
268 DWORD type,
269 DWORD size,
270 uint8* data);
272 // Appends the given DWORD |value| for |path| + |key| to the PReg file.
273 void AppendDWORDToPRegFile(const base::string16& path,
274 const std::string& key,
275 DWORD value);
277 // Appends the given string |value| for |path| + |key| to the PReg file.
278 void AppendStringToPRegFile(const base::string16& path,
279 const std::string& key,
280 const std::string& value);
282 // Appends the given policy |value| for |path| + |key| to the PReg file,
283 // converting and recursing as necessary.
284 void AppendPolicyToPRegFile(const base::string16& path,
285 const std::string& key,
286 const base::Value* value);
288 base::ScopedTempDir temp_dir_;
289 base::FilePath preg_file_path_;
290 GROUP_POLICY_OBJECT gpo_;
292 DISALLOW_COPY_AND_ASSIGN(PRegTestHarness);
295 ScopedGroupPolicyRegistrySandbox::ScopedGroupPolicyRegistrySandbox() {
296 // Generate a unique registry key for the override for each test. This
297 // makes sure that tests executing in parallel won't delete each other's
298 // key, at DeleteKeys().
299 key_name_ = base::ASCIIToWide(base::StringPrintf(
300 "SOFTWARE\\chromium unittest %d",
301 base::Process::Current().pid()));
302 std::wstring hklm_key_name = key_name_ + L"\\HKLM";
303 std::wstring hkcu_key_name = key_name_ + L"\\HKCU";
305 // Create the subkeys to hold the overridden HKLM and HKCU
306 // policy settings.
307 temp_hklm_hive_key_.Create(HKEY_CURRENT_USER,
308 hklm_key_name.c_str(),
309 KEY_ALL_ACCESS);
310 temp_hkcu_hive_key_.Create(HKEY_CURRENT_USER,
311 hkcu_key_name.c_str(),
312 KEY_ALL_ACCESS);
314 ActivateOverrides();
317 ScopedGroupPolicyRegistrySandbox::~ScopedGroupPolicyRegistrySandbox() {
318 RemoveOverrides();
319 DeleteKeys();
322 void ScopedGroupPolicyRegistrySandbox::ActivateOverrides() {
323 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE,
324 temp_hklm_hive_key_.Handle()));
325 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER,
326 temp_hkcu_hive_key_.Handle()));
329 void ScopedGroupPolicyRegistrySandbox::RemoveOverrides() {
330 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE, 0));
331 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER, 0));
334 void ScopedGroupPolicyRegistrySandbox::DeleteKeys() {
335 RegKey key(HKEY_CURRENT_USER, key_name_.c_str(), KEY_ALL_ACCESS);
336 ASSERT_TRUE(key.Valid());
337 key.DeleteKey(L"");
340 RegistryTestHarness::RegistryTestHarness(HKEY hive, PolicyScope scope)
341 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, scope), hive_(hive) {}
343 RegistryTestHarness::~RegistryTestHarness() {}
345 void RegistryTestHarness::SetUp() {}
347 ConfigurationPolicyProvider* RegistryTestHarness::CreateProvider(
348 SchemaRegistry* registry,
349 scoped_refptr<base::SequencedTaskRunner> task_runner) {
350 base::win::SetDomainStateForTesting(true);
351 scoped_ptr<AsyncPolicyLoader> loader(
352 new PolicyLoaderWin(task_runner, kTestPolicyKey, this));
353 return new AsyncPolicyProvider(registry, loader.Pass());
356 void RegistryTestHarness::InstallEmptyPolicy() {}
358 void RegistryTestHarness::InstallStringPolicy(
359 const std::string& policy_name,
360 const std::string& policy_value) {
361 RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
362 ASSERT_TRUE(key.Valid());
363 ASSERT_HRESULT_SUCCEEDED(key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
364 UTF8ToUTF16(policy_value).c_str()));
367 void RegistryTestHarness::InstallIntegerPolicy(
368 const std::string& policy_name,
369 int policy_value) {
370 RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
371 ASSERT_TRUE(key.Valid());
372 key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
373 static_cast<DWORD>(policy_value));
376 void RegistryTestHarness::InstallBooleanPolicy(
377 const std::string& policy_name,
378 bool policy_value) {
379 RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
380 ASSERT_TRUE(key.Valid());
381 key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
382 static_cast<DWORD>(policy_value));
385 void RegistryTestHarness::InstallStringListPolicy(
386 const std::string& policy_name,
387 const base::ListValue* policy_value) {
388 RegKey key(hive_,
389 (base::string16(kTestPolicyKey) + base::ASCIIToUTF16("\\") +
390 UTF8ToUTF16(policy_name)).c_str(),
391 KEY_ALL_ACCESS);
392 ASSERT_TRUE(key.Valid());
393 int index = 1;
394 for (base::ListValue::const_iterator element(policy_value->begin());
395 element != policy_value->end();
396 ++element) {
397 std::string element_value;
398 if (!(*element)->GetAsString(&element_value))
399 continue;
400 std::string name(base::IntToString(index++));
401 key.WriteValue(UTF8ToUTF16(name).c_str(),
402 UTF8ToUTF16(element_value).c_str());
406 void RegistryTestHarness::InstallDictionaryPolicy(
407 const std::string& policy_name,
408 const base::DictionaryValue* policy_value) {
409 std::string json;
410 base::JSONWriter::Write(policy_value, &json);
411 RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
412 ASSERT_TRUE(key.Valid());
413 key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
414 UTF8ToUTF16(json).c_str());
417 void RegistryTestHarness::Install3rdPartyPolicy(
418 const base::DictionaryValue* policies) {
419 // The first level entries are domains, and the second level entries map
420 // components to their policy.
421 const base::string16 kPathPrefix =
422 base::string16(kTestPolicyKey) + kPathSep + kThirdParty + kPathSep;
423 for (base::DictionaryValue::Iterator domain(*policies);
424 !domain.IsAtEnd(); domain.Advance()) {
425 const base::DictionaryValue* components = NULL;
426 if (!domain.value().GetAsDictionary(&components)) {
427 ADD_FAILURE();
428 continue;
430 for (base::DictionaryValue::Iterator component(*components);
431 !component.IsAtEnd(); component.Advance()) {
432 const base::string16 path = kPathPrefix +
433 UTF8ToUTF16(domain.key()) + kPathSep + UTF8ToUTF16(component.key());
434 InstallValue(component.value(), hive_, path, kMandatory);
439 DWORD RegistryTestHarness::GetAppliedGPOList(DWORD flags,
440 LPCTSTR machine_name,
441 PSID sid_user,
442 GUID* extension_guid,
443 PGROUP_POLICY_OBJECT* gpo_list) {
444 *gpo_list = NULL;
445 return ERROR_ACCESS_DENIED;
448 BOOL RegistryTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) {
449 return TRUE;
452 // static
453 PolicyProviderTestHarness* RegistryTestHarness::CreateHKCU() {
454 return new RegistryTestHarness(HKEY_CURRENT_USER, POLICY_SCOPE_USER);
457 // static
458 PolicyProviderTestHarness* RegistryTestHarness::CreateHKLM() {
459 return new RegistryTestHarness(HKEY_LOCAL_MACHINE, POLICY_SCOPE_MACHINE);
462 PRegTestHarness::PRegTestHarness()
463 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE) {}
465 PRegTestHarness::~PRegTestHarness() {}
467 void PRegTestHarness::SetUp() {
468 base::win::SetDomainStateForTesting(false);
469 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
470 preg_file_path_ = temp_dir_.path().Append(PolicyLoaderWin::kPRegFileName);
471 ASSERT_TRUE(base::WriteFile(preg_file_path_,
472 preg_parser::kPRegFileHeader,
473 arraysize(preg_parser::kPRegFileHeader)));
475 memset(&gpo_, 0, sizeof(GROUP_POLICY_OBJECT));
476 gpo_.lpFileSysPath = const_cast<wchar_t*>(temp_dir_.path().value().c_str());
479 ConfigurationPolicyProvider* PRegTestHarness::CreateProvider(
480 SchemaRegistry* registry,
481 scoped_refptr<base::SequencedTaskRunner> task_runner) {
482 scoped_ptr<AsyncPolicyLoader> loader(
483 new PolicyLoaderWin(task_runner, kTestPolicyKey, this));
484 return new AsyncPolicyProvider(registry, loader.Pass());
487 void PRegTestHarness::InstallEmptyPolicy() {}
489 void PRegTestHarness::InstallStringPolicy(const std::string& policy_name,
490 const std::string& policy_value) {
491 AppendStringToPRegFile(kTestPolicyKey, policy_name, policy_value);
494 void PRegTestHarness::InstallIntegerPolicy(const std::string& policy_name,
495 int policy_value) {
496 AppendDWORDToPRegFile(kTestPolicyKey, policy_name, policy_value);
499 void PRegTestHarness::InstallBooleanPolicy(const std::string& policy_name,
500 bool policy_value) {
501 AppendDWORDToPRegFile(kTestPolicyKey, policy_name, policy_value);
504 void PRegTestHarness::InstallStringListPolicy(
505 const std::string& policy_name,
506 const base::ListValue* policy_value) {
507 AppendPolicyToPRegFile(kTestPolicyKey, policy_name, policy_value);
510 void PRegTestHarness::InstallDictionaryPolicy(
511 const std::string& policy_name,
512 const base::DictionaryValue* policy_value) {
513 std::string json;
514 base::JSONWriter::Write(policy_value, &json);
515 AppendStringToPRegFile(kTestPolicyKey, policy_name, json);
518 void PRegTestHarness::Install3rdPartyPolicy(
519 const base::DictionaryValue* policies) {
520 // The first level entries are domains, and the second level entries map
521 // components to their policy.
522 const base::string16 kPathPrefix =
523 base::string16(kTestPolicyKey) + kPathSep + kThirdParty + kPathSep;
524 for (base::DictionaryValue::Iterator domain(*policies);
525 !domain.IsAtEnd(); domain.Advance()) {
526 const base::DictionaryValue* components = NULL;
527 if (!domain.value().GetAsDictionary(&components)) {
528 ADD_FAILURE();
529 continue;
531 const base::string16 domain_path = kPathPrefix + UTF8ToUTF16(domain.key());
532 for (base::DictionaryValue::Iterator component(*components);
533 !component.IsAtEnd(); component.Advance()) {
534 const base::string16 component_path =
535 domain_path + kPathSep + UTF8ToUTF16(component.key());
536 AppendPolicyToPRegFile(component_path, UTF16ToUTF8(kMandatory),
537 &component.value());
542 DWORD PRegTestHarness::GetAppliedGPOList(DWORD flags,
543 LPCTSTR machine_name,
544 PSID sid_user,
545 GUID* extension_guid,
546 PGROUP_POLICY_OBJECT* gpo_list) {
547 *gpo_list = flags & GPO_LIST_FLAG_MACHINE ? &gpo_ : NULL;
548 return ERROR_SUCCESS;
551 BOOL PRegTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) {
552 return TRUE;
555 // static
556 PolicyProviderTestHarness* PRegTestHarness::Create() {
557 return new PRegTestHarness();
560 // static
561 void PRegTestHarness::AppendChars(std::vector<uint8>* buffer,
562 const base::string16& chars) {
563 for (base::string16::const_iterator c(chars.begin()); c != chars.end(); ++c) {
564 buffer->push_back(*c & 0xff);
565 buffer->push_back((*c >> 8) & 0xff);
569 void PRegTestHarness::AppendRecordToPRegFile(const base::string16& path,
570 const std::string& key,
571 DWORD type,
572 DWORD size,
573 uint8* data) {
574 std::vector<uint8> buffer;
575 AppendChars(&buffer, L"[");
576 AppendChars(&buffer, path);
577 AppendChars(&buffer, base::string16(L"\0;", 2));
578 AppendChars(&buffer, UTF8ToUTF16(key));
579 AppendChars(&buffer, base::string16(L"\0;", 2));
580 type = base::ByteSwapToLE32(type);
581 uint8* type_data = reinterpret_cast<uint8*>(&type);
582 buffer.insert(buffer.end(), type_data, type_data + sizeof(DWORD));
583 AppendChars(&buffer, L";");
584 size = base::ByteSwapToLE32(size);
585 uint8* size_data = reinterpret_cast<uint8*>(&size);
586 buffer.insert(buffer.end(), size_data, size_data + sizeof(DWORD));
587 AppendChars(&buffer, L";");
588 buffer.insert(buffer.end(), data, data + size);
589 AppendChars(&buffer, L"]");
591 ASSERT_EQ(buffer.size(),
592 base::AppendToFile(
593 preg_file_path_,
594 reinterpret_cast<const char*>(vector_as_array(&buffer)),
595 buffer.size()));
598 void PRegTestHarness::AppendDWORDToPRegFile(const base::string16& path,
599 const std::string& key,
600 DWORD value) {
601 value = base::ByteSwapToLE32(value);
602 AppendRecordToPRegFile(path, key, REG_DWORD, sizeof(DWORD),
603 reinterpret_cast<uint8*>(&value));
606 void PRegTestHarness::AppendStringToPRegFile(const base::string16& path,
607 const std::string& key,
608 const std::string& value) {
609 base::string16 string16_value(UTF8ToUTF16(value));
610 std::vector<base::char16> data;
611 std::transform(string16_value.begin(), string16_value.end(),
612 std::back_inserter(data), std::ptr_fun(base::ByteSwapToLE16));
613 data.push_back(base::ByteSwapToLE16(L'\0'));
615 AppendRecordToPRegFile(path, key, REG_SZ, data.size() * sizeof(base::char16),
616 reinterpret_cast<uint8*>(vector_as_array(&data)));
619 void PRegTestHarness::AppendPolicyToPRegFile(const base::string16& path,
620 const std::string& key,
621 const base::Value* value) {
622 switch (value->GetType()) {
623 case base::Value::TYPE_BOOLEAN: {
624 bool boolean_value = false;
625 ASSERT_TRUE(value->GetAsBoolean(&boolean_value));
626 AppendDWORDToPRegFile(path, key, boolean_value);
627 break;
629 case base::Value::TYPE_INTEGER: {
630 int int_value = 0;
631 ASSERT_TRUE(value->GetAsInteger(&int_value));
632 AppendDWORDToPRegFile(path, key, int_value);
633 break;
635 case base::Value::TYPE_DOUBLE: {
636 double double_value = 0;
637 ASSERT_TRUE(value->GetAsDouble(&double_value));
638 AppendStringToPRegFile(path, key, base::DoubleToString(double_value));
639 break;
641 case base::Value::TYPE_STRING: {
642 std::string string_value;
643 ASSERT_TRUE(value->GetAsString(&string_value));
644 AppendStringToPRegFile(path, key, string_value);
645 break;
647 case base::Value::TYPE_DICTIONARY: {
648 base::string16 subpath = path + kPathSep + UTF8ToUTF16(key);
649 const base::DictionaryValue* dict = NULL;
650 ASSERT_TRUE(value->GetAsDictionary(&dict));
651 for (base::DictionaryValue::Iterator entry(*dict); !entry.IsAtEnd();
652 entry.Advance()) {
653 AppendPolicyToPRegFile(subpath, entry.key(), &entry.value());
655 break;
657 case base::Value::TYPE_LIST: {
658 base::string16 subpath = path + kPathSep + UTF8ToUTF16(key);
659 const base::ListValue* list = NULL;
660 ASSERT_TRUE(value->GetAsList(&list));
661 for (size_t i = 0; i < list->GetSize(); ++i) {
662 const base::Value* entry = NULL;
663 ASSERT_TRUE(list->Get(i, &entry));
664 AppendPolicyToPRegFile(subpath, base::IntToString(i + 1), entry);
666 break;
668 case base::Value::TYPE_BINARY:
669 case base::Value::TYPE_NULL: {
670 ADD_FAILURE();
671 break;
676 } // namespace
678 // Instantiate abstract test case for basic policy reading tests.
679 INSTANTIATE_TEST_CASE_P(
680 PolicyProviderWinTest,
681 ConfigurationPolicyProviderTest,
682 testing::Values(RegistryTestHarness::CreateHKCU,
683 RegistryTestHarness::CreateHKLM,
684 PRegTestHarness::Create));
686 // Instantiate abstract test case for 3rd party policy reading tests.
687 INSTANTIATE_TEST_CASE_P(
688 ThirdPartyPolicyProviderWinTest,
689 Configuration3rdPartyPolicyProviderTest,
690 testing::Values(RegistryTestHarness::CreateHKCU,
691 RegistryTestHarness::CreateHKLM,
692 PRegTestHarness::Create));
694 // Test cases for windows policy provider specific functionality.
695 class PolicyLoaderWinTest : public PolicyTestBase,
696 public AppliedGPOListProvider {
697 protected:
698 // The policy key this tests places data under. This must match the data
699 // files in chrome/test/data/policy/gpo.
700 static const base::char16 kTestPolicyKey[];
702 PolicyLoaderWinTest()
703 : gpo_list_(NULL),
704 gpo_list_status_(ERROR_ACCESS_DENIED) {}
705 virtual ~PolicyLoaderWinTest() {}
707 virtual void SetUp() OVERRIDE {
708 base::win::SetDomainStateForTesting(false);
709 PolicyTestBase::SetUp();
711 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir_));
712 test_data_dir_ = test_data_dir_.AppendASCII("chrome")
713 .AppendASCII("test")
714 .AppendASCII("data")
715 .AppendASCII("policy")
716 .AppendASCII("gpo");
719 // AppliedGPOListProvider:
720 virtual DWORD GetAppliedGPOList(DWORD flags,
721 LPCTSTR machine_name,
722 PSID sid_user,
723 GUID* extension_guid,
724 PGROUP_POLICY_OBJECT* gpo_list) OVERRIDE {
725 *gpo_list = gpo_list_;
726 return gpo_list_status_;
728 virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) OVERRIDE {
729 return TRUE;
732 void InitGPO(GROUP_POLICY_OBJECT* gpo,
733 DWORD options,
734 const base::FilePath& path,
735 GROUP_POLICY_OBJECT* next,
736 GROUP_POLICY_OBJECT* prev) {
737 memset(gpo, 0, sizeof(GROUP_POLICY_OBJECT));
738 gpo->dwOptions = options;
739 gpo->lpFileSysPath = const_cast<wchar_t*>(path.value().c_str());
740 gpo->pNext = next;
741 gpo->pPrev = prev;
744 bool Matches(const PolicyBundle& expected) {
745 PolicyLoaderWin loader(loop_.message_loop_proxy(), kTestPolicyKey, this);
746 scoped_ptr<PolicyBundle> loaded(
747 loader.InitialLoad(schema_registry_.schema_map()));
748 return loaded->Equals(expected);
751 void InstallRegistrySentinel() {
752 RegKey hklm_key(HKEY_CURRENT_USER, kTestPolicyKey, KEY_ALL_ACCESS);
753 ASSERT_TRUE(hklm_key.Valid());
754 hklm_key.WriteValue(
755 UTF8ToUTF16(test_keys::kKeyString).c_str(),
756 UTF8ToUTF16("registry").c_str());
759 bool MatchesRegistrySentinel() {
760 base::DictionaryValue expected_policy;
761 expected_policy.SetString(test_keys::kKeyString, "registry");
762 PolicyBundle expected;
763 expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
764 .LoadFrom(&expected_policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
765 return Matches(expected);
768 bool MatchesTestBundle() {
769 base::DictionaryValue expected_policy;
770 expected_policy.SetBoolean(test_keys::kKeyBoolean, true);
771 expected_policy.SetString(test_keys::kKeyString, "GPO");
772 expected_policy.SetInteger(test_keys::kKeyInteger, 42);
773 scoped_ptr<base::ListValue> list(new base::ListValue());
774 list->AppendString("GPO 1");
775 list->AppendString("GPO 2");
776 expected_policy.Set(test_keys::kKeyStringList, list.release());
777 PolicyBundle expected;
778 expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
779 .LoadFrom(&expected_policy, POLICY_LEVEL_MANDATORY,
780 POLICY_SCOPE_MACHINE);
781 return Matches(expected);
784 ScopedGroupPolicyRegistrySandbox registry_sandbox_;
785 PGROUP_POLICY_OBJECT gpo_list_;
786 DWORD gpo_list_status_;
787 base::FilePath test_data_dir_;
790 const base::char16 PolicyLoaderWinTest::kTestPolicyKey[] =
791 L"SOFTWARE\\Policies\\Chromium";
793 TEST_F(PolicyLoaderWinTest, HKLMOverHKCU) {
794 RegKey hklm_key(HKEY_LOCAL_MACHINE, kTestPolicyKey, KEY_ALL_ACCESS);
795 ASSERT_TRUE(hklm_key.Valid());
796 hklm_key.WriteValue(UTF8ToUTF16(test_keys::kKeyString).c_str(),
797 UTF8ToUTF16("hklm").c_str());
798 RegKey hkcu_key(HKEY_CURRENT_USER, kTestPolicyKey, KEY_ALL_ACCESS);
799 ASSERT_TRUE(hkcu_key.Valid());
800 hkcu_key.WriteValue(UTF8ToUTF16(test_keys::kKeyString).c_str(),
801 UTF8ToUTF16("hkcu").c_str());
803 PolicyBundle expected;
804 expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
805 .Set(test_keys::kKeyString,
806 POLICY_LEVEL_MANDATORY,
807 POLICY_SCOPE_MACHINE,
808 base::Value::CreateStringValue("hklm"), NULL);
809 EXPECT_TRUE(Matches(expected));
812 TEST_F(PolicyLoaderWinTest, Merge3rdPartyPolicies) {
813 // Policy for the same extension will be provided at the 4 level/scope
814 // combinations, to verify that they overlap as expected.
815 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "merge");
816 ASSERT_TRUE(RegisterSchema(
819 " \"type\": \"object\","
820 " \"properties\": {"
821 " \"a\": { \"type\": \"string\" },"
822 " \"b\": { \"type\": \"string\" },"
823 " \"c\": { \"type\": \"string\" },"
824 " \"d\": { \"type\": \"string\" }"
825 " }"
826 "}"));
828 const base::string16 kPathSuffix =
829 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\merge");
831 const char kUserMandatory[] = "user-mandatory";
832 const char kUserRecommended[] = "user-recommended";
833 const char kMachineMandatory[] = "machine-mandatory";
834 const char kMachineRecommended[] = "machine-recommended";
836 base::DictionaryValue policy;
837 policy.SetString("a", kMachineMandatory);
838 EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE,
839 kPathSuffix, kMandatory));
840 policy.SetString("a", kUserMandatory);
841 policy.SetString("b", kUserMandatory);
842 EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER,
843 kPathSuffix, kMandatory));
844 policy.SetString("a", kMachineRecommended);
845 policy.SetString("b", kMachineRecommended);
846 policy.SetString("c", kMachineRecommended);
847 EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE,
848 kPathSuffix, kRecommended));
849 policy.SetString("a", kUserRecommended);
850 policy.SetString("b", kUserRecommended);
851 policy.SetString("c", kUserRecommended);
852 policy.SetString("d", kUserRecommended);
853 EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER,
854 kPathSuffix, kRecommended));
856 PolicyBundle expected;
857 PolicyMap& expected_policy = expected.Get(ns);
858 expected_policy.Set("a", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
859 base::Value::CreateStringValue(kMachineMandatory), NULL);
860 expected_policy.Set("b", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
861 base::Value::CreateStringValue(kUserMandatory), NULL);
862 expected_policy.Set("c", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
863 base::Value::CreateStringValue(kMachineRecommended),
864 NULL);
865 expected_policy.Set("d", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
866 base::Value::CreateStringValue(kUserRecommended), NULL);
867 EXPECT_TRUE(Matches(expected));
870 TEST_F(PolicyLoaderWinTest, LoadStringEncodedValues) {
871 // Create a dictionary with all the types that can be stored encoded in a
872 // string.
873 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "string");
874 ASSERT_TRUE(RegisterSchema(
877 " \"type\": \"object\","
878 " \"id\": \"MainType\","
879 " \"properties\": {"
880 " \"null\": { \"type\": \"null\" },"
881 " \"bool\": { \"type\": \"boolean\" },"
882 " \"int\": { \"type\": \"integer\" },"
883 " \"double\": { \"type\": \"number\" },"
884 " \"list\": {"
885 " \"type\": \"array\","
886 " \"items\": { \"$ref\": \"MainType\" }"
887 " },"
888 " \"dict\": { \"$ref\": \"MainType\" }"
889 " }"
890 "}"));
892 base::DictionaryValue policy;
893 policy.Set("null", base::Value::CreateNullValue());
894 policy.SetBoolean("bool", true);
895 policy.SetInteger("int", -123);
896 policy.SetDouble("double", 456.78e9);
897 base::ListValue list;
898 list.Append(policy.DeepCopy());
899 list.Append(policy.DeepCopy());
900 policy.Set("list", list.DeepCopy());
901 // Encode |policy| before adding the "dict" entry.
902 std::string encoded_dict;
903 base::JSONWriter::Write(&policy, &encoded_dict);
904 ASSERT_FALSE(encoded_dict.empty());
905 policy.Set("dict", policy.DeepCopy());
906 std::string encoded_list;
907 base::JSONWriter::Write(&list, &encoded_list);
908 ASSERT_FALSE(encoded_list.empty());
909 base::DictionaryValue encoded_policy;
910 encoded_policy.SetString("null", "");
911 encoded_policy.SetString("bool", "1");
912 encoded_policy.SetString("int", "-123");
913 encoded_policy.SetString("double", "456.78e9");
914 encoded_policy.SetString("list", encoded_list);
915 encoded_policy.SetString("dict", encoded_dict);
917 const base::string16 kPathSuffix =
918 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\string");
919 EXPECT_TRUE(
920 InstallValue(encoded_policy, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
922 PolicyBundle expected;
923 expected.Get(ns).LoadFrom(&policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
924 EXPECT_TRUE(Matches(expected));
927 TEST_F(PolicyLoaderWinTest, LoadIntegerEncodedValues) {
928 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "int");
929 ASSERT_TRUE(RegisterSchema(
932 " \"type\": \"object\","
933 " \"properties\": {"
934 " \"bool\": { \"type\": \"boolean\" },"
935 " \"int\": { \"type\": \"integer\" },"
936 " \"double\": { \"type\": \"number\" }"
937 " }"
938 "}"));
940 base::DictionaryValue encoded_policy;
941 encoded_policy.SetInteger("bool", 1);
942 encoded_policy.SetInteger("int", 123);
943 encoded_policy.SetInteger("double", 456);
945 const base::string16 kPathSuffix =
946 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\int");
947 EXPECT_TRUE(
948 InstallValue(encoded_policy, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
950 base::DictionaryValue policy;
951 policy.SetBoolean("bool", true);
952 policy.SetInteger("int", 123);
953 policy.SetDouble("double", 456.0);
954 PolicyBundle expected;
955 expected.Get(ns).LoadFrom(&policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
956 EXPECT_TRUE(Matches(expected));
959 TEST_F(PolicyLoaderWinTest, DefaultPropertySchemaType) {
960 // Build a schema for an "object" with a default schema for its properties.
961 // Note that the top-level object can't have "additionalProperties", so
962 // a "policy" property is used instead.
963 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "test");
964 ASSERT_TRUE(RegisterSchema(
967 " \"type\": \"object\","
968 " \"properties\": {"
969 " \"policy\": {"
970 " \"type\": \"object\","
971 " \"properties\": {"
972 " \"special-int1\": { \"type\": \"integer\" },"
973 " \"special-int2\": { \"type\": \"integer\" }"
974 " },"
975 " \"additionalProperties\": { \"type\": \"number\" }"
976 " }"
977 " }"
978 "}"));
980 // Write some test values.
981 base::DictionaryValue policy;
982 // These special values have a specific schema for them.
983 policy.SetInteger("special-int1", 123);
984 policy.SetString("special-int2", "-456");
985 // Other values default to be loaded as doubles.
986 policy.SetInteger("double1", 789.0);
987 policy.SetString("double2", "123.456e7");
988 policy.SetString("invalid", "omg");
989 base::DictionaryValue all_policies;
990 all_policies.Set("policy", policy.DeepCopy());
992 const base::string16 kPathSuffix =
993 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\test");
994 EXPECT_TRUE(
995 InstallValue(all_policies, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
997 base::DictionaryValue expected_policy;
998 expected_policy.SetInteger("special-int1", 123);
999 expected_policy.SetInteger("special-int2", -456);
1000 expected_policy.SetDouble("double1", 789.0);
1001 expected_policy.SetDouble("double2", 123.456e7);
1002 base::DictionaryValue expected_policies;
1003 expected_policies.Set("policy", expected_policy.DeepCopy());
1004 PolicyBundle expected;
1005 expected.Get(ns).LoadFrom(
1006 &expected_policies, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
1007 EXPECT_TRUE(Matches(expected));
1010 TEST_F(PolicyLoaderWinTest, AppliedPolicyNotPresent) {
1011 InstallRegistrySentinel();
1012 gpo_list_ = NULL;
1013 gpo_list_status_ = ERROR_SUCCESS;
1015 PolicyBundle empty;
1016 EXPECT_TRUE(Matches(empty));
1019 TEST_F(PolicyLoaderWinTest, AppliedPolicyEmpty) {
1020 InstallRegistrySentinel();
1021 base::FilePath gpo_dir(test_data_dir_.AppendASCII("empty"));
1022 GROUP_POLICY_OBJECT gpo;
1023 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1024 gpo_list_ = &gpo;
1025 gpo_list_status_ = ERROR_SUCCESS;
1027 PolicyBundle empty;
1028 EXPECT_TRUE(Matches(empty));
1031 TEST_F(PolicyLoaderWinTest, AppliedPolicyInDomain) {
1032 base::win::SetDomainStateForTesting(true);
1033 InstallRegistrySentinel();
1034 base::FilePath gpo_dir(test_data_dir_.AppendASCII("empty"));
1035 GROUP_POLICY_OBJECT gpo;
1036 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1037 gpo_list_ = &gpo;
1038 gpo_list_status_ = ERROR_SUCCESS;
1040 PolicyBundle empty;
1041 EXPECT_TRUE(MatchesRegistrySentinel());
1044 TEST_F(PolicyLoaderWinTest, AppliedPolicyNonExistingFile) {
1045 InstallRegistrySentinel();
1046 GROUP_POLICY_OBJECT gpo;
1047 InitGPO(&gpo, 0, test_data_dir_, NULL, NULL);
1048 gpo_list_ = &gpo;
1049 gpo_list_status_ = ERROR_SUCCESS;
1051 EXPECT_TRUE(MatchesRegistrySentinel());
1054 TEST_F(PolicyLoaderWinTest, AppliedPolicyBadPath) {
1055 InstallRegistrySentinel();
1056 base::FilePath gpo_dir(test_data_dir_.AppendASCII("bad"));
1057 GROUP_POLICY_OBJECT gpo;
1058 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1059 gpo_list_ = &gpo;
1060 gpo_list_status_ = ERROR_SUCCESS;
1062 EXPECT_TRUE(MatchesRegistrySentinel());
1065 TEST_F(PolicyLoaderWinTest, AppliedPolicyPresent) {
1066 InstallRegistrySentinel();
1067 base::FilePath gpo_dir(test_data_dir_.AppendASCII("test1"));
1068 GROUP_POLICY_OBJECT gpo;
1069 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1070 gpo_list_ = &gpo;
1071 gpo_list_status_ = ERROR_SUCCESS;
1073 EXPECT_TRUE(MatchesTestBundle());
1076 TEST_F(PolicyLoaderWinTest, AppliedPolicyMerged) {
1077 InstallRegistrySentinel();
1078 base::FilePath gpo1_dir(test_data_dir_.AppendASCII("test2"));
1079 base::FilePath gpo2_dir(test_data_dir_.AppendASCII("test1"));
1080 GROUP_POLICY_OBJECT gpo1;
1081 GROUP_POLICY_OBJECT gpo2;
1082 InitGPO(&gpo1, 0, gpo1_dir, &gpo2, NULL);
1083 InitGPO(&gpo2, 0, gpo2_dir, NULL, &gpo1);
1084 gpo_list_ = &gpo1;
1085 gpo_list_status_ = ERROR_SUCCESS;
1087 EXPECT_TRUE(MatchesTestBundle());
1090 TEST_F(PolicyLoaderWinTest, AppliedPolicyDisabled) {
1091 InstallRegistrySentinel();
1092 base::FilePath gpo1_dir(test_data_dir_.AppendASCII("test1"));
1093 base::FilePath gpo2_dir(test_data_dir_.AppendASCII("test2"));
1094 GROUP_POLICY_OBJECT gpo1;
1095 GROUP_POLICY_OBJECT gpo2;
1096 InitGPO(&gpo1, 0, gpo1_dir, &gpo2, NULL);
1097 InitGPO(&gpo2, GPO_FLAG_DISABLE, gpo2_dir, NULL, &gpo1);
1098 gpo_list_ = &gpo1;
1099 gpo_list_status_ = ERROR_SUCCESS;
1101 EXPECT_TRUE(MatchesTestBundle());
1104 TEST_F(PolicyLoaderWinTest, AppliedPolicyForcedPolicy) {
1105 InstallRegistrySentinel();
1106 base::FilePath gpo1_dir(test_data_dir_.AppendASCII("test1"));
1107 base::FilePath gpo2_dir(test_data_dir_.AppendASCII("test2"));
1108 GROUP_POLICY_OBJECT gpo1;
1109 GROUP_POLICY_OBJECT gpo2;
1110 InitGPO(&gpo1, GPO_FLAG_FORCE, gpo1_dir, &gpo2, NULL);
1111 InitGPO(&gpo2, 0, gpo2_dir, NULL, &gpo1);
1112 gpo_list_ = &gpo1;
1113 gpo_list_status_ = ERROR_SUCCESS;
1115 EXPECT_TRUE(MatchesTestBundle());
1118 TEST_F(PolicyLoaderWinTest, AppliedPolicyUNCPath) {
1119 InstallRegistrySentinel();
1120 base::FilePath gpo_dir(test_data_dir_.AppendASCII("test1"));
1121 base::FilePath unc_path(L"\\\\some_share\\GPO");
1122 GROUP_POLICY_OBJECT gpo1;
1123 GROUP_POLICY_OBJECT gpo2;
1124 InitGPO(&gpo1, 0, gpo_dir, &gpo2, NULL);
1125 InitGPO(&gpo2, 0, unc_path, NULL, &gpo1);
1126 gpo_list_ = &gpo1;
1127 gpo_list_status_ = ERROR_SUCCESS;
1129 EXPECT_TRUE(MatchesRegistrySentinel());
1132 TEST_F(PolicyLoaderWinTest, LoadExtensionPolicyAlternativeSpelling) {
1133 base::FilePath gpo_dir(
1134 test_data_dir_.AppendASCII("extension_alternative_spelling"));
1135 GROUP_POLICY_OBJECT gpo;
1136 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1137 gpo_list_ = &gpo;
1138 gpo_list_status_ = ERROR_SUCCESS;
1140 const char kTestSchema[] =
1142 " \"type\": \"object\","
1143 " \"properties\": {"
1144 " \"policy 1\": { \"type\": \"integer\" },"
1145 " \"policy 2\": { \"type\": \"integer\" }"
1146 " }"
1147 "}";
1148 const PolicyNamespace ns_a(
1149 POLICY_DOMAIN_EXTENSIONS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
1150 const PolicyNamespace ns_b(
1151 POLICY_DOMAIN_EXTENSIONS, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
1152 ASSERT_TRUE(RegisterSchema(ns_a, kTestSchema));
1153 ASSERT_TRUE(RegisterSchema(ns_b, kTestSchema));
1155 PolicyBundle expected;
1156 base::DictionaryValue expected_a;
1157 expected_a.SetInteger("policy 1", 3);
1158 expected_a.SetInteger("policy 2", 3);
1159 expected.Get(ns_a).LoadFrom(
1160 &expected_a, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE);
1161 base::DictionaryValue expected_b;
1162 expected_b.SetInteger("policy 1", 2);
1163 expected.Get(ns_b).LoadFrom(
1164 &expected_b, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE);
1165 EXPECT_TRUE(Matches(expected));
1168 TEST_F(PolicyLoaderWinTest, LBSSupport) {
1169 const PolicyNamespace ns(
1170 POLICY_DOMAIN_EXTENSIONS, "heildphpnddilhkemkielfhnkaagiabh");
1171 schema_registry_.RegisterComponent(ns, Schema());
1173 const char kIncompleteSchema[] =
1175 " \"type\": \"object\","
1176 " \"properties\": {"
1177 " \"url_list\": { \"type\": \"array\" },"
1178 " \"url_greylist\": { \"type\": \"array\" }"
1179 " }"
1180 "}";
1182 const base::string16 kPathSuffix =
1183 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions");
1185 base::ListValue list;
1186 list.AppendString("youtube.com");
1187 base::DictionaryValue policy;
1188 policy.Set("url_list", list.DeepCopy());
1189 policy.SetString("alternative_browser_path", "c:\\legacy\\browser.exe");
1190 base::DictionaryValue root;
1191 root.Set(base::UTF16ToUTF8(kMandatory), policy.DeepCopy());
1192 root.SetString(kSchema, kIncompleteSchema);
1193 EXPECT_TRUE(InstallValue(root, HKEY_LOCAL_MACHINE,
1194 kPathSuffix, base::ASCIIToUTF16(ns.component_id)));
1196 PolicyBundle expected;
1197 PolicyMap& expected_policy = expected.Get(ns);
1198 expected_policy.Set("alternative_browser_path",
1199 POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
1200 new base::StringValue("c:\\legacy\\browser.exe"), NULL);
1201 expected_policy.Set("url_list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
1202 list.DeepCopy(), NULL);
1203 EXPECT_TRUE(Matches(expected));
1206 } // namespace policy