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 ~RegistryTestHarness() override
;
175 // PolicyProviderTestHarness:
176 void SetUp() override
;
178 ConfigurationPolicyProvider
* CreateProvider(
179 SchemaRegistry
* registry
,
180 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) override
;
182 void InstallEmptyPolicy() override
;
183 void InstallStringPolicy(const std::string
& policy_name
,
184 const std::string
& policy_value
) override
;
185 void InstallIntegerPolicy(const std::string
& policy_name
,
186 int policy_value
) override
;
187 void InstallBooleanPolicy(const std::string
& policy_name
,
188 bool policy_value
) override
;
189 void InstallStringListPolicy(const std::string
& policy_name
,
190 const base::ListValue
* policy_value
) override
;
191 void InstallDictionaryPolicy(
192 const std::string
& policy_name
,
193 const base::DictionaryValue
* policy_value
) override
;
194 void Install3rdPartyPolicy(const base::DictionaryValue
* policies
) override
;
196 // AppliedGPOListProvider:
197 DWORD
GetAppliedGPOList(DWORD flags
,
198 LPCTSTR machine_name
,
200 GUID
* extension_guid
,
201 PGROUP_POLICY_OBJECT
* gpo_list
) override
;
202 BOOL
FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) override
;
204 // Creates a harness instance that will install policy in HKCU or HKLM,
206 static PolicyProviderTestHarness
* CreateHKCU();
207 static PolicyProviderTestHarness
* CreateHKLM();
212 ScopedGroupPolicyRegistrySandbox registry_sandbox_
;
214 DISALLOW_COPY_AND_ASSIGN(RegistryTestHarness
);
217 // A test harness that generates PReg files for the provider to read.
218 class PRegTestHarness
: public PolicyProviderTestHarness
,
219 public AppliedGPOListProvider
{
222 ~PRegTestHarness() override
;
224 // PolicyProviderTestHarness:
225 void SetUp() override
;
227 ConfigurationPolicyProvider
* CreateProvider(
228 SchemaRegistry
* registry
,
229 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) override
;
231 void InstallEmptyPolicy() override
;
232 void InstallStringPolicy(const std::string
& policy_name
,
233 const std::string
& policy_value
) override
;
234 void InstallIntegerPolicy(const std::string
& policy_name
,
235 int policy_value
) override
;
236 void InstallBooleanPolicy(const std::string
& policy_name
,
237 bool policy_value
) override
;
238 void InstallStringListPolicy(const std::string
& policy_name
,
239 const base::ListValue
* policy_value
) override
;
240 void InstallDictionaryPolicy(
241 const std::string
& policy_name
,
242 const base::DictionaryValue
* policy_value
) override
;
243 void Install3rdPartyPolicy(const base::DictionaryValue
* policies
) override
;
245 // AppliedGPOListProvider:
246 DWORD
GetAppliedGPOList(DWORD flags
,
247 LPCTSTR machine_name
,
249 GUID
* extension_guid
,
250 PGROUP_POLICY_OBJECT
* gpo_list
) override
;
251 BOOL
FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) override
;
253 // Creates a harness instance.
254 static PolicyProviderTestHarness
* Create();
257 // Helper to append a base::string16 to an uint8 buffer.
258 static void AppendChars(std::vector
<uint8
>* buffer
,
259 const base::string16
& chars
);
261 // Appends a record with the given fields to the PReg file.
262 void AppendRecordToPRegFile(const base::string16
& path
,
263 const std::string
& key
,
268 // Appends the given DWORD |value| for |path| + |key| to the PReg file.
269 void AppendDWORDToPRegFile(const base::string16
& path
,
270 const std::string
& key
,
273 // Appends the given string |value| for |path| + |key| to the PReg file.
274 void AppendStringToPRegFile(const base::string16
& path
,
275 const std::string
& key
,
276 const std::string
& value
);
278 // Appends the given policy |value| for |path| + |key| to the PReg file,
279 // converting and recursing as necessary.
280 void AppendPolicyToPRegFile(const base::string16
& path
,
281 const std::string
& key
,
282 const base::Value
* value
);
284 base::ScopedTempDir temp_dir_
;
285 base::FilePath preg_file_path_
;
286 GROUP_POLICY_OBJECT gpo_
;
288 DISALLOW_COPY_AND_ASSIGN(PRegTestHarness
);
291 ScopedGroupPolicyRegistrySandbox::ScopedGroupPolicyRegistrySandbox() {
292 // Generate a unique registry key for the override for each test. This
293 // makes sure that tests executing in parallel won't delete each other's
294 // key, at DeleteKeys().
295 key_name_
= base::ASCIIToUTF16(base::StringPrintf(
296 "SOFTWARE\\chromium unittest %d", base::GetCurrentProcId()));
297 std::wstring hklm_key_name
= key_name_
+ L
"\\HKLM";
298 std::wstring hkcu_key_name
= key_name_
+ L
"\\HKCU";
300 // Create the subkeys to hold the overridden HKLM and HKCU
302 temp_hklm_hive_key_
.Create(HKEY_CURRENT_USER
,
303 hklm_key_name
.c_str(),
305 temp_hkcu_hive_key_
.Create(HKEY_CURRENT_USER
,
306 hkcu_key_name
.c_str(),
312 ScopedGroupPolicyRegistrySandbox::~ScopedGroupPolicyRegistrySandbox() {
317 void ScopedGroupPolicyRegistrySandbox::ActivateOverrides() {
318 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE
,
319 temp_hklm_hive_key_
.Handle()));
320 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER
,
321 temp_hkcu_hive_key_
.Handle()));
324 void ScopedGroupPolicyRegistrySandbox::RemoveOverrides() {
325 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE
, 0));
326 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER
, 0));
329 void ScopedGroupPolicyRegistrySandbox::DeleteKeys() {
330 RegKey
key(HKEY_CURRENT_USER
, key_name_
.c_str(), KEY_ALL_ACCESS
);
331 ASSERT_TRUE(key
.Valid());
335 RegistryTestHarness::RegistryTestHarness(HKEY hive
, PolicyScope scope
)
336 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY
, scope
), hive_(hive
) {}
338 RegistryTestHarness::~RegistryTestHarness() {}
340 void RegistryTestHarness::SetUp() {}
342 ConfigurationPolicyProvider
* RegistryTestHarness::CreateProvider(
343 SchemaRegistry
* registry
,
344 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) {
345 base::win::SetDomainStateForTesting(true);
346 scoped_ptr
<AsyncPolicyLoader
> loader(
347 new PolicyLoaderWin(task_runner
, kTestPolicyKey
, this));
348 return new AsyncPolicyProvider(registry
, loader
.Pass());
351 void RegistryTestHarness::InstallEmptyPolicy() {}
353 void RegistryTestHarness::InstallStringPolicy(
354 const std::string
& policy_name
,
355 const std::string
& policy_value
) {
356 RegKey
key(hive_
, kTestPolicyKey
, KEY_ALL_ACCESS
);
357 ASSERT_TRUE(key
.Valid());
358 ASSERT_HRESULT_SUCCEEDED(key
.WriteValue(UTF8ToUTF16(policy_name
).c_str(),
359 UTF8ToUTF16(policy_value
).c_str()));
362 void RegistryTestHarness::InstallIntegerPolicy(
363 const std::string
& policy_name
,
365 RegKey
key(hive_
, kTestPolicyKey
, KEY_ALL_ACCESS
);
366 ASSERT_TRUE(key
.Valid());
367 key
.WriteValue(UTF8ToUTF16(policy_name
).c_str(),
368 static_cast<DWORD
>(policy_value
));
371 void RegistryTestHarness::InstallBooleanPolicy(
372 const std::string
& policy_name
,
374 RegKey
key(hive_
, kTestPolicyKey
, KEY_ALL_ACCESS
);
375 ASSERT_TRUE(key
.Valid());
376 key
.WriteValue(UTF8ToUTF16(policy_name
).c_str(),
377 static_cast<DWORD
>(policy_value
));
380 void RegistryTestHarness::InstallStringListPolicy(
381 const std::string
& policy_name
,
382 const base::ListValue
* policy_value
) {
384 (base::string16(kTestPolicyKey
) + base::ASCIIToUTF16("\\") +
385 UTF8ToUTF16(policy_name
)).c_str(),
387 ASSERT_TRUE(key
.Valid());
389 for (base::ListValue::const_iterator
element(policy_value
->begin());
390 element
!= policy_value
->end();
392 std::string element_value
;
393 if (!(*element
)->GetAsString(&element_value
))
395 std::string
name(base::IntToString(index
++));
396 key
.WriteValue(UTF8ToUTF16(name
).c_str(),
397 UTF8ToUTF16(element_value
).c_str());
401 void RegistryTestHarness::InstallDictionaryPolicy(
402 const std::string
& policy_name
,
403 const base::DictionaryValue
* policy_value
) {
405 base::JSONWriter::Write(*policy_value
, &json
);
406 RegKey
key(hive_
, kTestPolicyKey
, KEY_ALL_ACCESS
);
407 ASSERT_TRUE(key
.Valid());
408 key
.WriteValue(UTF8ToUTF16(policy_name
).c_str(),
409 UTF8ToUTF16(json
).c_str());
412 void RegistryTestHarness::Install3rdPartyPolicy(
413 const base::DictionaryValue
* policies
) {
414 // The first level entries are domains, and the second level entries map
415 // components to their policy.
416 const base::string16 kPathPrefix
=
417 base::string16(kTestPolicyKey
) + kPathSep
+ kThirdParty
+ kPathSep
;
418 for (base::DictionaryValue::Iterator
domain(*policies
);
419 !domain
.IsAtEnd(); domain
.Advance()) {
420 const base::DictionaryValue
* components
= NULL
;
421 if (!domain
.value().GetAsDictionary(&components
)) {
425 for (base::DictionaryValue::Iterator
component(*components
);
426 !component
.IsAtEnd(); component
.Advance()) {
427 const base::string16 path
= kPathPrefix
+
428 UTF8ToUTF16(domain
.key()) + kPathSep
+ UTF8ToUTF16(component
.key());
429 InstallValue(component
.value(), hive_
, path
, kMandatory
);
434 DWORD
RegistryTestHarness::GetAppliedGPOList(DWORD flags
,
435 LPCTSTR machine_name
,
437 GUID
* extension_guid
,
438 PGROUP_POLICY_OBJECT
* gpo_list
) {
440 return ERROR_ACCESS_DENIED
;
443 BOOL
RegistryTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) {
448 PolicyProviderTestHarness
* RegistryTestHarness::CreateHKCU() {
449 return new RegistryTestHarness(HKEY_CURRENT_USER
, POLICY_SCOPE_USER
);
453 PolicyProviderTestHarness
* RegistryTestHarness::CreateHKLM() {
454 return new RegistryTestHarness(HKEY_LOCAL_MACHINE
, POLICY_SCOPE_MACHINE
);
457 PRegTestHarness::PRegTestHarness()
458 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
) {}
460 PRegTestHarness::~PRegTestHarness() {}
462 void PRegTestHarness::SetUp() {
463 base::win::SetDomainStateForTesting(false);
464 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
465 preg_file_path_
= temp_dir_
.path().Append(PolicyLoaderWin::kPRegFileName
);
466 ASSERT_TRUE(base::WriteFile(preg_file_path_
,
467 preg_parser::kPRegFileHeader
,
468 arraysize(preg_parser::kPRegFileHeader
)));
470 memset(&gpo_
, 0, sizeof(GROUP_POLICY_OBJECT
));
471 gpo_
.lpFileSysPath
= const_cast<wchar_t*>(temp_dir_
.path().value().c_str());
474 ConfigurationPolicyProvider
* PRegTestHarness::CreateProvider(
475 SchemaRegistry
* registry
,
476 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) {
477 scoped_ptr
<AsyncPolicyLoader
> loader(
478 new PolicyLoaderWin(task_runner
, kTestPolicyKey
, this));
479 return new AsyncPolicyProvider(registry
, loader
.Pass());
482 void PRegTestHarness::InstallEmptyPolicy() {}
484 void PRegTestHarness::InstallStringPolicy(const std::string
& policy_name
,
485 const std::string
& policy_value
) {
486 AppendStringToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
489 void PRegTestHarness::InstallIntegerPolicy(const std::string
& policy_name
,
491 AppendDWORDToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
494 void PRegTestHarness::InstallBooleanPolicy(const std::string
& policy_name
,
496 AppendDWORDToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
499 void PRegTestHarness::InstallStringListPolicy(
500 const std::string
& policy_name
,
501 const base::ListValue
* policy_value
) {
502 AppendPolicyToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
505 void PRegTestHarness::InstallDictionaryPolicy(
506 const std::string
& policy_name
,
507 const base::DictionaryValue
* policy_value
) {
509 base::JSONWriter::Write(*policy_value
, &json
);
510 AppendStringToPRegFile(kTestPolicyKey
, policy_name
, json
);
513 void PRegTestHarness::Install3rdPartyPolicy(
514 const base::DictionaryValue
* policies
) {
515 // The first level entries are domains, and the second level entries map
516 // components to their policy.
517 const base::string16 kPathPrefix
=
518 base::string16(kTestPolicyKey
) + kPathSep
+ kThirdParty
+ kPathSep
;
519 for (base::DictionaryValue::Iterator
domain(*policies
);
520 !domain
.IsAtEnd(); domain
.Advance()) {
521 const base::DictionaryValue
* components
= NULL
;
522 if (!domain
.value().GetAsDictionary(&components
)) {
526 const base::string16 domain_path
= kPathPrefix
+ UTF8ToUTF16(domain
.key());
527 for (base::DictionaryValue::Iterator
component(*components
);
528 !component
.IsAtEnd(); component
.Advance()) {
529 const base::string16 component_path
=
530 domain_path
+ kPathSep
+ UTF8ToUTF16(component
.key());
531 AppendPolicyToPRegFile(component_path
, UTF16ToUTF8(kMandatory
),
537 DWORD
PRegTestHarness::GetAppliedGPOList(DWORD flags
,
538 LPCTSTR machine_name
,
540 GUID
* extension_guid
,
541 PGROUP_POLICY_OBJECT
* gpo_list
) {
542 *gpo_list
= flags
& GPO_LIST_FLAG_MACHINE
? &gpo_
: NULL
;
543 return ERROR_SUCCESS
;
546 BOOL
PRegTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) {
551 PolicyProviderTestHarness
* PRegTestHarness::Create() {
552 return new PRegTestHarness();
556 void PRegTestHarness::AppendChars(std::vector
<uint8
>* buffer
,
557 const base::string16
& chars
) {
558 for (base::string16::const_iterator
c(chars
.begin()); c
!= chars
.end(); ++c
) {
559 buffer
->push_back(*c
& 0xff);
560 buffer
->push_back((*c
>> 8) & 0xff);
564 void PRegTestHarness::AppendRecordToPRegFile(const base::string16
& path
,
565 const std::string
& key
,
569 std::vector
<uint8
> buffer
;
570 AppendChars(&buffer
, L
"[");
571 AppendChars(&buffer
, path
);
572 AppendChars(&buffer
, base::string16(L
"\0;", 2));
573 AppendChars(&buffer
, UTF8ToUTF16(key
));
574 AppendChars(&buffer
, base::string16(L
"\0;", 2));
575 type
= base::ByteSwapToLE32(type
);
576 uint8
* type_data
= reinterpret_cast<uint8
*>(&type
);
577 buffer
.insert(buffer
.end(), type_data
, type_data
+ sizeof(DWORD
));
578 AppendChars(&buffer
, L
";");
579 size
= base::ByteSwapToLE32(size
);
580 uint8
* size_data
= reinterpret_cast<uint8
*>(&size
);
581 buffer
.insert(buffer
.end(), size_data
, size_data
+ sizeof(DWORD
));
582 AppendChars(&buffer
, L
";");
583 buffer
.insert(buffer
.end(), data
, data
+ size
);
584 AppendChars(&buffer
, L
"]");
586 ASSERT_TRUE(base::AppendToFile(
588 reinterpret_cast<const char*>(vector_as_array(&buffer
)),
592 void PRegTestHarness::AppendDWORDToPRegFile(const base::string16
& path
,
593 const std::string
& key
,
595 value
= base::ByteSwapToLE32(value
);
596 AppendRecordToPRegFile(path
, key
, REG_DWORD
, sizeof(DWORD
),
597 reinterpret_cast<uint8
*>(&value
));
600 void PRegTestHarness::AppendStringToPRegFile(const base::string16
& path
,
601 const std::string
& key
,
602 const std::string
& value
) {
603 base::string16
string16_value(UTF8ToUTF16(value
));
604 std::vector
<base::char16
> data
;
605 std::transform(string16_value
.begin(), string16_value
.end(),
606 std::back_inserter(data
), std::ptr_fun(base::ByteSwapToLE16
));
607 data
.push_back(base::ByteSwapToLE16(L
'\0'));
609 AppendRecordToPRegFile(path
, key
, REG_SZ
, data
.size() * sizeof(base::char16
),
610 reinterpret_cast<uint8
*>(vector_as_array(&data
)));
613 void PRegTestHarness::AppendPolicyToPRegFile(const base::string16
& path
,
614 const std::string
& key
,
615 const base::Value
* value
) {
616 switch (value
->GetType()) {
617 case base::Value::TYPE_BOOLEAN
: {
618 bool boolean_value
= false;
619 ASSERT_TRUE(value
->GetAsBoolean(&boolean_value
));
620 AppendDWORDToPRegFile(path
, key
, boolean_value
);
623 case base::Value::TYPE_INTEGER
: {
625 ASSERT_TRUE(value
->GetAsInteger(&int_value
));
626 AppendDWORDToPRegFile(path
, key
, int_value
);
629 case base::Value::TYPE_DOUBLE
: {
630 double double_value
= 0;
631 ASSERT_TRUE(value
->GetAsDouble(&double_value
));
632 AppendStringToPRegFile(path
, key
, base::DoubleToString(double_value
));
635 case base::Value::TYPE_STRING
: {
636 std::string string_value
;
637 ASSERT_TRUE(value
->GetAsString(&string_value
));
638 AppendStringToPRegFile(path
, key
, string_value
);
641 case base::Value::TYPE_DICTIONARY
: {
642 base::string16 subpath
= path
+ kPathSep
+ UTF8ToUTF16(key
);
643 const base::DictionaryValue
* dict
= NULL
;
644 ASSERT_TRUE(value
->GetAsDictionary(&dict
));
645 for (base::DictionaryValue::Iterator
entry(*dict
); !entry
.IsAtEnd();
647 AppendPolicyToPRegFile(subpath
, entry
.key(), &entry
.value());
651 case base::Value::TYPE_LIST
: {
652 base::string16 subpath
= path
+ kPathSep
+ UTF8ToUTF16(key
);
653 const base::ListValue
* list
= NULL
;
654 ASSERT_TRUE(value
->GetAsList(&list
));
655 for (size_t i
= 0; i
< list
->GetSize(); ++i
) {
656 const base::Value
* entry
= NULL
;
657 ASSERT_TRUE(list
->Get(i
, &entry
));
658 AppendPolicyToPRegFile(subpath
, base::IntToString(i
+ 1), entry
);
662 case base::Value::TYPE_BINARY
:
663 case base::Value::TYPE_NULL
: {
672 // Instantiate abstract test case for basic policy reading tests.
673 INSTANTIATE_TEST_CASE_P(
674 PolicyProviderWinTest
,
675 ConfigurationPolicyProviderTest
,
676 testing::Values(RegistryTestHarness::CreateHKCU
,
677 RegistryTestHarness::CreateHKLM
,
678 PRegTestHarness::Create
));
680 // Instantiate abstract test case for 3rd party policy reading tests.
681 INSTANTIATE_TEST_CASE_P(
682 ThirdPartyPolicyProviderWinTest
,
683 Configuration3rdPartyPolicyProviderTest
,
684 testing::Values(RegistryTestHarness::CreateHKCU
,
685 RegistryTestHarness::CreateHKLM
,
686 PRegTestHarness::Create
));
688 // Test cases for windows policy provider specific functionality.
689 class PolicyLoaderWinTest
: public PolicyTestBase
,
690 public AppliedGPOListProvider
{
692 // The policy key this tests places data under. This must match the data
693 // files in chrome/test/data/policy/gpo.
694 static const base::char16 kTestPolicyKey
[];
696 PolicyLoaderWinTest()
698 gpo_list_status_(ERROR_ACCESS_DENIED
) {}
699 ~PolicyLoaderWinTest() override
{}
701 void SetUp() override
{
702 base::win::SetDomainStateForTesting(false);
703 PolicyTestBase::SetUp();
705 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &test_data_dir_
));
706 test_data_dir_
= test_data_dir_
.AppendASCII("chrome")
709 .AppendASCII("policy")
712 gpo_list_provider_
= this;
715 // AppliedGPOListProvider:
716 DWORD
GetAppliedGPOList(DWORD flags
,
717 LPCTSTR machine_name
,
719 GUID
* extension_guid
,
720 PGROUP_POLICY_OBJECT
* gpo_list
) override
{
721 *gpo_list
= gpo_list_
;
722 return gpo_list_status_
;
724 BOOL
FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) override
{
728 void InitGPO(GROUP_POLICY_OBJECT
* gpo
,
730 const base::FilePath
& path
,
731 GROUP_POLICY_OBJECT
* next
,
732 GROUP_POLICY_OBJECT
* prev
) {
733 memset(gpo
, 0, sizeof(GROUP_POLICY_OBJECT
));
734 gpo
->dwOptions
= options
;
735 gpo
->lpFileSysPath
= const_cast<wchar_t*>(path
.value().c_str());
740 bool Matches(const PolicyBundle
& expected
) {
741 PolicyLoaderWin
loader(loop_
.task_runner(), kTestPolicyKey
,
743 scoped_ptr
<PolicyBundle
> loaded(
744 loader
.InitialLoad(schema_registry_
.schema_map()));
745 return loaded
->Equals(expected
);
748 void InstallRegistrySentinel() {
749 RegKey
hklm_key(HKEY_CURRENT_USER
, kTestPolicyKey
, KEY_ALL_ACCESS
);
750 ASSERT_TRUE(hklm_key
.Valid());
752 UTF8ToUTF16(test_keys::kKeyString
).c_str(),
753 UTF8ToUTF16("registry").c_str());
756 bool MatchesRegistrySentinel() {
757 base::DictionaryValue expected_policy
;
758 expected_policy
.SetString(test_keys::kKeyString
, "registry");
759 PolicyBundle expected
;
760 expected
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
761 .LoadFrom(&expected_policy
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
);
762 return Matches(expected
);
765 bool MatchesTestBundle() {
766 base::DictionaryValue expected_policy
;
767 expected_policy
.SetBoolean(test_keys::kKeyBoolean
, true);
768 expected_policy
.SetString(test_keys::kKeyString
, "GPO");
769 expected_policy
.SetInteger(test_keys::kKeyInteger
, 42);
770 scoped_ptr
<base::ListValue
> list(new base::ListValue());
771 list
->AppendString("GPO 1");
772 list
->AppendString("GPO 2");
773 expected_policy
.Set(test_keys::kKeyStringList
, list
.release());
774 PolicyBundle expected
;
775 expected
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
776 .LoadFrom(&expected_policy
, POLICY_LEVEL_MANDATORY
,
777 POLICY_SCOPE_MACHINE
);
778 return Matches(expected
);
781 ScopedGroupPolicyRegistrySandbox registry_sandbox_
;
782 PGROUP_POLICY_OBJECT gpo_list_
;
783 DWORD gpo_list_status_
;
784 base::FilePath test_data_dir_
;
785 AppliedGPOListProvider
* gpo_list_provider_
;
788 const base::char16
PolicyLoaderWinTest::kTestPolicyKey
[] =
789 L
"SOFTWARE\\Policies\\Chromium";
791 TEST_F(PolicyLoaderWinTest
, HKLMOverHKCU
) {
792 RegKey
hklm_key(HKEY_LOCAL_MACHINE
, kTestPolicyKey
, KEY_ALL_ACCESS
);
793 ASSERT_TRUE(hklm_key
.Valid());
794 hklm_key
.WriteValue(UTF8ToUTF16(test_keys::kKeyString
).c_str(),
795 UTF8ToUTF16("hklm").c_str());
796 RegKey
hkcu_key(HKEY_CURRENT_USER
, kTestPolicyKey
, KEY_ALL_ACCESS
);
797 ASSERT_TRUE(hkcu_key
.Valid());
798 hkcu_key
.WriteValue(UTF8ToUTF16(test_keys::kKeyString
).c_str(),
799 UTF8ToUTF16("hkcu").c_str());
801 PolicyBundle expected
;
802 expected
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
803 .Set(test_keys::kKeyString
,
804 POLICY_LEVEL_MANDATORY
,
805 POLICY_SCOPE_MACHINE
,
806 new base::StringValue("hklm"),
808 EXPECT_TRUE(Matches(expected
));
811 TEST_F(PolicyLoaderWinTest
, Merge3rdPartyPolicies
) {
812 // Policy for the same extension will be provided at the 4 level/scope
813 // combinations, to verify that they overlap as expected.
814 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "merge");
815 ASSERT_TRUE(RegisterSchema(
818 " \"type\": \"object\","
820 " \"a\": { \"type\": \"string\" },"
821 " \"b\": { \"type\": \"string\" },"
822 " \"c\": { \"type\": \"string\" },"
823 " \"d\": { \"type\": \"string\" }"
827 const base::string16 kPathSuffix
=
828 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\merge");
830 const char kUserMandatory
[] = "user-mandatory";
831 const char kUserRecommended
[] = "user-recommended";
832 const char kMachineMandatory
[] = "machine-mandatory";
833 const char kMachineRecommended
[] = "machine-recommended";
835 base::DictionaryValue policy
;
836 policy
.SetString("a", kMachineMandatory
);
837 EXPECT_TRUE(InstallValue(policy
, HKEY_LOCAL_MACHINE
,
838 kPathSuffix
, kMandatory
));
839 policy
.SetString("a", kUserMandatory
);
840 policy
.SetString("b", kUserMandatory
);
841 EXPECT_TRUE(InstallValue(policy
, HKEY_CURRENT_USER
,
842 kPathSuffix
, kMandatory
));
843 policy
.SetString("a", kMachineRecommended
);
844 policy
.SetString("b", kMachineRecommended
);
845 policy
.SetString("c", kMachineRecommended
);
846 EXPECT_TRUE(InstallValue(policy
, HKEY_LOCAL_MACHINE
,
847 kPathSuffix
, kRecommended
));
848 policy
.SetString("a", kUserRecommended
);
849 policy
.SetString("b", kUserRecommended
);
850 policy
.SetString("c", kUserRecommended
);
851 policy
.SetString("d", kUserRecommended
);
852 EXPECT_TRUE(InstallValue(policy
, HKEY_CURRENT_USER
,
853 kPathSuffix
, kRecommended
));
855 PolicyBundle expected
;
856 PolicyMap
& expected_policy
= expected
.Get(ns
);
857 expected_policy
.Set("a",
858 POLICY_LEVEL_MANDATORY
,
859 POLICY_SCOPE_MACHINE
,
860 new base::StringValue(kMachineMandatory
),
862 expected_policy
.Set("b",
863 POLICY_LEVEL_MANDATORY
,
865 new base::StringValue(kUserMandatory
),
867 expected_policy
.Set("c",
868 POLICY_LEVEL_RECOMMENDED
,
869 POLICY_SCOPE_MACHINE
,
870 new base::StringValue(kMachineRecommended
),
872 expected_policy
.Set("d",
873 POLICY_LEVEL_RECOMMENDED
,
875 new base::StringValue(kUserRecommended
),
877 EXPECT_TRUE(Matches(expected
));
880 TEST_F(PolicyLoaderWinTest
, LoadStringEncodedValues
) {
881 // Create a dictionary with all the types that can be stored encoded in a
883 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "string");
884 ASSERT_TRUE(RegisterSchema(
887 " \"type\": \"object\","
888 " \"id\": \"MainType\","
890 " \"null\": { \"type\": \"null\" },"
891 " \"bool\": { \"type\": \"boolean\" },"
892 " \"int\": { \"type\": \"integer\" },"
893 " \"double\": { \"type\": \"number\" },"
895 " \"type\": \"array\","
896 " \"items\": { \"$ref\": \"MainType\" }"
898 " \"dict\": { \"$ref\": \"MainType\" }"
902 base::DictionaryValue policy
;
903 policy
.Set("null", base::Value::CreateNullValue());
904 policy
.SetBoolean("bool", true);
905 policy
.SetInteger("int", -123);
906 policy
.SetDouble("double", 456.78e9
);
907 base::ListValue list
;
908 list
.Append(policy
.DeepCopy());
909 list
.Append(policy
.DeepCopy());
910 policy
.Set("list", list
.DeepCopy());
911 // Encode |policy| before adding the "dict" entry.
912 std::string encoded_dict
;
913 base::JSONWriter::Write(policy
, &encoded_dict
);
914 ASSERT_FALSE(encoded_dict
.empty());
915 policy
.Set("dict", policy
.DeepCopy());
916 std::string encoded_list
;
917 base::JSONWriter::Write(list
, &encoded_list
);
918 ASSERT_FALSE(encoded_list
.empty());
919 base::DictionaryValue encoded_policy
;
920 encoded_policy
.SetString("null", "");
921 encoded_policy
.SetString("bool", "1");
922 encoded_policy
.SetString("int", "-123");
923 encoded_policy
.SetString("double", "456.78e9");
924 encoded_policy
.SetString("list", encoded_list
);
925 encoded_policy
.SetString("dict", encoded_dict
);
927 const base::string16 kPathSuffix
=
928 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\string");
930 InstallValue(encoded_policy
, HKEY_CURRENT_USER
, kPathSuffix
, kMandatory
));
932 PolicyBundle expected
;
933 expected
.Get(ns
).LoadFrom(&policy
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
);
934 EXPECT_TRUE(Matches(expected
));
937 TEST_F(PolicyLoaderWinTest
, LoadIntegerEncodedValues
) {
938 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "int");
939 ASSERT_TRUE(RegisterSchema(
942 " \"type\": \"object\","
944 " \"bool\": { \"type\": \"boolean\" },"
945 " \"int\": { \"type\": \"integer\" },"
946 " \"double\": { \"type\": \"number\" }"
950 base::DictionaryValue encoded_policy
;
951 encoded_policy
.SetInteger("bool", 1);
952 encoded_policy
.SetInteger("int", 123);
953 encoded_policy
.SetInteger("double", 456);
955 const base::string16 kPathSuffix
=
956 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\int");
958 InstallValue(encoded_policy
, HKEY_CURRENT_USER
, kPathSuffix
, kMandatory
));
960 base::DictionaryValue policy
;
961 policy
.SetBoolean("bool", true);
962 policy
.SetInteger("int", 123);
963 policy
.SetDouble("double", 456.0);
964 PolicyBundle expected
;
965 expected
.Get(ns
).LoadFrom(&policy
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
);
966 EXPECT_TRUE(Matches(expected
));
969 TEST_F(PolicyLoaderWinTest
, DefaultPropertySchemaType
) {
970 // Build a schema for an "object" with a default schema for its properties.
971 // Note that the top-level object can't have "additionalProperties", so
972 // a "policy" property is used instead.
973 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "test");
974 ASSERT_TRUE(RegisterSchema(
977 " \"type\": \"object\","
980 " \"type\": \"object\","
982 " \"special-int1\": { \"type\": \"integer\" },"
983 " \"special-int2\": { \"type\": \"integer\" }"
985 " \"additionalProperties\": { \"type\": \"number\" }"
990 // Write some test values.
991 base::DictionaryValue policy
;
992 // These special values have a specific schema for them.
993 policy
.SetInteger("special-int1", 123);
994 policy
.SetString("special-int2", "-456");
995 // Other values default to be loaded as doubles.
996 policy
.SetInteger("double1", 789.0);
997 policy
.SetString("double2", "123.456e7");
998 policy
.SetString("invalid", "omg");
999 base::DictionaryValue all_policies
;
1000 all_policies
.Set("policy", policy
.DeepCopy());
1002 const base::string16 kPathSuffix
=
1003 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\test");
1005 InstallValue(all_policies
, HKEY_CURRENT_USER
, kPathSuffix
, kMandatory
));
1007 base::DictionaryValue expected_policy
;
1008 expected_policy
.SetInteger("special-int1", 123);
1009 expected_policy
.SetInteger("special-int2", -456);
1010 expected_policy
.SetDouble("double1", 789.0);
1011 expected_policy
.SetDouble("double2", 123.456e7
);
1012 base::DictionaryValue expected_policies
;
1013 expected_policies
.Set("policy", expected_policy
.DeepCopy());
1014 PolicyBundle expected
;
1015 expected
.Get(ns
).LoadFrom(
1016 &expected_policies
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
);
1017 EXPECT_TRUE(Matches(expected
));
1020 TEST_F(PolicyLoaderWinTest
, AppliedPolicyNotPresent
) {
1021 InstallRegistrySentinel();
1023 gpo_list_status_
= ERROR_SUCCESS
;
1026 EXPECT_TRUE(Matches(empty
));
1029 TEST_F(PolicyLoaderWinTest
, AppliedPolicyEmpty
) {
1030 InstallRegistrySentinel();
1031 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("empty"));
1032 GROUP_POLICY_OBJECT gpo
;
1033 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1035 gpo_list_status_
= ERROR_SUCCESS
;
1038 EXPECT_TRUE(Matches(empty
));
1041 TEST_F(PolicyLoaderWinTest
, AppliedPolicyInDomain
) {
1042 base::win::SetDomainStateForTesting(true);
1043 InstallRegistrySentinel();
1044 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("empty"));
1045 GROUP_POLICY_OBJECT gpo
;
1046 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1048 gpo_list_status_
= ERROR_SUCCESS
;
1050 EXPECT_TRUE(MatchesRegistrySentinel());
1053 TEST_F(PolicyLoaderWinTest
, GpoProviderNotSpecified
) {
1054 base::win::SetDomainStateForTesting(false);
1055 InstallRegistrySentinel();
1056 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("empty"));
1057 GROUP_POLICY_OBJECT gpo
;
1058 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1060 gpo_list_status_
= ERROR_SUCCESS
;
1061 gpo_list_provider_
= nullptr;
1063 EXPECT_TRUE(MatchesRegistrySentinel());
1066 TEST_F(PolicyLoaderWinTest
, AppliedPolicyNonExistingFile
) {
1067 InstallRegistrySentinel();
1068 GROUP_POLICY_OBJECT gpo
;
1069 InitGPO(&gpo
, 0, test_data_dir_
, NULL
, NULL
);
1071 gpo_list_status_
= ERROR_SUCCESS
;
1073 EXPECT_TRUE(MatchesRegistrySentinel());
1076 TEST_F(PolicyLoaderWinTest
, AppliedPolicyBadPath
) {
1077 InstallRegistrySentinel();
1078 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("bad"));
1079 GROUP_POLICY_OBJECT gpo
;
1080 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1082 gpo_list_status_
= ERROR_SUCCESS
;
1084 EXPECT_TRUE(MatchesRegistrySentinel());
1087 TEST_F(PolicyLoaderWinTest
, AppliedPolicyPresent
) {
1088 InstallRegistrySentinel();
1089 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("test1"));
1090 GROUP_POLICY_OBJECT gpo
;
1091 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1093 gpo_list_status_
= ERROR_SUCCESS
;
1095 EXPECT_TRUE(MatchesTestBundle());
1098 TEST_F(PolicyLoaderWinTest
, AppliedPolicyMerged
) {
1099 InstallRegistrySentinel();
1100 base::FilePath
gpo1_dir(test_data_dir_
.AppendASCII("test2"));
1101 base::FilePath
gpo2_dir(test_data_dir_
.AppendASCII("test1"));
1102 GROUP_POLICY_OBJECT gpo1
;
1103 GROUP_POLICY_OBJECT gpo2
;
1104 InitGPO(&gpo1
, 0, gpo1_dir
, &gpo2
, NULL
);
1105 InitGPO(&gpo2
, 0, gpo2_dir
, NULL
, &gpo1
);
1107 gpo_list_status_
= ERROR_SUCCESS
;
1109 EXPECT_TRUE(MatchesTestBundle());
1112 TEST_F(PolicyLoaderWinTest
, AppliedPolicyDisabled
) {
1113 InstallRegistrySentinel();
1114 base::FilePath
gpo1_dir(test_data_dir_
.AppendASCII("test1"));
1115 base::FilePath
gpo2_dir(test_data_dir_
.AppendASCII("test2"));
1116 GROUP_POLICY_OBJECT gpo1
;
1117 GROUP_POLICY_OBJECT gpo2
;
1118 InitGPO(&gpo1
, 0, gpo1_dir
, &gpo2
, NULL
);
1119 InitGPO(&gpo2
, GPO_FLAG_DISABLE
, gpo2_dir
, NULL
, &gpo1
);
1121 gpo_list_status_
= ERROR_SUCCESS
;
1123 EXPECT_TRUE(MatchesTestBundle());
1126 TEST_F(PolicyLoaderWinTest
, AppliedPolicyForcedPolicy
) {
1127 InstallRegistrySentinel();
1128 base::FilePath
gpo1_dir(test_data_dir_
.AppendASCII("test1"));
1129 base::FilePath
gpo2_dir(test_data_dir_
.AppendASCII("test2"));
1130 GROUP_POLICY_OBJECT gpo1
;
1131 GROUP_POLICY_OBJECT gpo2
;
1132 InitGPO(&gpo1
, GPO_FLAG_FORCE
, gpo1_dir
, &gpo2
, NULL
);
1133 InitGPO(&gpo2
, 0, gpo2_dir
, NULL
, &gpo1
);
1135 gpo_list_status_
= ERROR_SUCCESS
;
1137 EXPECT_TRUE(MatchesTestBundle());
1140 TEST_F(PolicyLoaderWinTest
, AppliedPolicyUNCPath
) {
1141 InstallRegistrySentinel();
1142 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("test1"));
1143 base::FilePath
unc_path(L
"\\\\some_share\\GPO");
1144 GROUP_POLICY_OBJECT gpo1
;
1145 GROUP_POLICY_OBJECT gpo2
;
1146 InitGPO(&gpo1
, 0, gpo_dir
, &gpo2
, NULL
);
1147 InitGPO(&gpo2
, 0, unc_path
, NULL
, &gpo1
);
1149 gpo_list_status_
= ERROR_SUCCESS
;
1151 EXPECT_TRUE(MatchesRegistrySentinel());
1154 TEST_F(PolicyLoaderWinTest
, LoadExtensionPolicyAlternativeSpelling
) {
1155 base::FilePath
gpo_dir(
1156 test_data_dir_
.AppendASCII("extension_alternative_spelling"));
1157 GROUP_POLICY_OBJECT gpo
;
1158 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1160 gpo_list_status_
= ERROR_SUCCESS
;
1162 const char kTestSchema
[] =
1164 " \"type\": \"object\","
1165 " \"properties\": {"
1166 " \"policy 1\": { \"type\": \"integer\" },"
1167 " \"policy 2\": { \"type\": \"integer\" }"
1170 const PolicyNamespace
ns_a(
1171 POLICY_DOMAIN_EXTENSIONS
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
1172 const PolicyNamespace
ns_b(
1173 POLICY_DOMAIN_EXTENSIONS
, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
1174 ASSERT_TRUE(RegisterSchema(ns_a
, kTestSchema
));
1175 ASSERT_TRUE(RegisterSchema(ns_b
, kTestSchema
));
1177 PolicyBundle expected
;
1178 base::DictionaryValue expected_a
;
1179 expected_a
.SetInteger("policy 1", 3);
1180 expected_a
.SetInteger("policy 2", 3);
1181 expected
.Get(ns_a
).LoadFrom(
1182 &expected_a
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
);
1183 base::DictionaryValue expected_b
;
1184 expected_b
.SetInteger("policy 1", 2);
1185 expected
.Get(ns_b
).LoadFrom(
1186 &expected_b
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
);
1187 EXPECT_TRUE(Matches(expected
));
1190 TEST_F(PolicyLoaderWinTest
, LBSSupport
) {
1191 const PolicyNamespace
ns(
1192 POLICY_DOMAIN_EXTENSIONS
, "heildphpnddilhkemkielfhnkaagiabh");
1193 schema_registry_
.RegisterComponent(ns
, Schema());
1195 const char kIncompleteSchema
[] =
1197 " \"type\": \"object\","
1198 " \"properties\": {"
1199 " \"url_list\": { \"type\": \"array\" },"
1200 " \"url_greylist\": { \"type\": \"array\" }"
1204 const base::string16 kPathSuffix
=
1205 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions");
1207 base::ListValue list
;
1208 list
.AppendString("youtube.com");
1209 base::DictionaryValue policy
;
1210 policy
.Set("url_list", list
.DeepCopy());
1211 policy
.SetString("alternative_browser_path", "c:\\legacy\\browser.exe");
1212 base::DictionaryValue root
;
1213 root
.Set(base::UTF16ToUTF8(kMandatory
), policy
.DeepCopy());
1214 root
.SetString(kSchema
, kIncompleteSchema
);
1215 EXPECT_TRUE(InstallValue(root
, HKEY_LOCAL_MACHINE
,
1216 kPathSuffix
, base::ASCIIToUTF16(ns
.component_id
)));
1218 PolicyBundle expected
;
1219 PolicyMap
& expected_policy
= expected
.Get(ns
);
1220 expected_policy
.Set("alternative_browser_path",
1221 POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
,
1222 new base::StringValue("c:\\legacy\\browser.exe"), NULL
);
1223 expected_policy
.Set("url_list", POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
,
1224 list
.DeepCopy(), NULL
);
1225 EXPECT_TRUE(Matches(expected
));
1228 } // namespace policy