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/policy_types.h"
38 #include "components/policy/core/common/preg_parser_win.h"
39 #include "components/policy/core/common/schema_map.h"
40 #include "testing/gtest/include/gtest/gtest.h"
42 using base::UTF8ToUTF16
;
43 using base::UTF16ToUTF8
;
44 using base::win::RegKey
;
50 // Constants for registry key names.
51 const wchar_t kPathSep
[] = L
"\\";
52 const wchar_t kThirdParty
[] = L
"3rdparty";
53 const wchar_t kMandatory
[] = L
"policy";
54 const wchar_t kRecommended
[] = L
"recommended";
55 const char kSchema
[] = "schema";
56 const wchar_t kTestPolicyKey
[] = L
"chrome.policy.key";
58 // Installs |value| in the given registry |path| and |hive|, under the key
59 // |name|. Returns false on errors.
60 // Some of the possible Value types are stored after a conversion (e.g. doubles
61 // are stored as strings), and can only be retrieved if a corresponding schema
63 bool InstallValue(const base::Value
& value
,
65 const base::string16
& path
,
66 const base::string16
& name
) {
67 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet.
68 RegKey
key(hive
, path
.c_str(), KEY_ALL_ACCESS
);
69 EXPECT_TRUE(key
.Valid());
70 switch (value
.GetType()) {
71 case base::Value::TYPE_NULL
:
72 return key
.WriteValue(name
.c_str(), L
"") == ERROR_SUCCESS
;
74 case base::Value::TYPE_BOOLEAN
: {
76 if (!value
.GetAsBoolean(&bool_value
))
78 return key
.WriteValue(name
.c_str(), bool_value
? 1 : 0) == ERROR_SUCCESS
;
81 case base::Value::TYPE_INTEGER
: {
83 if (!value
.GetAsInteger(&int_value
))
85 return key
.WriteValue(name
.c_str(), int_value
) == ERROR_SUCCESS
;
88 case base::Value::TYPE_DOUBLE
: {
90 if (!value
.GetAsDouble(&double_value
))
92 base::string16 str_value
=
93 UTF8ToUTF16(base::DoubleToString(double_value
));
94 return key
.WriteValue(name
.c_str(), str_value
.c_str()) == ERROR_SUCCESS
;
97 case base::Value::TYPE_STRING
: {
98 base::string16 str_value
;
99 if (!value
.GetAsString(&str_value
))
101 return key
.WriteValue(name
.c_str(), str_value
.c_str()) == ERROR_SUCCESS
;
104 case base::Value::TYPE_DICTIONARY
: {
105 const base::DictionaryValue
* sub_dict
= NULL
;
106 if (!value
.GetAsDictionary(&sub_dict
))
108 for (base::DictionaryValue::Iterator
it(*sub_dict
);
109 !it
.IsAtEnd(); it
.Advance()) {
110 if (!InstallValue(it
.value(), hive
, path
+ kPathSep
+ name
,
111 UTF8ToUTF16(it
.key()))) {
118 case base::Value::TYPE_LIST
: {
119 const base::ListValue
* list
= NULL
;
120 if (!value
.GetAsList(&list
))
122 for (size_t i
= 0; i
< list
->GetSize(); ++i
) {
123 const base::Value
* item
;
124 if (!list
->Get(i
, &item
))
126 if (!InstallValue(*item
, hive
, path
+ kPathSep
+ name
,
127 base::UintToString16(i
+ 1))) {
134 case base::Value::TYPE_BINARY
:
141 // This class provides sandboxing and mocking for the parts of the Windows
142 // Registry implementing Group Policy. It prepares two temporary sandbox keys,
143 // one for HKLM and one for HKCU. A test's calls to the registry are redirected
144 // by Windows to these sandboxes, allowing the tests to manipulate and access
145 // policy as if it were active, but without actually changing the parts of the
146 // Registry that are managed by Group Policy.
147 class ScopedGroupPolicyRegistrySandbox
{
149 ScopedGroupPolicyRegistrySandbox();
150 ~ScopedGroupPolicyRegistrySandbox();
153 void ActivateOverrides();
154 void RemoveOverrides();
156 // Deletes the sandbox keys.
159 base::string16 key_name_
;
161 // Keys are created for the lifetime of a test to contain
162 // the sandboxed HKCU and HKLM hives, respectively.
163 RegKey temp_hkcu_hive_key_
;
164 RegKey temp_hklm_hive_key_
;
166 DISALLOW_COPY_AND_ASSIGN(ScopedGroupPolicyRegistrySandbox
);
169 // A test harness that feeds policy via the Chrome GPO registry subtree.
170 class RegistryTestHarness
: public PolicyProviderTestHarness
,
171 public AppliedGPOListProvider
{
173 RegistryTestHarness(HKEY hive
, PolicyScope scope
);
174 ~RegistryTestHarness() override
;
176 // PolicyProviderTestHarness:
177 void SetUp() override
;
179 ConfigurationPolicyProvider
* CreateProvider(
180 SchemaRegistry
* registry
,
181 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) override
;
183 void InstallEmptyPolicy() override
;
184 void InstallStringPolicy(const std::string
& policy_name
,
185 const std::string
& policy_value
) override
;
186 void InstallIntegerPolicy(const std::string
& policy_name
,
187 int policy_value
) override
;
188 void InstallBooleanPolicy(const std::string
& policy_name
,
189 bool policy_value
) override
;
190 void InstallStringListPolicy(const std::string
& policy_name
,
191 const base::ListValue
* policy_value
) override
;
192 void InstallDictionaryPolicy(
193 const std::string
& policy_name
,
194 const base::DictionaryValue
* policy_value
) override
;
195 void Install3rdPartyPolicy(const base::DictionaryValue
* policies
) override
;
197 // AppliedGPOListProvider:
198 DWORD
GetAppliedGPOList(DWORD flags
,
199 LPCTSTR machine_name
,
201 GUID
* extension_guid
,
202 PGROUP_POLICY_OBJECT
* gpo_list
) override
;
203 BOOL
FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) override
;
205 // Creates a harness instance that will install policy in HKCU or HKLM,
207 static PolicyProviderTestHarness
* CreateHKCU();
208 static PolicyProviderTestHarness
* CreateHKLM();
213 ScopedGroupPolicyRegistrySandbox registry_sandbox_
;
215 DISALLOW_COPY_AND_ASSIGN(RegistryTestHarness
);
218 // A test harness that generates PReg files for the provider to read.
219 class PRegTestHarness
: public PolicyProviderTestHarness
,
220 public AppliedGPOListProvider
{
223 ~PRegTestHarness() override
;
225 // PolicyProviderTestHarness:
226 void SetUp() override
;
228 ConfigurationPolicyProvider
* CreateProvider(
229 SchemaRegistry
* registry
,
230 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) override
;
232 void InstallEmptyPolicy() override
;
233 void InstallStringPolicy(const std::string
& policy_name
,
234 const std::string
& policy_value
) override
;
235 void InstallIntegerPolicy(const std::string
& policy_name
,
236 int policy_value
) override
;
237 void InstallBooleanPolicy(const std::string
& policy_name
,
238 bool policy_value
) override
;
239 void InstallStringListPolicy(const std::string
& policy_name
,
240 const base::ListValue
* policy_value
) override
;
241 void InstallDictionaryPolicy(
242 const std::string
& policy_name
,
243 const base::DictionaryValue
* policy_value
) override
;
244 void Install3rdPartyPolicy(const base::DictionaryValue
* policies
) override
;
246 // AppliedGPOListProvider:
247 DWORD
GetAppliedGPOList(DWORD flags
,
248 LPCTSTR machine_name
,
250 GUID
* extension_guid
,
251 PGROUP_POLICY_OBJECT
* gpo_list
) override
;
252 BOOL
FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) override
;
254 // Creates a harness instance.
255 static PolicyProviderTestHarness
* Create();
258 // Helper to append a base::string16 to an uint8 buffer.
259 static void AppendChars(std::vector
<uint8
>* buffer
,
260 const base::string16
& chars
);
262 // Appends a record with the given fields to the PReg file.
263 void AppendRecordToPRegFile(const base::string16
& path
,
264 const std::string
& key
,
269 // Appends the given DWORD |value| for |path| + |key| to the PReg file.
270 void AppendDWORDToPRegFile(const base::string16
& path
,
271 const std::string
& key
,
274 // Appends the given string |value| for |path| + |key| to the PReg file.
275 void AppendStringToPRegFile(const base::string16
& path
,
276 const std::string
& key
,
277 const std::string
& value
);
279 // Appends the given policy |value| for |path| + |key| to the PReg file,
280 // converting and recursing as necessary.
281 void AppendPolicyToPRegFile(const base::string16
& path
,
282 const std::string
& key
,
283 const base::Value
* value
);
285 base::ScopedTempDir temp_dir_
;
286 base::FilePath preg_file_path_
;
287 GROUP_POLICY_OBJECT gpo_
;
289 DISALLOW_COPY_AND_ASSIGN(PRegTestHarness
);
292 ScopedGroupPolicyRegistrySandbox::ScopedGroupPolicyRegistrySandbox() {
293 // Generate a unique registry key for the override for each test. This
294 // makes sure that tests executing in parallel won't delete each other's
295 // key, at DeleteKeys().
296 key_name_
= base::ASCIIToUTF16(base::StringPrintf(
297 "SOFTWARE\\chromium unittest %d", base::GetCurrentProcId()));
298 std::wstring hklm_key_name
= key_name_
+ L
"\\HKLM";
299 std::wstring hkcu_key_name
= key_name_
+ L
"\\HKCU";
301 // Create the subkeys to hold the overridden HKLM and HKCU
303 temp_hklm_hive_key_
.Create(HKEY_CURRENT_USER
,
304 hklm_key_name
.c_str(),
306 temp_hkcu_hive_key_
.Create(HKEY_CURRENT_USER
,
307 hkcu_key_name
.c_str(),
313 ScopedGroupPolicyRegistrySandbox::~ScopedGroupPolicyRegistrySandbox() {
318 void ScopedGroupPolicyRegistrySandbox::ActivateOverrides() {
319 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE
,
320 temp_hklm_hive_key_
.Handle()));
321 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER
,
322 temp_hkcu_hive_key_
.Handle()));
325 void ScopedGroupPolicyRegistrySandbox::RemoveOverrides() {
326 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE
, 0));
327 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER
, 0));
330 void ScopedGroupPolicyRegistrySandbox::DeleteKeys() {
331 RegKey
key(HKEY_CURRENT_USER
, key_name_
.c_str(), KEY_ALL_ACCESS
);
332 ASSERT_TRUE(key
.Valid());
336 RegistryTestHarness::RegistryTestHarness(HKEY hive
, PolicyScope scope
)
337 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY
, scope
,
338 POLICY_SOURCE_PLATFORM
),
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
,
463 POLICY_SOURCE_PLATFORM
) {
466 PRegTestHarness::~PRegTestHarness() {}
468 void PRegTestHarness::SetUp() {
469 base::win::SetDomainStateForTesting(false);
470 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
471 preg_file_path_
= temp_dir_
.path().Append(PolicyLoaderWin::kPRegFileName
);
472 ASSERT_TRUE(base::WriteFile(preg_file_path_
,
473 preg_parser::kPRegFileHeader
,
474 arraysize(preg_parser::kPRegFileHeader
)));
476 memset(&gpo_
, 0, sizeof(GROUP_POLICY_OBJECT
));
477 gpo_
.lpFileSysPath
= const_cast<wchar_t*>(temp_dir_
.path().value().c_str());
480 ConfigurationPolicyProvider
* PRegTestHarness::CreateProvider(
481 SchemaRegistry
* registry
,
482 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) {
483 scoped_ptr
<AsyncPolicyLoader
> loader(
484 new PolicyLoaderWin(task_runner
, kTestPolicyKey
, this));
485 return new AsyncPolicyProvider(registry
, loader
.Pass());
488 void PRegTestHarness::InstallEmptyPolicy() {}
490 void PRegTestHarness::InstallStringPolicy(const std::string
& policy_name
,
491 const std::string
& policy_value
) {
492 AppendStringToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
495 void PRegTestHarness::InstallIntegerPolicy(const std::string
& policy_name
,
497 AppendDWORDToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
500 void PRegTestHarness::InstallBooleanPolicy(const std::string
& policy_name
,
502 AppendDWORDToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
505 void PRegTestHarness::InstallStringListPolicy(
506 const std::string
& policy_name
,
507 const base::ListValue
* policy_value
) {
508 AppendPolicyToPRegFile(kTestPolicyKey
, policy_name
, policy_value
);
511 void PRegTestHarness::InstallDictionaryPolicy(
512 const std::string
& policy_name
,
513 const base::DictionaryValue
* policy_value
) {
515 base::JSONWriter::Write(*policy_value
, &json
);
516 AppendStringToPRegFile(kTestPolicyKey
, policy_name
, json
);
519 void PRegTestHarness::Install3rdPartyPolicy(
520 const base::DictionaryValue
* policies
) {
521 // The first level entries are domains, and the second level entries map
522 // components to their policy.
523 const base::string16 kPathPrefix
=
524 base::string16(kTestPolicyKey
) + kPathSep
+ kThirdParty
+ kPathSep
;
525 for (base::DictionaryValue::Iterator
domain(*policies
);
526 !domain
.IsAtEnd(); domain
.Advance()) {
527 const base::DictionaryValue
* components
= NULL
;
528 if (!domain
.value().GetAsDictionary(&components
)) {
532 const base::string16 domain_path
= kPathPrefix
+ UTF8ToUTF16(domain
.key());
533 for (base::DictionaryValue::Iterator
component(*components
);
534 !component
.IsAtEnd(); component
.Advance()) {
535 const base::string16 component_path
=
536 domain_path
+ kPathSep
+ UTF8ToUTF16(component
.key());
537 AppendPolicyToPRegFile(component_path
, UTF16ToUTF8(kMandatory
),
543 DWORD
PRegTestHarness::GetAppliedGPOList(DWORD flags
,
544 LPCTSTR machine_name
,
546 GUID
* extension_guid
,
547 PGROUP_POLICY_OBJECT
* gpo_list
) {
548 *gpo_list
= flags
& GPO_LIST_FLAG_MACHINE
? &gpo_
: NULL
;
549 return ERROR_SUCCESS
;
552 BOOL
PRegTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) {
557 PolicyProviderTestHarness
* PRegTestHarness::Create() {
558 return new PRegTestHarness();
562 void PRegTestHarness::AppendChars(std::vector
<uint8
>* buffer
,
563 const base::string16
& chars
) {
564 for (base::string16::const_iterator
c(chars
.begin()); c
!= chars
.end(); ++c
) {
565 buffer
->push_back(*c
& 0xff);
566 buffer
->push_back((*c
>> 8) & 0xff);
570 void PRegTestHarness::AppendRecordToPRegFile(const base::string16
& path
,
571 const std::string
& key
,
575 std::vector
<uint8
> buffer
;
576 AppendChars(&buffer
, L
"[");
577 AppendChars(&buffer
, path
);
578 AppendChars(&buffer
, base::string16(L
"\0;", 2));
579 AppendChars(&buffer
, UTF8ToUTF16(key
));
580 AppendChars(&buffer
, base::string16(L
"\0;", 2));
581 type
= base::ByteSwapToLE32(type
);
582 uint8
* type_data
= reinterpret_cast<uint8
*>(&type
);
583 buffer
.insert(buffer
.end(), type_data
, type_data
+ sizeof(DWORD
));
584 AppendChars(&buffer
, L
";");
585 size
= base::ByteSwapToLE32(size
);
586 uint8
* size_data
= reinterpret_cast<uint8
*>(&size
);
587 buffer
.insert(buffer
.end(), size_data
, size_data
+ sizeof(DWORD
));
588 AppendChars(&buffer
, L
";");
589 buffer
.insert(buffer
.end(), data
, data
+ size
);
590 AppendChars(&buffer
, L
"]");
592 ASSERT_TRUE(base::AppendToFile(
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 ~PolicyLoaderWinTest() override
{}
707 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")
718 gpo_list_provider_
= this;
721 // AppliedGPOListProvider:
722 DWORD
GetAppliedGPOList(DWORD flags
,
723 LPCTSTR machine_name
,
725 GUID
* extension_guid
,
726 PGROUP_POLICY_OBJECT
* gpo_list
) override
{
727 *gpo_list
= gpo_list_
;
728 return gpo_list_status_
;
730 BOOL
FreeGPOList(PGROUP_POLICY_OBJECT gpo_list
) override
{
734 void InitGPO(GROUP_POLICY_OBJECT
* gpo
,
736 const base::FilePath
& path
,
737 GROUP_POLICY_OBJECT
* next
,
738 GROUP_POLICY_OBJECT
* prev
) {
739 memset(gpo
, 0, sizeof(GROUP_POLICY_OBJECT
));
740 gpo
->dwOptions
= options
;
741 gpo
->lpFileSysPath
= const_cast<wchar_t*>(path
.value().c_str());
746 bool Matches(const PolicyBundle
& expected
) {
747 PolicyLoaderWin
loader(loop_
.task_runner(), kTestPolicyKey
,
749 scoped_ptr
<PolicyBundle
> loaded(
750 loader
.InitialLoad(schema_registry_
.schema_map()));
751 return loaded
->Equals(expected
);
754 void InstallRegistrySentinel() {
755 RegKey
hklm_key(HKEY_CURRENT_USER
, kTestPolicyKey
, KEY_ALL_ACCESS
);
756 ASSERT_TRUE(hklm_key
.Valid());
758 UTF8ToUTF16(test_keys::kKeyString
).c_str(),
759 UTF8ToUTF16("registry").c_str());
762 bool MatchesRegistrySentinel() {
763 base::DictionaryValue expected_policy
;
764 expected_policy
.SetString(test_keys::kKeyString
, "registry");
765 PolicyBundle expected
;
766 expected
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
767 .LoadFrom(&expected_policy
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
,
768 POLICY_SOURCE_PLATFORM
);
769 return Matches(expected
);
772 bool MatchesTestBundle() {
773 base::DictionaryValue expected_policy
;
774 expected_policy
.SetBoolean(test_keys::kKeyBoolean
, true);
775 expected_policy
.SetString(test_keys::kKeyString
, "GPO");
776 expected_policy
.SetInteger(test_keys::kKeyInteger
, 42);
777 scoped_ptr
<base::ListValue
> list(new base::ListValue());
778 list
->AppendString("GPO 1");
779 list
->AppendString("GPO 2");
780 expected_policy
.Set(test_keys::kKeyStringList
, list
.release());
781 PolicyBundle expected
;
782 expected
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
783 .LoadFrom(&expected_policy
, POLICY_LEVEL_MANDATORY
,
784 POLICY_SCOPE_MACHINE
, POLICY_SOURCE_PLATFORM
);
785 return Matches(expected
);
788 ScopedGroupPolicyRegistrySandbox registry_sandbox_
;
789 PGROUP_POLICY_OBJECT gpo_list_
;
790 DWORD gpo_list_status_
;
791 base::FilePath test_data_dir_
;
792 AppliedGPOListProvider
* gpo_list_provider_
;
795 const base::char16
PolicyLoaderWinTest::kTestPolicyKey
[] =
796 L
"SOFTWARE\\Policies\\Chromium";
798 TEST_F(PolicyLoaderWinTest
, HKLMOverHKCU
) {
799 RegKey
hklm_key(HKEY_LOCAL_MACHINE
, kTestPolicyKey
, KEY_ALL_ACCESS
);
800 ASSERT_TRUE(hklm_key
.Valid());
801 hklm_key
.WriteValue(UTF8ToUTF16(test_keys::kKeyString
).c_str(),
802 UTF8ToUTF16("hklm").c_str());
803 RegKey
hkcu_key(HKEY_CURRENT_USER
, kTestPolicyKey
, KEY_ALL_ACCESS
);
804 ASSERT_TRUE(hkcu_key
.Valid());
805 hkcu_key
.WriteValue(UTF8ToUTF16(test_keys::kKeyString
).c_str(),
806 UTF8ToUTF16("hkcu").c_str());
808 PolicyBundle expected
;
809 expected
.Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
810 .Set(test_keys::kKeyString
,
811 POLICY_LEVEL_MANDATORY
,
812 POLICY_SCOPE_MACHINE
,
813 POLICY_SOURCE_PLATFORM
,
814 new base::StringValue("hklm"),
816 EXPECT_TRUE(Matches(expected
));
819 TEST_F(PolicyLoaderWinTest
, Merge3rdPartyPolicies
) {
820 // Policy for the same extension will be provided at the 4 level/scope
821 // combinations, to verify that they overlap as expected.
822 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "merge");
823 ASSERT_TRUE(RegisterSchema(
826 " \"type\": \"object\","
828 " \"a\": { \"type\": \"string\" },"
829 " \"b\": { \"type\": \"string\" },"
830 " \"c\": { \"type\": \"string\" },"
831 " \"d\": { \"type\": \"string\" }"
835 const base::string16 kPathSuffix
=
836 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\merge");
838 const char kUserMandatory
[] = "user-mandatory";
839 const char kUserRecommended
[] = "user-recommended";
840 const char kMachineMandatory
[] = "machine-mandatory";
841 const char kMachineRecommended
[] = "machine-recommended";
843 base::DictionaryValue policy
;
844 policy
.SetString("a", kMachineMandatory
);
845 EXPECT_TRUE(InstallValue(policy
, HKEY_LOCAL_MACHINE
,
846 kPathSuffix
, kMandatory
));
847 policy
.SetString("a", kUserMandatory
);
848 policy
.SetString("b", kUserMandatory
);
849 EXPECT_TRUE(InstallValue(policy
, HKEY_CURRENT_USER
,
850 kPathSuffix
, kMandatory
));
851 policy
.SetString("a", kMachineRecommended
);
852 policy
.SetString("b", kMachineRecommended
);
853 policy
.SetString("c", kMachineRecommended
);
854 EXPECT_TRUE(InstallValue(policy
, HKEY_LOCAL_MACHINE
,
855 kPathSuffix
, kRecommended
));
856 policy
.SetString("a", kUserRecommended
);
857 policy
.SetString("b", kUserRecommended
);
858 policy
.SetString("c", kUserRecommended
);
859 policy
.SetString("d", kUserRecommended
);
860 EXPECT_TRUE(InstallValue(policy
, HKEY_CURRENT_USER
,
861 kPathSuffix
, kRecommended
));
863 PolicyBundle expected
;
864 PolicyMap
& expected_policy
= expected
.Get(ns
);
865 expected_policy
.Set("a",
866 POLICY_LEVEL_MANDATORY
,
867 POLICY_SCOPE_MACHINE
,
868 POLICY_SOURCE_PLATFORM
,
869 new base::StringValue(kMachineMandatory
),
871 expected_policy
.Set("b",
872 POLICY_LEVEL_MANDATORY
,
874 POLICY_SOURCE_PLATFORM
,
875 new base::StringValue(kUserMandatory
),
877 expected_policy
.Set("c",
878 POLICY_LEVEL_RECOMMENDED
,
879 POLICY_SCOPE_MACHINE
,
880 POLICY_SOURCE_PLATFORM
,
881 new base::StringValue(kMachineRecommended
),
883 expected_policy
.Set("d",
884 POLICY_LEVEL_RECOMMENDED
,
886 POLICY_SOURCE_PLATFORM
,
887 new base::StringValue(kUserRecommended
),
889 EXPECT_TRUE(Matches(expected
));
892 TEST_F(PolicyLoaderWinTest
, LoadStringEncodedValues
) {
893 // Create a dictionary with all the types that can be stored encoded in a
895 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "string");
896 ASSERT_TRUE(RegisterSchema(
899 " \"type\": \"object\","
900 " \"id\": \"MainType\","
902 " \"null\": { \"type\": \"null\" },"
903 " \"bool\": { \"type\": \"boolean\" },"
904 " \"int\": { \"type\": \"integer\" },"
905 " \"double\": { \"type\": \"number\" },"
907 " \"type\": \"array\","
908 " \"items\": { \"$ref\": \"MainType\" }"
910 " \"dict\": { \"$ref\": \"MainType\" }"
914 base::DictionaryValue policy
;
915 policy
.Set("null", base::Value::CreateNullValue());
916 policy
.SetBoolean("bool", true);
917 policy
.SetInteger("int", -123);
918 policy
.SetDouble("double", 456.78e9
);
919 base::ListValue list
;
920 list
.Append(policy
.DeepCopy());
921 list
.Append(policy
.DeepCopy());
922 policy
.Set("list", list
.DeepCopy());
923 // Encode |policy| before adding the "dict" entry.
924 std::string encoded_dict
;
925 base::JSONWriter::Write(policy
, &encoded_dict
);
926 ASSERT_FALSE(encoded_dict
.empty());
927 policy
.Set("dict", policy
.DeepCopy());
928 std::string encoded_list
;
929 base::JSONWriter::Write(list
, &encoded_list
);
930 ASSERT_FALSE(encoded_list
.empty());
931 base::DictionaryValue encoded_policy
;
932 encoded_policy
.SetString("null", "");
933 encoded_policy
.SetString("bool", "1");
934 encoded_policy
.SetString("int", "-123");
935 encoded_policy
.SetString("double", "456.78e9");
936 encoded_policy
.SetString("list", encoded_list
);
937 encoded_policy
.SetString("dict", encoded_dict
);
939 const base::string16 kPathSuffix
=
940 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\string");
942 InstallValue(encoded_policy
, HKEY_CURRENT_USER
, kPathSuffix
, kMandatory
));
944 PolicyBundle expected
;
945 expected
.Get(ns
).LoadFrom(&policy
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
,
946 POLICY_SOURCE_PLATFORM
);
947 EXPECT_TRUE(Matches(expected
));
950 TEST_F(PolicyLoaderWinTest
, LoadIntegerEncodedValues
) {
951 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "int");
952 ASSERT_TRUE(RegisterSchema(
955 " \"type\": \"object\","
957 " \"bool\": { \"type\": \"boolean\" },"
958 " \"int\": { \"type\": \"integer\" },"
959 " \"double\": { \"type\": \"number\" }"
963 base::DictionaryValue encoded_policy
;
964 encoded_policy
.SetInteger("bool", 1);
965 encoded_policy
.SetInteger("int", 123);
966 encoded_policy
.SetInteger("double", 456);
968 const base::string16 kPathSuffix
=
969 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\int");
971 InstallValue(encoded_policy
, HKEY_CURRENT_USER
, kPathSuffix
, kMandatory
));
973 base::DictionaryValue policy
;
974 policy
.SetBoolean("bool", true);
975 policy
.SetInteger("int", 123);
976 policy
.SetDouble("double", 456.0);
977 PolicyBundle expected
;
978 expected
.Get(ns
).LoadFrom(&policy
, POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
,
979 POLICY_SOURCE_PLATFORM
);
980 EXPECT_TRUE(Matches(expected
));
983 TEST_F(PolicyLoaderWinTest
, DefaultPropertySchemaType
) {
984 // Build a schema for an "object" with a default schema for its properties.
985 // Note that the top-level object can't have "additionalProperties", so
986 // a "policy" property is used instead.
987 const PolicyNamespace
ns(POLICY_DOMAIN_EXTENSIONS
, "test");
988 ASSERT_TRUE(RegisterSchema(
991 " \"type\": \"object\","
994 " \"type\": \"object\","
996 " \"special-int1\": { \"type\": \"integer\" },"
997 " \"special-int2\": { \"type\": \"integer\" }"
999 " \"additionalProperties\": { \"type\": \"number\" }"
1004 // Write some test values.
1005 base::DictionaryValue policy
;
1006 // These special values have a specific schema for them.
1007 policy
.SetInteger("special-int1", 123);
1008 policy
.SetString("special-int2", "-456");
1009 // Other values default to be loaded as doubles.
1010 policy
.SetInteger("double1", 789.0);
1011 policy
.SetString("double2", "123.456e7");
1012 policy
.SetString("invalid", "omg");
1013 base::DictionaryValue all_policies
;
1014 all_policies
.Set("policy", policy
.DeepCopy());
1016 const base::string16 kPathSuffix
=
1017 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions\\test");
1019 InstallValue(all_policies
, HKEY_CURRENT_USER
, kPathSuffix
, kMandatory
));
1021 base::DictionaryValue expected_policy
;
1022 expected_policy
.SetInteger("special-int1", 123);
1023 expected_policy
.SetInteger("special-int2", -456);
1024 expected_policy
.SetDouble("double1", 789.0);
1025 expected_policy
.SetDouble("double2", 123.456e7
);
1026 base::DictionaryValue expected_policies
;
1027 expected_policies
.Set("policy", expected_policy
.DeepCopy());
1028 PolicyBundle expected
;
1029 expected
.Get(ns
).LoadFrom(&expected_policies
, POLICY_LEVEL_MANDATORY
,
1030 POLICY_SCOPE_USER
, POLICY_SOURCE_PLATFORM
);
1031 EXPECT_TRUE(Matches(expected
));
1034 TEST_F(PolicyLoaderWinTest
, AppliedPolicyNotPresent
) {
1035 InstallRegistrySentinel();
1037 gpo_list_status_
= ERROR_SUCCESS
;
1040 EXPECT_TRUE(Matches(empty
));
1043 TEST_F(PolicyLoaderWinTest
, AppliedPolicyEmpty
) {
1044 InstallRegistrySentinel();
1045 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("empty"));
1046 GROUP_POLICY_OBJECT gpo
;
1047 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1049 gpo_list_status_
= ERROR_SUCCESS
;
1052 EXPECT_TRUE(Matches(empty
));
1055 TEST_F(PolicyLoaderWinTest
, AppliedPolicyInDomain
) {
1056 base::win::SetDomainStateForTesting(true);
1057 InstallRegistrySentinel();
1058 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("empty"));
1059 GROUP_POLICY_OBJECT gpo
;
1060 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1062 gpo_list_status_
= ERROR_SUCCESS
;
1064 EXPECT_TRUE(MatchesRegistrySentinel());
1067 TEST_F(PolicyLoaderWinTest
, GpoProviderNotSpecified
) {
1068 base::win::SetDomainStateForTesting(false);
1069 InstallRegistrySentinel();
1070 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("empty"));
1071 GROUP_POLICY_OBJECT gpo
;
1072 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1074 gpo_list_status_
= ERROR_SUCCESS
;
1075 gpo_list_provider_
= nullptr;
1077 EXPECT_TRUE(MatchesRegistrySentinel());
1080 TEST_F(PolicyLoaderWinTest
, AppliedPolicyNonExistingFile
) {
1081 InstallRegistrySentinel();
1082 GROUP_POLICY_OBJECT gpo
;
1083 InitGPO(&gpo
, 0, test_data_dir_
, NULL
, NULL
);
1085 gpo_list_status_
= ERROR_SUCCESS
;
1087 EXPECT_TRUE(MatchesRegistrySentinel());
1090 TEST_F(PolicyLoaderWinTest
, AppliedPolicyBadPath
) {
1091 InstallRegistrySentinel();
1092 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("bad"));
1093 GROUP_POLICY_OBJECT gpo
;
1094 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1096 gpo_list_status_
= ERROR_SUCCESS
;
1098 EXPECT_TRUE(MatchesRegistrySentinel());
1101 TEST_F(PolicyLoaderWinTest
, AppliedPolicyPresent
) {
1102 InstallRegistrySentinel();
1103 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("test1"));
1104 GROUP_POLICY_OBJECT gpo
;
1105 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1107 gpo_list_status_
= ERROR_SUCCESS
;
1109 EXPECT_TRUE(MatchesTestBundle());
1112 TEST_F(PolicyLoaderWinTest
, AppliedPolicyMerged
) {
1113 InstallRegistrySentinel();
1114 base::FilePath
gpo1_dir(test_data_dir_
.AppendASCII("test2"));
1115 base::FilePath
gpo2_dir(test_data_dir_
.AppendASCII("test1"));
1116 GROUP_POLICY_OBJECT gpo1
;
1117 GROUP_POLICY_OBJECT gpo2
;
1118 InitGPO(&gpo1
, 0, gpo1_dir
, &gpo2
, NULL
);
1119 InitGPO(&gpo2
, 0, gpo2_dir
, NULL
, &gpo1
);
1121 gpo_list_status_
= ERROR_SUCCESS
;
1123 EXPECT_TRUE(MatchesTestBundle());
1126 TEST_F(PolicyLoaderWinTest
, AppliedPolicyDisabled
) {
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
, 0, gpo1_dir
, &gpo2
, NULL
);
1133 InitGPO(&gpo2
, GPO_FLAG_DISABLE
, gpo2_dir
, NULL
, &gpo1
);
1135 gpo_list_status_
= ERROR_SUCCESS
;
1137 EXPECT_TRUE(MatchesTestBundle());
1140 TEST_F(PolicyLoaderWinTest
, AppliedPolicyForcedPolicy
) {
1141 InstallRegistrySentinel();
1142 base::FilePath
gpo1_dir(test_data_dir_
.AppendASCII("test1"));
1143 base::FilePath
gpo2_dir(test_data_dir_
.AppendASCII("test2"));
1144 GROUP_POLICY_OBJECT gpo1
;
1145 GROUP_POLICY_OBJECT gpo2
;
1146 InitGPO(&gpo1
, GPO_FLAG_FORCE
, gpo1_dir
, &gpo2
, NULL
);
1147 InitGPO(&gpo2
, 0, gpo2_dir
, NULL
, &gpo1
);
1149 gpo_list_status_
= ERROR_SUCCESS
;
1151 EXPECT_TRUE(MatchesTestBundle());
1154 TEST_F(PolicyLoaderWinTest
, AppliedPolicyUNCPath
) {
1155 InstallRegistrySentinel();
1156 base::FilePath
gpo_dir(test_data_dir_
.AppendASCII("test1"));
1157 base::FilePath
unc_path(L
"\\\\some_share\\GPO");
1158 GROUP_POLICY_OBJECT gpo1
;
1159 GROUP_POLICY_OBJECT gpo2
;
1160 InitGPO(&gpo1
, 0, gpo_dir
, &gpo2
, NULL
);
1161 InitGPO(&gpo2
, 0, unc_path
, NULL
, &gpo1
);
1163 gpo_list_status_
= ERROR_SUCCESS
;
1165 EXPECT_TRUE(MatchesRegistrySentinel());
1168 TEST_F(PolicyLoaderWinTest
, LoadExtensionPolicyAlternativeSpelling
) {
1169 base::FilePath
gpo_dir(
1170 test_data_dir_
.AppendASCII("extension_alternative_spelling"));
1171 GROUP_POLICY_OBJECT gpo
;
1172 InitGPO(&gpo
, 0, gpo_dir
, NULL
, NULL
);
1174 gpo_list_status_
= ERROR_SUCCESS
;
1176 const char kTestSchema
[] =
1178 " \"type\": \"object\","
1179 " \"properties\": {"
1180 " \"policy 1\": { \"type\": \"integer\" },"
1181 " \"policy 2\": { \"type\": \"integer\" }"
1184 const PolicyNamespace
ns_a(
1185 POLICY_DOMAIN_EXTENSIONS
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
1186 const PolicyNamespace
ns_b(
1187 POLICY_DOMAIN_EXTENSIONS
, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
1188 ASSERT_TRUE(RegisterSchema(ns_a
, kTestSchema
));
1189 ASSERT_TRUE(RegisterSchema(ns_b
, kTestSchema
));
1191 PolicyBundle expected
;
1192 base::DictionaryValue expected_a
;
1193 expected_a
.SetInteger("policy 1", 3);
1194 expected_a
.SetInteger("policy 2", 3);
1195 expected
.Get(ns_a
).LoadFrom(&expected_a
, POLICY_LEVEL_MANDATORY
,
1196 POLICY_SCOPE_MACHINE
, POLICY_SOURCE_PLATFORM
);
1197 base::DictionaryValue expected_b
;
1198 expected_b
.SetInteger("policy 1", 2);
1199 expected
.Get(ns_b
).LoadFrom(&expected_b
, POLICY_LEVEL_MANDATORY
,
1200 POLICY_SCOPE_MACHINE
, POLICY_SOURCE_PLATFORM
);
1201 EXPECT_TRUE(Matches(expected
));
1204 TEST_F(PolicyLoaderWinTest
, LBSSupport
) {
1205 const PolicyNamespace
ns(
1206 POLICY_DOMAIN_EXTENSIONS
, "heildphpnddilhkemkielfhnkaagiabh");
1207 schema_registry_
.RegisterComponent(ns
, Schema());
1209 const char kIncompleteSchema
[] =
1211 " \"type\": \"object\","
1212 " \"properties\": {"
1213 " \"url_list\": { \"type\": \"array\" },"
1214 " \"url_greylist\": { \"type\": \"array\" }"
1218 const base::string16 kPathSuffix
=
1219 kTestPolicyKey
+ base::ASCIIToUTF16("\\3rdparty\\extensions");
1221 base::ListValue list
;
1222 list
.AppendString("youtube.com");
1223 base::DictionaryValue policy
;
1224 policy
.Set("url_list", list
.DeepCopy());
1225 policy
.SetString("alternative_browser_path", "c:\\legacy\\browser.exe");
1226 base::DictionaryValue root
;
1227 root
.Set(base::UTF16ToUTF8(kMandatory
), policy
.DeepCopy());
1228 root
.SetString(kSchema
, kIncompleteSchema
);
1229 EXPECT_TRUE(InstallValue(root
, HKEY_LOCAL_MACHINE
,
1230 kPathSuffix
, base::ASCIIToUTF16(ns
.component_id
)));
1232 PolicyBundle expected
;
1233 PolicyMap
& expected_policy
= expected
.Get(ns
);
1234 expected_policy
.Set("alternative_browser_path",
1235 POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
,
1236 POLICY_SOURCE_PLATFORM
,
1237 new base::StringValue("c:\\legacy\\browser.exe"), NULL
);
1238 expected_policy
.Set("url_list", POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_MACHINE
,
1239 POLICY_SOURCE_PLATFORM
, list
.DeepCopy(), nullptr);
1240 EXPECT_TRUE(Matches(expected
));
1243 } // namespace policy