Add abhijeet.k@samsung.com to AUTHORS list.
[chromium-blink-merge.git] / components / policy / core / common / policy_loader_win_unittest.cc
blob90591282304a0482ff19b59da847aaeea427d613
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/policy/core/common/policy_loader_win.h"
7 #include <windows.h>
8 #include <userenv.h>
10 #include <algorithm>
11 #include <cstring>
12 #include <functional>
13 #include <iterator>
14 #include <vector>
16 #include "base/base_paths.h"
17 #include "base/callback.h"
18 #include "base/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;
45 namespace policy {
47 namespace {
49 // Constants for registry key names.
50 const wchar_t kPathSep[] = L"\\";
51 const wchar_t kThirdParty[] = L"3rdparty";
52 const wchar_t kMandatory[] = L"policy";
53 const wchar_t kRecommended[] = L"recommended";
54 const char kSchema[] = "schema";
55 const wchar_t kTestPolicyKey[] = L"chrome.policy.key";
57 // Installs |value| in the given registry |path| and |hive|, under the key
58 // |name|. Returns false on errors.
59 // Some of the possible Value types are stored after a conversion (e.g. doubles
60 // are stored as strings), and can only be retrieved if a corresponding schema
61 // is written.
62 bool InstallValue(const base::Value& value,
63 HKEY hive,
64 const base::string16& path,
65 const base::string16& name) {
66 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet.
67 RegKey key(hive, path.c_str(), KEY_ALL_ACCESS);
68 EXPECT_TRUE(key.Valid());
69 switch (value.GetType()) {
70 case base::Value::TYPE_NULL:
71 return key.WriteValue(name.c_str(), L"") == ERROR_SUCCESS;
73 case base::Value::TYPE_BOOLEAN: {
74 bool bool_value;
75 if (!value.GetAsBoolean(&bool_value))
76 return false;
77 return key.WriteValue(name.c_str(), bool_value ? 1 : 0) == ERROR_SUCCESS;
80 case base::Value::TYPE_INTEGER: {
81 int int_value;
82 if (!value.GetAsInteger(&int_value))
83 return false;
84 return key.WriteValue(name.c_str(), int_value) == ERROR_SUCCESS;
87 case base::Value::TYPE_DOUBLE: {
88 double double_value;
89 if (!value.GetAsDouble(&double_value))
90 return false;
91 base::string16 str_value =
92 UTF8ToUTF16(base::DoubleToString(double_value));
93 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
96 case base::Value::TYPE_STRING: {
97 base::string16 str_value;
98 if (!value.GetAsString(&str_value))
99 return false;
100 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
103 case base::Value::TYPE_DICTIONARY: {
104 const base::DictionaryValue* sub_dict = NULL;
105 if (!value.GetAsDictionary(&sub_dict))
106 return false;
107 for (base::DictionaryValue::Iterator it(*sub_dict);
108 !it.IsAtEnd(); it.Advance()) {
109 if (!InstallValue(it.value(), hive, path + kPathSep + name,
110 UTF8ToUTF16(it.key()))) {
111 return false;
114 return true;
117 case base::Value::TYPE_LIST: {
118 const base::ListValue* list = NULL;
119 if (!value.GetAsList(&list))
120 return false;
121 for (size_t i = 0; i < list->GetSize(); ++i) {
122 const base::Value* item;
123 if (!list->Get(i, &item))
124 return false;
125 if (!InstallValue(*item, hive, path + kPathSep + name,
126 base::UintToString16(i + 1))) {
127 return false;
130 return true;
133 case base::Value::TYPE_BINARY:
134 return false;
136 NOTREACHED();
137 return false;
140 // This class provides sandboxing and mocking for the parts of the Windows
141 // Registry implementing Group Policy. It prepares two temporary sandbox keys,
142 // one for HKLM and one for HKCU. A test's calls to the registry are redirected
143 // by Windows to these sandboxes, allowing the tests to manipulate and access
144 // policy as if it were active, but without actually changing the parts of the
145 // Registry that are managed by Group Policy.
146 class ScopedGroupPolicyRegistrySandbox {
147 public:
148 ScopedGroupPolicyRegistrySandbox();
149 ~ScopedGroupPolicyRegistrySandbox();
151 private:
152 void ActivateOverrides();
153 void RemoveOverrides();
155 // Deletes the sandbox keys.
156 void DeleteKeys();
158 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 {
171 public:
172 RegistryTestHarness(HKEY hive, PolicyScope scope);
173 virtual ~RegistryTestHarness();
175 // PolicyProviderTestHarness:
176 virtual void SetUp() override;
178 virtual ConfigurationPolicyProvider* CreateProvider(
179 SchemaRegistry* registry,
180 scoped_refptr<base::SequencedTaskRunner> task_runner) override;
182 virtual void InstallEmptyPolicy() override;
183 virtual void InstallStringPolicy(const std::string& policy_name,
184 const std::string& policy_value) override;
185 virtual void InstallIntegerPolicy(const std::string& policy_name,
186 int policy_value) override;
187 virtual void InstallBooleanPolicy(const std::string& policy_name,
188 bool policy_value) override;
189 virtual void InstallStringListPolicy(
190 const std::string& policy_name,
191 const base::ListValue* policy_value) override;
192 virtual void InstallDictionaryPolicy(
193 const std::string& policy_name,
194 const base::DictionaryValue* policy_value) override;
195 virtual void Install3rdPartyPolicy(
196 const base::DictionaryValue* policies) override;
198 // AppliedGPOListProvider:
199 virtual DWORD GetAppliedGPOList(DWORD flags,
200 LPCTSTR machine_name,
201 PSID sid_user,
202 GUID* extension_guid,
203 PGROUP_POLICY_OBJECT* gpo_list) override;
204 virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) override;
206 // Creates a harness instance that will install policy in HKCU or HKLM,
207 // respectively.
208 static PolicyProviderTestHarness* CreateHKCU();
209 static PolicyProviderTestHarness* CreateHKLM();
211 private:
212 HKEY hive_;
214 ScopedGroupPolicyRegistrySandbox registry_sandbox_;
216 DISALLOW_COPY_AND_ASSIGN(RegistryTestHarness);
219 // A test harness that generates PReg files for the provider to read.
220 class PRegTestHarness : public PolicyProviderTestHarness,
221 public AppliedGPOListProvider {
222 public:
223 PRegTestHarness();
224 virtual ~PRegTestHarness();
226 // PolicyProviderTestHarness:
227 virtual void SetUp() override;
229 virtual ConfigurationPolicyProvider* CreateProvider(
230 SchemaRegistry* registry,
231 scoped_refptr<base::SequencedTaskRunner> task_runner) override;
233 virtual void InstallEmptyPolicy() override;
234 virtual void InstallStringPolicy(const std::string& policy_name,
235 const std::string& policy_value) override;
236 virtual void InstallIntegerPolicy(const std::string& policy_name,
237 int policy_value) override;
238 virtual void InstallBooleanPolicy(const std::string& policy_name,
239 bool policy_value) override;
240 virtual void InstallStringListPolicy(
241 const std::string& policy_name,
242 const base::ListValue* policy_value) override;
243 virtual void InstallDictionaryPolicy(
244 const std::string& policy_name,
245 const base::DictionaryValue* policy_value) override;
246 virtual void Install3rdPartyPolicy(
247 const base::DictionaryValue* policies) override;
249 // AppliedGPOListProvider:
250 virtual DWORD GetAppliedGPOList(DWORD flags,
251 LPCTSTR machine_name,
252 PSID sid_user,
253 GUID* extension_guid,
254 PGROUP_POLICY_OBJECT* gpo_list) override;
255 virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) override;
257 // Creates a harness instance.
258 static PolicyProviderTestHarness* Create();
260 private:
261 // Helper to append a base::string16 to an uint8 buffer.
262 static void AppendChars(std::vector<uint8>* buffer,
263 const base::string16& chars);
265 // Appends a record with the given fields to the PReg file.
266 void AppendRecordToPRegFile(const base::string16& path,
267 const std::string& key,
268 DWORD type,
269 DWORD size,
270 uint8* data);
272 // Appends the given DWORD |value| for |path| + |key| to the PReg file.
273 void AppendDWORDToPRegFile(const base::string16& path,
274 const std::string& key,
275 DWORD value);
277 // Appends the given string |value| for |path| + |key| to the PReg file.
278 void AppendStringToPRegFile(const base::string16& path,
279 const std::string& key,
280 const std::string& value);
282 // Appends the given policy |value| for |path| + |key| to the PReg file,
283 // converting and recursing as necessary.
284 void AppendPolicyToPRegFile(const base::string16& path,
285 const std::string& key,
286 const base::Value* value);
288 base::ScopedTempDir temp_dir_;
289 base::FilePath preg_file_path_;
290 GROUP_POLICY_OBJECT gpo_;
292 DISALLOW_COPY_AND_ASSIGN(PRegTestHarness);
295 ScopedGroupPolicyRegistrySandbox::ScopedGroupPolicyRegistrySandbox() {
296 // Generate a unique registry key for the override for each test. This
297 // makes sure that tests executing in parallel won't delete each other's
298 // key, at DeleteKeys().
299 key_name_ = base::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
305 // policy settings.
306 temp_hklm_hive_key_.Create(HKEY_CURRENT_USER,
307 hklm_key_name.c_str(),
308 KEY_ALL_ACCESS);
309 temp_hkcu_hive_key_.Create(HKEY_CURRENT_USER,
310 hkcu_key_name.c_str(),
311 KEY_ALL_ACCESS);
313 ActivateOverrides();
316 ScopedGroupPolicyRegistrySandbox::~ScopedGroupPolicyRegistrySandbox() {
317 RemoveOverrides();
318 DeleteKeys();
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());
336 key.DeleteKey(L"");
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,
368 int policy_value) {
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,
377 bool policy_value) {
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) {
387 RegKey key(hive_,
388 (base::string16(kTestPolicyKey) + base::ASCIIToUTF16("\\") +
389 UTF8ToUTF16(policy_name)).c_str(),
390 KEY_ALL_ACCESS);
391 ASSERT_TRUE(key.Valid());
392 int index = 1;
393 for (base::ListValue::const_iterator element(policy_value->begin());
394 element != policy_value->end();
395 ++element) {
396 std::string element_value;
397 if (!(*element)->GetAsString(&element_value))
398 continue;
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) {
408 std::string json;
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)) {
426 ADD_FAILURE();
427 continue;
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,
440 PSID sid_user,
441 GUID* extension_guid,
442 PGROUP_POLICY_OBJECT* gpo_list) {
443 *gpo_list = NULL;
444 return ERROR_ACCESS_DENIED;
447 BOOL RegistryTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) {
448 return TRUE;
451 // static
452 PolicyProviderTestHarness* RegistryTestHarness::CreateHKCU() {
453 return new RegistryTestHarness(HKEY_CURRENT_USER, POLICY_SCOPE_USER);
456 // static
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,
494 int policy_value) {
495 AppendDWORDToPRegFile(kTestPolicyKey, policy_name, policy_value);
498 void PRegTestHarness::InstallBooleanPolicy(const std::string& policy_name,
499 bool policy_value) {
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) {
512 std::string json;
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)) {
527 ADD_FAILURE();
528 continue;
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),
536 &component.value());
541 DWORD PRegTestHarness::GetAppliedGPOList(DWORD flags,
542 LPCTSTR machine_name,
543 PSID sid_user,
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) {
551 return TRUE;
554 // static
555 PolicyProviderTestHarness* PRegTestHarness::Create() {
556 return new PRegTestHarness();
559 // static
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,
570 DWORD type,
571 DWORD size,
572 uint8* data) {
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(
591 preg_file_path_,
592 reinterpret_cast<const char*>(vector_as_array(&buffer)),
593 buffer.size()));
596 void PRegTestHarness::AppendDWORDToPRegFile(const base::string16& path,
597 const std::string& key,
598 DWORD value) {
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);
625 break;
627 case base::Value::TYPE_INTEGER: {
628 int int_value = 0;
629 ASSERT_TRUE(value->GetAsInteger(&int_value));
630 AppendDWORDToPRegFile(path, key, int_value);
631 break;
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));
637 break;
639 case base::Value::TYPE_STRING: {
640 std::string string_value;
641 ASSERT_TRUE(value->GetAsString(&string_value));
642 AppendStringToPRegFile(path, key, string_value);
643 break;
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();
650 entry.Advance()) {
651 AppendPolicyToPRegFile(subpath, entry.key(), &entry.value());
653 break;
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);
664 break;
666 case base::Value::TYPE_BINARY:
667 case base::Value::TYPE_NULL: {
668 ADD_FAILURE();
669 break;
674 } // namespace
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 {
695 protected:
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()
701 : gpo_list_(NULL),
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")
711 .AppendASCII("test")
712 .AppendASCII("data")
713 .AppendASCII("policy")
714 .AppendASCII("gpo");
716 gpo_list_provider_ = this;
719 // AppliedGPOListProvider:
720 virtual DWORD GetAppliedGPOList(DWORD flags,
721 LPCTSTR machine_name,
722 PSID sid_user,
723 GUID* extension_guid,
724 PGROUP_POLICY_OBJECT* gpo_list) override {
725 *gpo_list = gpo_list_;
726 return gpo_list_status_;
728 virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) override {
729 return TRUE;
732 void InitGPO(GROUP_POLICY_OBJECT* gpo,
733 DWORD options,
734 const base::FilePath& path,
735 GROUP_POLICY_OBJECT* next,
736 GROUP_POLICY_OBJECT* prev) {
737 memset(gpo, 0, sizeof(GROUP_POLICY_OBJECT));
738 gpo->dwOptions = options;
739 gpo->lpFileSysPath = const_cast<wchar_t*>(path.value().c_str());
740 gpo->pNext = next;
741 gpo->pPrev = prev;
744 bool Matches(const PolicyBundle& expected) {
745 PolicyLoaderWin loader(loop_.message_loop_proxy(), kTestPolicyKey,
746 gpo_list_provider_);
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());
755 hklm_key.WriteValue(
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"),
811 NULL);
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\","
823 " \"properties\": {"
824 " \"a\": { \"type\": \"string\" },"
825 " \"b\": { \"type\": \"string\" },"
826 " \"c\": { \"type\": \"string\" },"
827 " \"d\": { \"type\": \"string\" }"
828 " }"
829 "}"));
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),
865 NULL);
866 expected_policy.Set("b",
867 POLICY_LEVEL_MANDATORY,
868 POLICY_SCOPE_USER,
869 new base::StringValue(kUserMandatory),
870 NULL);
871 expected_policy.Set("c",
872 POLICY_LEVEL_RECOMMENDED,
873 POLICY_SCOPE_MACHINE,
874 new base::StringValue(kMachineRecommended),
875 NULL);
876 expected_policy.Set("d",
877 POLICY_LEVEL_RECOMMENDED,
878 POLICY_SCOPE_USER,
879 new base::StringValue(kUserRecommended),
880 NULL);
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
886 // string.
887 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "string");
888 ASSERT_TRUE(RegisterSchema(
891 " \"type\": \"object\","
892 " \"id\": \"MainType\","
893 " \"properties\": {"
894 " \"null\": { \"type\": \"null\" },"
895 " \"bool\": { \"type\": \"boolean\" },"
896 " \"int\": { \"type\": \"integer\" },"
897 " \"double\": { \"type\": \"number\" },"
898 " \"list\": {"
899 " \"type\": \"array\","
900 " \"items\": { \"$ref\": \"MainType\" }"
901 " },"
902 " \"dict\": { \"$ref\": \"MainType\" }"
903 " }"
904 "}"));
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");
933 EXPECT_TRUE(
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\","
947 " \"properties\": {"
948 " \"bool\": { \"type\": \"boolean\" },"
949 " \"int\": { \"type\": \"integer\" },"
950 " \"double\": { \"type\": \"number\" }"
951 " }"
952 "}"));
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");
961 EXPECT_TRUE(
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\","
982 " \"properties\": {"
983 " \"policy\": {"
984 " \"type\": \"object\","
985 " \"properties\": {"
986 " \"special-int1\": { \"type\": \"integer\" },"
987 " \"special-int2\": { \"type\": \"integer\" }"
988 " },"
989 " \"additionalProperties\": { \"type\": \"number\" }"
990 " }"
991 " }"
992 "}"));
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");
1008 EXPECT_TRUE(
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();
1026 gpo_list_ = NULL;
1027 gpo_list_status_ = ERROR_SUCCESS;
1029 PolicyBundle empty;
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);
1038 gpo_list_ = &gpo;
1039 gpo_list_status_ = ERROR_SUCCESS;
1041 PolicyBundle empty;
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);
1051 gpo_list_ = &gpo;
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);
1063 gpo_list_ = &gpo;
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);
1074 gpo_list_ = &gpo;
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);
1085 gpo_list_ = &gpo;
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);
1096 gpo_list_ = &gpo;
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);
1110 gpo_list_ = &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);
1124 gpo_list_ = &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);
1138 gpo_list_ = &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);
1152 gpo_list_ = &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);
1163 gpo_list_ = &gpo;
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\" }"
1172 " }"
1173 "}";
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\" }"
1205 " }"
1206 "}";
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