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/files/file_path.h"
19 #include "base/files/file_util.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_handle.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 base::string16 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::ASCIIToUTF16(base::StringPrintf(
300 "SOFTWARE\\chromium unittest %d", base::GetCurrentProcId()));
301 std::wstring hklm_key_name
= key_name_
+ L
"\\HKLM";
302 std::wstring hkcu_key_name
= key_name_
+ L
"\\HKCU";
304 // Create the subkeys to hold the overridden HKLM and HKCU
306 temp_hklm_hive_key_
.Create(HKEY_CURRENT_USER
,
307 hklm_key_name
.c_str(),
309 temp_hkcu_hive_key_
.Create(HKEY_CURRENT_USER
,
310 hkcu_key_name
.c_str(),
316 ScopedGroupPolicyRegistrySandbox::~ScopedGroupPolicyRegistrySandbox() {
321 void ScopedGroupPolicyRegistrySandbox::ActivateOverrides() {
322 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE
,
323 temp_hklm_hive_key_
.Handle()));
324 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER
,
325 temp_hkcu_hive_key_
.Handle()));
328 void ScopedGroupPolicyRegistrySandbox::RemoveOverrides() {
329 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE
, 0));
330 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER
, 0));
333 void ScopedGroupPolicyRegistrySandbox::DeleteKeys() {
334 RegKey
key(HKEY_CURRENT_USER
, key_name_
.c_str(), KEY_ALL_ACCESS
);
335 ASSERT_TRUE(key
.Valid());
339 RegistryTestHarness::RegistryTestHarness(HKEY hive
, PolicyScope scope
)
340 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY
, scope
), hive_(hive
) {}
342 RegistryTestHarness::~RegistryTestHarness() {}
344 void RegistryTestHarness::SetUp() {}
346 ConfigurationPolicyProvider
* RegistryTestHarness::CreateProvider(
347 SchemaRegistry
* registry
,
348 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) {
349 base::win::SetDomainStateForTesting(true);
350 scoped_ptr
<AsyncPolicyLoader
> loader(
351 new PolicyLoaderWin(task_runner
, kTestPolicyKey
, this));
352 return new AsyncPolicyProvider(registry
, loader
.Pass());
355 void RegistryTestHarness::InstallEmptyPolicy() {}
357 void RegistryTestHarness::InstallStringPolicy(
358 const std::string
& policy_name
,
359 const std::string
& policy_value
) {
360 RegKey
key(hive_
, kTestPolicyKey
, KEY_ALL_ACCESS
);
361 ASSERT_TRUE(key
.Valid());
362 ASSERT_HRESULT_SUCCEEDED(key
.WriteValue(UTF8ToUTF16(policy_name
).c_str(),
363 UTF8ToUTF16(policy_value
).c_str()));
366 void RegistryTestHarness::InstallIntegerPolicy(
367 const std::string
& policy_name
,
369 RegKey
key(hive_
, kTestPolicyKey
, KEY_ALL_ACCESS
);
370 ASSERT_TRUE(key
.Valid());
371 key
.WriteValue(UTF8ToUTF16(policy_name
).c_str(),
372 static_cast<DWORD
>(policy_value
));
375 void RegistryTestHarness::InstallBooleanPolicy(
376 const std::string
& policy_name
,
378 RegKey
key(hive_
, kTestPolicyKey
, KEY_ALL_ACCESS
);
379 ASSERT_TRUE(key
.Valid());
380 key
.WriteValue(UTF8ToUTF16(policy_name
).c_str(),
381 static_cast<DWORD
>(policy_value
));
384 void RegistryTestHarness::InstallStringListPolicy(
385 const std::string
& policy_name
,
386 const base::ListValue
* policy_value
) {
388 (base::string16(kTestPolicyKey
) + base::ASCIIToUTF16("\\") +
389 UTF8ToUTF16(policy_name
)).c_str(),
391 ASSERT_TRUE(key
.Valid());
393 for (base::ListValue::const_iterator
element(policy_value
->begin());
394 element
!= policy_value
->end();
396 std::string element_value
;
397 if (!(*element
)->GetAsString(&element_value
))
399 std::string
name(base::IntToString(index
++));
400 key
.WriteValue(UTF8ToUTF16(name
).c_str(),
401 UTF8ToUTF16(element_value
).c_str());
405 void RegistryTestHarness::InstallDictionaryPolicy(
406 const std::string
& policy_name
,
407 const base::DictionaryValue
* policy_value
) {
409 base::JSONWriter::Write(policy_value
, &json
);
410 RegKey
key(hive_
, kTestPolicyKey
, KEY_ALL_ACCESS
);
411 ASSERT_TRUE(key
.Valid());
412 key
.WriteValue(UTF8ToUTF16(policy_name
).c_str(),
413 UTF8ToUTF16(json
).c_str());
416 void RegistryTestHarness::Install3rdPartyPolicy(
417 const base::DictionaryValue
* policies
) {
418 // The first level entries are domains, and the second level entries map
419 // components to their policy.
420 const base::string16 kPathPrefix
=
421 base::string16(kTestPolicyKey
) + kPathSep
+ kThirdParty
+ kPathSep
;
422 for (base::DictionaryValue::Iterator
domain(*policies
);
423 !domain
.IsAtEnd(); domain
.Advance()) {
424 const base::DictionaryValue
* components
= NULL
;
425 if (!domain
.value().GetAsDictionary(&components
)) {
429 for (base::DictionaryValue::Iterator
component(*components
);
430 !component
.IsAtEnd(); component
.Advance()) {
431 const base::string16 path
= kPathPrefix
+
432 UTF8ToUTF16(domain
.key()) + kPathSep
+ UTF8ToUTF16(component
.key());
433 InstallValue(component
.value(), hive_
, path
, kMandatory
);
438 DWORD
RegistryTestHarness::GetAppliedGPOList(DWORD flags
,
439 LPCTSTR machine_name
,
441 GUID
* extension_guid
,
442 PGROUP_POLICY_OBJECT
* gpo_list
) {
444 return ERROR_ACCESS_DENIED
;
447 BOOL
RegistryTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) {
452 PolicyProviderTestHarness
* RegistryTestHarness::CreateHKCU() {
453 return new RegistryTestHarness(HKEY_CURRENT_USER
, POLICY_SCOPE_USER
);
457 PolicyProviderTestHarness
* RegistryTestHarness::CreateHKLM() {
458 return new RegistryTestHarness(HKEY_LOCAL_MACHINE
, POLICY_SCOPE_MACHINE
);
461 PRegTestHarness::PRegTestHarness()
462 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
) {}
464 PRegTestHarness::~PRegTestHarness() {}
466 void PRegTestHarness::SetUp() {
467 base::win::SetDomainStateForTesting(false);
468 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
469 preg_file_path_
= temp_dir_
.path().Append(PolicyLoaderWin::kPRegFileName
);
470 ASSERT_TRUE(base::WriteFile(preg_file_path_
,
471 preg_parser::kPRegFileHeader
,
472 arraysize(preg_parser::kPRegFileHeader
)));
474 memset(&gpo_
, 0, sizeof(GROUP_POLICY_OBJECT
));
475 gpo_
.lpFileSysPath
= const_cast<wchar_t*>(temp_dir_
.path().value().c_str());
478 ConfigurationPolicyProvider
* PRegTestHarness::CreateProvider(
479 SchemaRegistry
* registry
,
480 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) {
481 scoped_ptr
<AsyncPolicyLoader
> loader(
482 new PolicyLoaderWin(task_runner
, kTestPolicyKey
, this));
483 return new AsyncPolicyProvider(registry
, loader
.Pass());
486 void PRegTestHarness::InstallEmptyPolicy() {}
488 void PRegTestHarness::InstallStringPolicy(const std::string
& policy_name
,
489 const std::string
& policy_value
) {
490 AppendStringToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
493 void PRegTestHarness::InstallIntegerPolicy(const std::string
& policy_name
,
495 AppendDWORDToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
498 void PRegTestHarness::InstallBooleanPolicy(const std::string
& policy_name
,
500 AppendDWORDToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
503 void PRegTestHarness::InstallStringListPolicy(
504 const std::string
& policy_name
,
505 const base::ListValue
* policy_value
) {
506 AppendPolicyToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
509 void PRegTestHarness::InstallDictionaryPolicy(
510 const std::string
& policy_name
,
511 const base::DictionaryValue
* policy_value
) {
513 base::JSONWriter::Write(policy_value
, &json
);
514 AppendStringToPRegFile(kTestPolicyKey
, policy_name
, json
);
517 void PRegTestHarness::Install3rdPartyPolicy(
518 const base::DictionaryValue
* policies
) {
519 // The first level entries are domains, and the second level entries map
520 // components to their policy.
521 const base::string16 kPathPrefix
=
522 base::string16(kTestPolicyKey
) + kPathSep
+ kThirdParty
+ kPathSep
;
523 for (base::DictionaryValue::Iterator
domain(*policies
);
524 !domain
.IsAtEnd(); domain
.Advance()) {
525 const base::DictionaryValue
* components
= NULL
;
526 if (!domain
.value().GetAsDictionary(&components
)) {
530 const base::string16 domain_path
= kPathPrefix
+ UTF8ToUTF16(domain
.key());
531 for (base::DictionaryValue::Iterator
component(*components
);
532 !component
.IsAtEnd(); component
.Advance()) {
533 const base::string16 component_path
=
534 domain_path
+ kPathSep
+ UTF8ToUTF16(component
.key());
535 AppendPolicyToPRegFile(component_path
, UTF16ToUTF8(kMandatory
),
541 DWORD
PRegTestHarness::GetAppliedGPOList(DWORD flags
,
542 LPCTSTR machine_name
,
544 GUID
* extension_guid
,
545 PGROUP_POLICY_OBJECT
* gpo_list
) {
546 *gpo_list
= flags
& GPO_LIST_FLAG_MACHINE
? &gpo_
: NULL
;
547 return ERROR_SUCCESS
;
550 BOOL
PRegTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) {
555 PolicyProviderTestHarness
* PRegTestHarness::Create() {
556 return new PRegTestHarness();
560 void PRegTestHarness::AppendChars(std::vector
<uint8
>* buffer
,
561 const base::string16
& chars
) {
562 for (base::string16::const_iterator
c(chars
.begin()); c
!= chars
.end(); ++c
) {
563 buffer
->push_back(*c
& 0xff);
564 buffer
->push_back((*c
>> 8) & 0xff);
568 void PRegTestHarness::AppendRecordToPRegFile(const base::string16
& path
,
569 const std::string
& key
,
573 std::vector
<uint8
> buffer
;
574 AppendChars(&buffer
, L
"[");
575 AppendChars(&buffer
, path
);
576 AppendChars(&buffer
, base::string16(L
"\0;", 2));
577 AppendChars(&buffer
, UTF8ToUTF16(key
));
578 AppendChars(&buffer
, base::string16(L
"\0;", 2));
579 type
= base::ByteSwapToLE32(type
);
580 uint8
* type_data
= reinterpret_cast<uint8
*>(&type
);
581 buffer
.insert(buffer
.end(), type_data
, type_data
+ sizeof(DWORD
));
582 AppendChars(&buffer
, L
";");
583 size
= base::ByteSwapToLE32(size
);
584 uint8
* size_data
= reinterpret_cast<uint8
*>(&size
);
585 buffer
.insert(buffer
.end(), size_data
, size_data
+ sizeof(DWORD
));
586 AppendChars(&buffer
, L
";");
587 buffer
.insert(buffer
.end(), data
, data
+ size
);
588 AppendChars(&buffer
, L
"]");
590 ASSERT_TRUE(base::AppendToFile(
592 reinterpret_cast<const char*>(vector_as_array(&buffer
)),
596 void PRegTestHarness::AppendDWORDToPRegFile(const base::string16
& path
,
597 const std::string
& key
,
599 value
= base::ByteSwapToLE32(value
);
600 AppendRecordToPRegFile(path
, key
, REG_DWORD
, sizeof(DWORD
),
601 reinterpret_cast<uint8
*>(&value
));
604 void PRegTestHarness::AppendStringToPRegFile(const base::string16
& path
,
605 const std::string
& key
,
606 const std::string
& value
) {
607 base::string16
string16_value(UTF8ToUTF16(value
));
608 std::vector
<base::char16
> data
;
609 std::transform(string16_value
.begin(), string16_value
.end(),
610 std::back_inserter(data
), std::ptr_fun(base::ByteSwapToLE16
));
611 data
.push_back(base::ByteSwapToLE16(L
'\0'));
613 AppendRecordToPRegFile(path
, key
, REG_SZ
, data
.size() * sizeof(base::char16
),
614 reinterpret_cast<uint8
*>(vector_as_array(&data
)));
617 void PRegTestHarness::AppendPolicyToPRegFile(const base::string16
& path
,
618 const std::string
& key
,
619 const base::Value
* value
) {
620 switch (value
->GetType()) {
621 case base::Value::TYPE_BOOLEAN
: {
622 bool boolean_value
= false;
623 ASSERT_TRUE(value
->GetAsBoolean(&boolean_value
));
624 AppendDWORDToPRegFile(path
, key
, boolean_value
);
627 case base::Value::TYPE_INTEGER
: {
629 ASSERT_TRUE(value
->GetAsInteger(&int_value
));
630 AppendDWORDToPRegFile(path
, key
, int_value
);
633 case base::Value::TYPE_DOUBLE
: {
634 double double_value
= 0;
635 ASSERT_TRUE(value
->GetAsDouble(&double_value
));
636 AppendStringToPRegFile(path
, key
, base::DoubleToString(double_value
));
639 case base::Value::TYPE_STRING
: {
640 std::string string_value
;
641 ASSERT_TRUE(value
->GetAsString(&string_value
));
642 AppendStringToPRegFile(path
, key
, string_value
);
645 case base::Value::TYPE_DICTIONARY
: {
646 base::string16 subpath
= path
+ kPathSep
+ UTF8ToUTF16(key
);
647 const base::DictionaryValue
* dict
= NULL
;
648 ASSERT_TRUE(value
->GetAsDictionary(&dict
));
649 for (base::DictionaryValue::Iterator
entry(*dict
); !entry
.IsAtEnd();
651 AppendPolicyToPRegFile(subpath
, entry
.key(), &entry
.value());
655 case base::Value::TYPE_LIST
: {
656 base::string16 subpath
= path
+ kPathSep
+ UTF8ToUTF16(key
);
657 const base::ListValue
* list
= NULL
;
658 ASSERT_TRUE(value
->GetAsList(&list
));
659 for (size_t i
= 0; i
< list
->GetSize(); ++i
) {
660 const base::Value
* entry
= NULL
;
661 ASSERT_TRUE(list
->Get(i
, &entry
));
662 AppendPolicyToPRegFile(subpath
, base::IntToString(i
+ 1), entry
);
666 case base::Value::TYPE_BINARY
:
667 case base::Value::TYPE_NULL
: {
676 // Instantiate abstract test case for basic policy reading tests.
677 INSTANTIATE_TEST_CASE_P(
678 PolicyProviderWinTest
,
679 ConfigurationPolicyProviderTest
,
680 testing::Values(RegistryTestHarness::CreateHKCU
,
681 RegistryTestHarness::CreateHKLM
,
682 PRegTestHarness::Create
));
684 // Instantiate abstract test case for 3rd party policy reading tests.
685 INSTANTIATE_TEST_CASE_P(
686 ThirdPartyPolicyProviderWinTest
,
687 Configuration3rdPartyPolicyProviderTest
,
688 testing::Values(RegistryTestHarness::CreateHKCU
,
689 RegistryTestHarness::CreateHKLM
,
690 PRegTestHarness::Create
));
692 // Test cases for windows policy provider specific functionality.
693 class PolicyLoaderWinTest
: public PolicyTestBase
,
694 public AppliedGPOListProvider
{
696 // The policy key this tests places data under. This must match the data
697 // files in chrome/test/data/policy/gpo.
698 static const base::char16 kTestPolicyKey
[];
700 PolicyLoaderWinTest()
702 gpo_list_status_(ERROR_ACCESS_DENIED
) {}
703 virtual ~PolicyLoaderWinTest() {}
705 virtual void SetUp() override
{
706 base::win::SetDomainStateForTesting(false);
707 PolicyTestBase::SetUp();
709 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &test_data_dir_
));
710 test_data_dir_
= test_data_dir_
.AppendASCII("chrome")
713 .AppendASCII("policy")
716 gpo_list_provider_
= this;
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
,
747 scoped_ptr
<PolicyBundle
> loaded(
748 loader
.InitialLoad(schema_registry_
.schema_map()));
749 return loaded
->Equals(expected
);
752 void InstallRegistrySentinel() {
753 RegKey
hklm_key(HKEY_CURRENT_USER
, kTestPolicyKey
, KEY_ALL_ACCESS
);
754 ASSERT_TRUE(hklm_key
.Valid());
756 UTF8ToUTF16(test_keys::kKeyString
).c_str(),
757 UTF8ToUTF16("registry").c_str());
760 bool MatchesRegistrySentinel() {
761 base::DictionaryValue expected_policy
;
762 expected_policy
.SetString(test_keys::kKeyString
, "registry");
763 PolicyBundle expected
;
764 expected
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
765 .LoadFrom(&expected_policy
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
);
766 return Matches(expected
);
769 bool MatchesTestBundle() {
770 base::DictionaryValue expected_policy
;
771 expected_policy
.SetBoolean(test_keys::kKeyBoolean
, true);
772 expected_policy
.SetString(test_keys::kKeyString
, "GPO");
773 expected_policy
.SetInteger(test_keys::kKeyInteger
, 42);
774 scoped_ptr
<base::ListValue
> list(new base::ListValue());
775 list
->AppendString("GPO 1");
776 list
->AppendString("GPO 2");
777 expected_policy
.Set(test_keys::kKeyStringList
, list
.release());
778 PolicyBundle expected
;
779 expected
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
780 .LoadFrom(&expected_policy
, POLICY_LEVEL_MANDATORY
,
781 POLICY_SCOPE_MACHINE
);
782 return Matches(expected
);
785 ScopedGroupPolicyRegistrySandbox registry_sandbox_
;
786 PGROUP_POLICY_OBJECT gpo_list_
;
787 DWORD gpo_list_status_
;
788 base::FilePath test_data_dir_
;
789 AppliedGPOListProvider
* gpo_list_provider_
;
792 const base::char16
PolicyLoaderWinTest::kTestPolicyKey
[] =
793 L
"SOFTWARE\\Policies\\Chromium";
795 TEST_F(PolicyLoaderWinTest
, HKLMOverHKCU
) {
796 RegKey
hklm_key(HKEY_LOCAL_MACHINE
, kTestPolicyKey
, KEY_ALL_ACCESS
);
797 ASSERT_TRUE(hklm_key
.Valid());
798 hklm_key
.WriteValue(UTF8ToUTF16(test_keys::kKeyString
).c_str(),
799 UTF8ToUTF16("hklm").c_str());
800 RegKey
hkcu_key(HKEY_CURRENT_USER
, kTestPolicyKey
, KEY_ALL_ACCESS
);
801 ASSERT_TRUE(hkcu_key
.Valid());
802 hkcu_key
.WriteValue(UTF8ToUTF16(test_keys::kKeyString
).c_str(),
803 UTF8ToUTF16("hkcu").c_str());
805 PolicyBundle expected
;
806 expected
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
807 .Set(test_keys::kKeyString
,
808 POLICY_LEVEL_MANDATORY
,
809 POLICY_SCOPE_MACHINE
,
810 new base::StringValue("hklm"),
812 EXPECT_TRUE(Matches(expected
));
815 TEST_F(PolicyLoaderWinTest
, Merge3rdPartyPolicies
) {
816 // Policy for the same extension will be provided at the 4 level/scope
817 // combinations, to verify that they overlap as expected.
818 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "merge");
819 ASSERT_TRUE(RegisterSchema(
822 " \"type\": \"object\","
824 " \"a\": { \"type\": \"string\" },"
825 " \"b\": { \"type\": \"string\" },"
826 " \"c\": { \"type\": \"string\" },"
827 " \"d\": { \"type\": \"string\" }"
831 const base::string16 kPathSuffix
=
832 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\merge");
834 const char kUserMandatory
[] = "user-mandatory";
835 const char kUserRecommended
[] = "user-recommended";
836 const char kMachineMandatory
[] = "machine-mandatory";
837 const char kMachineRecommended
[] = "machine-recommended";
839 base::DictionaryValue policy
;
840 policy
.SetString("a", kMachineMandatory
);
841 EXPECT_TRUE(InstallValue(policy
, HKEY_LOCAL_MACHINE
,
842 kPathSuffix
, kMandatory
));
843 policy
.SetString("a", kUserMandatory
);
844 policy
.SetString("b", kUserMandatory
);
845 EXPECT_TRUE(InstallValue(policy
, HKEY_CURRENT_USER
,
846 kPathSuffix
, kMandatory
));
847 policy
.SetString("a", kMachineRecommended
);
848 policy
.SetString("b", kMachineRecommended
);
849 policy
.SetString("c", kMachineRecommended
);
850 EXPECT_TRUE(InstallValue(policy
, HKEY_LOCAL_MACHINE
,
851 kPathSuffix
, kRecommended
));
852 policy
.SetString("a", kUserRecommended
);
853 policy
.SetString("b", kUserRecommended
);
854 policy
.SetString("c", kUserRecommended
);
855 policy
.SetString("d", kUserRecommended
);
856 EXPECT_TRUE(InstallValue(policy
, HKEY_CURRENT_USER
,
857 kPathSuffix
, kRecommended
));
859 PolicyBundle expected
;
860 PolicyMap
& expected_policy
= expected
.Get(ns
);
861 expected_policy
.Set("a",
862 POLICY_LEVEL_MANDATORY
,
863 POLICY_SCOPE_MACHINE
,
864 new base::StringValue(kMachineMandatory
),
866 expected_policy
.Set("b",
867 POLICY_LEVEL_MANDATORY
,
869 new base::StringValue(kUserMandatory
),
871 expected_policy
.Set("c",
872 POLICY_LEVEL_RECOMMENDED
,
873 POLICY_SCOPE_MACHINE
,
874 new base::StringValue(kMachineRecommended
),
876 expected_policy
.Set("d",
877 POLICY_LEVEL_RECOMMENDED
,
879 new base::StringValue(kUserRecommended
),
881 EXPECT_TRUE(Matches(expected
));
884 TEST_F(PolicyLoaderWinTest
, LoadStringEncodedValues
) {
885 // Create a dictionary with all the types that can be stored encoded in a
887 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "string");
888 ASSERT_TRUE(RegisterSchema(
891 " \"type\": \"object\","
892 " \"id\": \"MainType\","
894 " \"null\": { \"type\": \"null\" },"
895 " \"bool\": { \"type\": \"boolean\" },"
896 " \"int\": { \"type\": \"integer\" },"
897 " \"double\": { \"type\": \"number\" },"
899 " \"type\": \"array\","
900 " \"items\": { \"$ref\": \"MainType\" }"
902 " \"dict\": { \"$ref\": \"MainType\" }"
906 base::DictionaryValue policy
;
907 policy
.Set("null", base::Value::CreateNullValue());
908 policy
.SetBoolean("bool", true);
909 policy
.SetInteger("int", -123);
910 policy
.SetDouble("double", 456.78e9
);
911 base::ListValue list
;
912 list
.Append(policy
.DeepCopy());
913 list
.Append(policy
.DeepCopy());
914 policy
.Set("list", list
.DeepCopy());
915 // Encode |policy| before adding the "dict" entry.
916 std::string encoded_dict
;
917 base::JSONWriter::Write(&policy
, &encoded_dict
);
918 ASSERT_FALSE(encoded_dict
.empty());
919 policy
.Set("dict", policy
.DeepCopy());
920 std::string encoded_list
;
921 base::JSONWriter::Write(&list
, &encoded_list
);
922 ASSERT_FALSE(encoded_list
.empty());
923 base::DictionaryValue encoded_policy
;
924 encoded_policy
.SetString("null", "");
925 encoded_policy
.SetString("bool", "1");
926 encoded_policy
.SetString("int", "-123");
927 encoded_policy
.SetString("double", "456.78e9");
928 encoded_policy
.SetString("list", encoded_list
);
929 encoded_policy
.SetString("dict", encoded_dict
);
931 const base::string16 kPathSuffix
=
932 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\string");
934 InstallValue(encoded_policy
, HKEY_CURRENT_USER
, kPathSuffix
, kMandatory
));
936 PolicyBundle expected
;
937 expected
.Get(ns
).LoadFrom(&policy
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
);
938 EXPECT_TRUE(Matches(expected
));
941 TEST_F(PolicyLoaderWinTest
, LoadIntegerEncodedValues
) {
942 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "int");
943 ASSERT_TRUE(RegisterSchema(
946 " \"type\": \"object\","
948 " \"bool\": { \"type\": \"boolean\" },"
949 " \"int\": { \"type\": \"integer\" },"
950 " \"double\": { \"type\": \"number\" }"
954 base::DictionaryValue encoded_policy
;
955 encoded_policy
.SetInteger("bool", 1);
956 encoded_policy
.SetInteger("int", 123);
957 encoded_policy
.SetInteger("double", 456);
959 const base::string16 kPathSuffix
=
960 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\int");
962 InstallValue(encoded_policy
, HKEY_CURRENT_USER
, kPathSuffix
, kMandatory
));
964 base::DictionaryValue policy
;
965 policy
.SetBoolean("bool", true);
966 policy
.SetInteger("int", 123);
967 policy
.SetDouble("double", 456.0);
968 PolicyBundle expected
;
969 expected
.Get(ns
).LoadFrom(&policy
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
);
970 EXPECT_TRUE(Matches(expected
));
973 TEST_F(PolicyLoaderWinTest
, DefaultPropertySchemaType
) {
974 // Build a schema for an "object" with a default schema for its properties.
975 // Note that the top-level object can't have "additionalProperties", so
976 // a "policy" property is used instead.
977 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "test");
978 ASSERT_TRUE(RegisterSchema(
981 " \"type\": \"object\","
984 " \"type\": \"object\","
986 " \"special-int1\": { \"type\": \"integer\" },"
987 " \"special-int2\": { \"type\": \"integer\" }"
989 " \"additionalProperties\": { \"type\": \"number\" }"
994 // Write some test values.
995 base::DictionaryValue policy
;
996 // These special values have a specific schema for them.
997 policy
.SetInteger("special-int1", 123);
998 policy
.SetString("special-int2", "-456");
999 // Other values default to be loaded as doubles.
1000 policy
.SetInteger("double1", 789.0);
1001 policy
.SetString("double2", "123.456e7");
1002 policy
.SetString("invalid", "omg");
1003 base::DictionaryValue all_policies
;
1004 all_policies
.Set("policy", policy
.DeepCopy());
1006 const base::string16 kPathSuffix
=
1007 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\test");
1009 InstallValue(all_policies
, HKEY_CURRENT_USER
, kPathSuffix
, kMandatory
));
1011 base::DictionaryValue expected_policy
;
1012 expected_policy
.SetInteger("special-int1", 123);
1013 expected_policy
.SetInteger("special-int2", -456);
1014 expected_policy
.SetDouble("double1", 789.0);
1015 expected_policy
.SetDouble("double2", 123.456e7
);
1016 base::DictionaryValue expected_policies
;
1017 expected_policies
.Set("policy", expected_policy
.DeepCopy());
1018 PolicyBundle expected
;
1019 expected
.Get(ns
).LoadFrom(
1020 &expected_policies
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
);
1021 EXPECT_TRUE(Matches(expected
));
1024 TEST_F(PolicyLoaderWinTest
, AppliedPolicyNotPresent
) {
1025 InstallRegistrySentinel();
1027 gpo_list_status_
= ERROR_SUCCESS
;
1030 EXPECT_TRUE(Matches(empty
));
1033 TEST_F(PolicyLoaderWinTest
, AppliedPolicyEmpty
) {
1034 InstallRegistrySentinel();
1035 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("empty"));
1036 GROUP_POLICY_OBJECT gpo
;
1037 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1039 gpo_list_status_
= ERROR_SUCCESS
;
1042 EXPECT_TRUE(Matches(empty
));
1045 TEST_F(PolicyLoaderWinTest
, AppliedPolicyInDomain
) {
1046 base::win::SetDomainStateForTesting(true);
1047 InstallRegistrySentinel();
1048 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("empty"));
1049 GROUP_POLICY_OBJECT gpo
;
1050 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1052 gpo_list_status_
= ERROR_SUCCESS
;
1054 EXPECT_TRUE(MatchesRegistrySentinel());
1057 TEST_F(PolicyLoaderWinTest
, GpoProviderNotSpecified
) {
1058 base::win::SetDomainStateForTesting(false);
1059 InstallRegistrySentinel();
1060 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("empty"));
1061 GROUP_POLICY_OBJECT gpo
;
1062 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1064 gpo_list_status_
= ERROR_SUCCESS
;
1065 gpo_list_provider_
= nullptr;
1067 EXPECT_TRUE(MatchesRegistrySentinel());
1070 TEST_F(PolicyLoaderWinTest
, AppliedPolicyNonExistingFile
) {
1071 InstallRegistrySentinel();
1072 GROUP_POLICY_OBJECT gpo
;
1073 InitGPO(&gpo
, 0, test_data_dir_
, NULL
, NULL
);
1075 gpo_list_status_
= ERROR_SUCCESS
;
1077 EXPECT_TRUE(MatchesRegistrySentinel());
1080 TEST_F(PolicyLoaderWinTest
, AppliedPolicyBadPath
) {
1081 InstallRegistrySentinel();
1082 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("bad"));
1083 GROUP_POLICY_OBJECT gpo
;
1084 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1086 gpo_list_status_
= ERROR_SUCCESS
;
1088 EXPECT_TRUE(MatchesRegistrySentinel());
1091 TEST_F(PolicyLoaderWinTest
, AppliedPolicyPresent
) {
1092 InstallRegistrySentinel();
1093 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("test1"));
1094 GROUP_POLICY_OBJECT gpo
;
1095 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1097 gpo_list_status_
= ERROR_SUCCESS
;
1099 EXPECT_TRUE(MatchesTestBundle());
1102 TEST_F(PolicyLoaderWinTest
, AppliedPolicyMerged
) {
1103 InstallRegistrySentinel();
1104 base::FilePath
gpo1_dir(test_data_dir_
.AppendASCII("test2"));
1105 base::FilePath
gpo2_dir(test_data_dir_
.AppendASCII("test1"));
1106 GROUP_POLICY_OBJECT gpo1
;
1107 GROUP_POLICY_OBJECT gpo2
;
1108 InitGPO(&gpo1
, 0, gpo1_dir
, &gpo2
, NULL
);
1109 InitGPO(&gpo2
, 0, gpo2_dir
, NULL
, &gpo1
);
1111 gpo_list_status_
= ERROR_SUCCESS
;
1113 EXPECT_TRUE(MatchesTestBundle());
1116 TEST_F(PolicyLoaderWinTest
, AppliedPolicyDisabled
) {
1117 InstallRegistrySentinel();
1118 base::FilePath
gpo1_dir(test_data_dir_
.AppendASCII("test1"));
1119 base::FilePath
gpo2_dir(test_data_dir_
.AppendASCII("test2"));
1120 GROUP_POLICY_OBJECT gpo1
;
1121 GROUP_POLICY_OBJECT gpo2
;
1122 InitGPO(&gpo1
, 0, gpo1_dir
, &gpo2
, NULL
);
1123 InitGPO(&gpo2
, GPO_FLAG_DISABLE
, gpo2_dir
, NULL
, &gpo1
);
1125 gpo_list_status_
= ERROR_SUCCESS
;
1127 EXPECT_TRUE(MatchesTestBundle());
1130 TEST_F(PolicyLoaderWinTest
, AppliedPolicyForcedPolicy
) {
1131 InstallRegistrySentinel();
1132 base::FilePath
gpo1_dir(test_data_dir_
.AppendASCII("test1"));
1133 base::FilePath
gpo2_dir(test_data_dir_
.AppendASCII("test2"));
1134 GROUP_POLICY_OBJECT gpo1
;
1135 GROUP_POLICY_OBJECT gpo2
;
1136 InitGPO(&gpo1
, GPO_FLAG_FORCE
, gpo1_dir
, &gpo2
, NULL
);
1137 InitGPO(&gpo2
, 0, gpo2_dir
, NULL
, &gpo1
);
1139 gpo_list_status_
= ERROR_SUCCESS
;
1141 EXPECT_TRUE(MatchesTestBundle());
1144 TEST_F(PolicyLoaderWinTest
, AppliedPolicyUNCPath
) {
1145 InstallRegistrySentinel();
1146 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("test1"));
1147 base::FilePath
unc_path(L
"\\\\some_share\\GPO");
1148 GROUP_POLICY_OBJECT gpo1
;
1149 GROUP_POLICY_OBJECT gpo2
;
1150 InitGPO(&gpo1
, 0, gpo_dir
, &gpo2
, NULL
);
1151 InitGPO(&gpo2
, 0, unc_path
, NULL
, &gpo1
);
1153 gpo_list_status_
= ERROR_SUCCESS
;
1155 EXPECT_TRUE(MatchesRegistrySentinel());
1158 TEST_F(PolicyLoaderWinTest
, LoadExtensionPolicyAlternativeSpelling
) {
1159 base::FilePath
gpo_dir(
1160 test_data_dir_
.AppendASCII("extension_alternative_spelling"));
1161 GROUP_POLICY_OBJECT gpo
;
1162 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1164 gpo_list_status_
= ERROR_SUCCESS
;
1166 const char kTestSchema
[] =
1168 " \"type\": \"object\","
1169 " \"properties\": {"
1170 " \"policy 1\": { \"type\": \"integer\" },"
1171 " \"policy 2\": { \"type\": \"integer\" }"
1174 const PolicyNamespace
ns_a(
1175 POLICY_DOMAIN_EXTENSIONS
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
1176 const PolicyNamespace
ns_b(
1177 POLICY_DOMAIN_EXTENSIONS
, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
1178 ASSERT_TRUE(RegisterSchema(ns_a
, kTestSchema
));
1179 ASSERT_TRUE(RegisterSchema(ns_b
, kTestSchema
));
1181 PolicyBundle expected
;
1182 base::DictionaryValue expected_a
;
1183 expected_a
.SetInteger("policy 1", 3);
1184 expected_a
.SetInteger("policy 2", 3);
1185 expected
.Get(ns_a
).LoadFrom(
1186 &expected_a
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
);
1187 base::DictionaryValue expected_b
;
1188 expected_b
.SetInteger("policy 1", 2);
1189 expected
.Get(ns_b
).LoadFrom(
1190 &expected_b
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
);
1191 EXPECT_TRUE(Matches(expected
));
1194 TEST_F(PolicyLoaderWinTest
, LBSSupport
) {
1195 const PolicyNamespace
ns(
1196 POLICY_DOMAIN_EXTENSIONS
, "heildphpnddilhkemkielfhnkaagiabh");
1197 schema_registry_
.RegisterComponent(ns
, Schema());
1199 const char kIncompleteSchema
[] =
1201 " \"type\": \"object\","
1202 " \"properties\": {"
1203 " \"url_list\": { \"type\": \"array\" },"
1204 " \"url_greylist\": { \"type\": \"array\" }"
1208 const base::string16 kPathSuffix
=
1209 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions");
1211 base::ListValue list
;
1212 list
.AppendString("youtube.com");
1213 base::DictionaryValue policy
;
1214 policy
.Set("url_list", list
.DeepCopy());
1215 policy
.SetString("alternative_browser_path", "c:\\legacy\\browser.exe");
1216 base::DictionaryValue root
;
1217 root
.Set(base::UTF16ToUTF8(kMandatory
), policy
.DeepCopy());
1218 root
.SetString(kSchema
, kIncompleteSchema
);
1219 EXPECT_TRUE(InstallValue(root
, HKEY_LOCAL_MACHINE
,
1220 kPathSuffix
, base::ASCIIToUTF16(ns
.component_id
)));
1222 PolicyBundle expected
;
1223 PolicyMap
& expected_policy
= expected
.Get(ns
);
1224 expected_policy
.Set("alternative_browser_path",
1225 POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
,
1226 new base::StringValue("c:\\legacy\\browser.exe"), NULL
);
1227 expected_policy
.Set("url_list", POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
,
1228 list
.DeepCopy(), NULL
);
1229 EXPECT_TRUE(Matches(expected
));
1232 } // namespace policy