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"
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
;
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
62 bool InstallValue(const base::Value
& value
,
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
: {
75 if (!value
.GetAsBoolean(&bool_value
))
77 return key
.WriteValue(name
.c_str(), bool_value
? 1 : 0) == ERROR_SUCCESS
;
80 case base::Value::TYPE_INTEGER
: {
82 if (!value
.GetAsInteger(&int_value
))
84 return key
.WriteValue(name
.c_str(), int_value
) == ERROR_SUCCESS
;
87 case base::Value::TYPE_DOUBLE
: {
89 if (!value
.GetAsDouble(&double_value
))
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
))
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
))
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()))) {
117 case base::Value::TYPE_LIST
: {
118 const base::ListValue
* list
= NULL
;
119 if (!value
.GetAsList(&list
))
121 for (size_t i
= 0; i
< list
->GetSize(); ++i
) {
122 const base::Value
* item
;
123 if (!list
->Get(i
, &item
))
125 if (!InstallValue(*item
, hive
, path
+ kPathSep
+ name
,
126 base::UintToString16(i
+ 1))) {
133 case base::Value::TYPE_BINARY
:
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
{
148 ScopedGroupPolicyRegistrySandbox();
149 ~ScopedGroupPolicyRegistrySandbox();
152 void ActivateOverrides();
153 void RemoveOverrides();
155 // Deletes the sandbox keys.
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
{
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
,
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,
208 static PolicyProviderTestHarness
* CreateHKCU();
209 static PolicyProviderTestHarness
* CreateHKLM();
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
{
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
,
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();
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
,
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
,
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
307 temp_hklm_hive_key_
.Create(HKEY_CURRENT_USER
,
308 hklm_key_name
.c_str(),
310 temp_hkcu_hive_key_
.Create(HKEY_CURRENT_USER
,
311 hkcu_key_name
.c_str(),
317 ScopedGroupPolicyRegistrySandbox::~ScopedGroupPolicyRegistrySandbox() {
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());
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
,
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
,
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
) {
389 (base::string16(kTestPolicyKey
) + base::ASCIIToUTF16("\\") +
390 UTF8ToUTF16(policy_name
)).c_str(),
392 ASSERT_TRUE(key
.Valid());
394 for (base::ListValue::const_iterator
element(policy_value
->begin());
395 element
!= policy_value
->end();
397 std::string element_value
;
398 if (!(*element
)->GetAsString(&element_value
))
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
) {
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
)) {
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
,
442 GUID
* extension_guid
,
443 PGROUP_POLICY_OBJECT
* gpo_list
) {
445 return ERROR_ACCESS_DENIED
;
448 BOOL
RegistryTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) {
453 PolicyProviderTestHarness
* RegistryTestHarness::CreateHKCU() {
454 return new RegistryTestHarness(HKEY_CURRENT_USER
, POLICY_SCOPE_USER
);
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
,
496 AppendDWORDToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
499 void PRegTestHarness::InstallBooleanPolicy(const std::string
& policy_name
,
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
) {
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
)) {
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
),
542 DWORD
PRegTestHarness::GetAppliedGPOList(DWORD flags
,
543 LPCTSTR machine_name
,
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
) {
556 PolicyProviderTestHarness
* PRegTestHarness::Create() {
557 return new PRegTestHarness();
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
,
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(),
594 reinterpret_cast<const char*>(vector_as_array(&buffer
)),
598 void PRegTestHarness::AppendDWORDToPRegFile(const base::string16
& path
,
599 const std::string
& key
,
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
);
629 case base::Value::TYPE_INTEGER
: {
631 ASSERT_TRUE(value
->GetAsInteger(&int_value
));
632 AppendDWORDToPRegFile(path
, key
, int_value
);
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
));
641 case base::Value::TYPE_STRING
: {
642 std::string string_value
;
643 ASSERT_TRUE(value
->GetAsString(&string_value
));
644 AppendStringToPRegFile(path
, key
, string_value
);
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();
653 AppendPolicyToPRegFile(subpath
, entry
.key(), &entry
.value());
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
);
668 case base::Value::TYPE_BINARY
:
669 case base::Value::TYPE_NULL
: {
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
{
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()
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")
715 .AppendASCII("policy")
719 // AppliedGPOListProvider:
720 virtual DWORD
GetAppliedGPOList(DWORD flags
,
721 LPCTSTR machine_name
,
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
{
732 void InitGPO(GROUP_POLICY_OBJECT
* gpo
,
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());
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());
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\","
821 " \"a\": { \"type\": \"string\" },"
822 " \"b\": { \"type\": \"string\" },"
823 " \"c\": { \"type\": \"string\" },"
824 " \"d\": { \"type\": \"string\" }"
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
),
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
873 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "string");
874 ASSERT_TRUE(RegisterSchema(
877 " \"type\": \"object\","
878 " \"id\": \"MainType\","
880 " \"null\": { \"type\": \"null\" },"
881 " \"bool\": { \"type\": \"boolean\" },"
882 " \"int\": { \"type\": \"integer\" },"
883 " \"double\": { \"type\": \"number\" },"
885 " \"type\": \"array\","
886 " \"items\": { \"$ref\": \"MainType\" }"
888 " \"dict\": { \"$ref\": \"MainType\" }"
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");
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\","
934 " \"bool\": { \"type\": \"boolean\" },"
935 " \"int\": { \"type\": \"integer\" },"
936 " \"double\": { \"type\": \"number\" }"
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");
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\","
970 " \"type\": \"object\","
972 " \"special-int1\": { \"type\": \"integer\" },"
973 " \"special-int2\": { \"type\": \"integer\" }"
975 " \"additionalProperties\": { \"type\": \"number\" }"
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");
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();
1013 gpo_list_status_
= ERROR_SUCCESS
;
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
);
1025 gpo_list_status_
= ERROR_SUCCESS
;
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
);
1038 gpo_list_status_
= ERROR_SUCCESS
;
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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\" }"
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\" }"
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