Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/policy/policy_loader_win.h" | 5 #include "chrome/browser/policy/policy_loader_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/string16.h" | 10 #include "base/string16.h" |
| 11 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
| 12 #include "base/string_util.h" | |
| 12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 13 #include "base/win/registry.h" | 14 #include "base/win/registry.h" |
| 14 #include "chrome/browser/policy/async_policy_provider.h" | 15 #include "chrome/browser/policy/async_policy_provider.h" |
| 15 #include "chrome/browser/policy/configuration_policy_provider_test.h" | 16 #include "chrome/browser/policy/configuration_policy_provider_test.h" |
| 16 #include "chrome/browser/policy/policy_bundle.h" | 17 #include "chrome/browser/policy/policy_bundle.h" |
| 17 #include "chrome/browser/policy/policy_map.h" | 18 #include "chrome/browser/policy/policy_map.h" |
| 18 #include "policy/policy_constants.h" | 19 #include "policy/policy_constants.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 21 |
| 21 using base::win::RegKey; | 22 using base::win::RegKey; |
| 22 | 23 |
| 23 namespace policy { | 24 namespace policy { |
| 24 | 25 |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| 27 const wchar_t kUnitTestRegistrySubKey[] = L"SOFTWARE\\Chromium Unit Tests"; | 28 const wchar_t kUnitTestRegistrySubKey[] = L"SOFTWARE\\Chromium Unit Tests"; |
| 28 const wchar_t kUnitTestMachineOverrideSubKey[] = | 29 const wchar_t kUnitTestMachineOverrideSubKey[] = |
| 29 L"SOFTWARE\\Chromium Unit Tests\\HKLM Override"; | 30 L"SOFTWARE\\Chromium Unit Tests\\HKLM Override"; |
| 30 const wchar_t kUnitTestUserOverrideSubKey[] = | 31 const wchar_t kUnitTestUserOverrideSubKey[] = |
| 31 L"SOFTWARE\\Chromium Unit Tests\\HKCU Override"; | 32 L"SOFTWARE\\Chromium Unit Tests\\HKCU Override"; |
| 32 | 33 |
| 33 // Installs |dict| at the given |path|, in the given |hive|. Currently only | 34 const wchar_t kPathSep[] = L"\\"; |
| 34 // string, int and dictionary types are converted; other types cause a failure. | 35 |
| 35 // Returns false if there was any failure, and true if |dict| was successfully | 36 // Registry key where 3rd party policy is stored. |
| 36 // written. | 37 const wchar_t kThirdParty[] = L"3rdparty"; |
| 37 // TODO(joaodasilva): generate a schema for |dict| too, so that all types can | 38 |
| 38 // be retrieved. | 39 // Keys for mandatory and recommended policy and schema under the registry key |
| 39 bool InstallDictionary(const base::DictionaryValue& dict, | 40 // for a component. |
| 40 HKEY hive, | 41 const wchar_t kMandatory[] = L"policy"; |
| 41 const string16& path) { | 42 const wchar_t kRecommended[] = L"recommended"; |
| 43 const wchar_t kSchema[] = L"schema"; | |
| 44 | |
| 45 // Installs |value| in the given registry |path| and |hive|, under the key | |
| 46 // |name|. Returns false on errors. | |
| 47 // Some of the possible Value types are stored after a conversion (e.g. doubles | |
| 48 // are stored as strings), and can only be retrieved if a corresponding schema | |
| 49 // is written. | |
| 50 bool InstallValue(const base::Value& value, | |
| 51 HKEY hive, | |
| 52 const string16& path, | |
| 53 const string16& name) { | |
| 42 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet. | 54 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet. |
| 43 RegKey key(hive, path.c_str(), KEY_ALL_ACCESS); | 55 RegKey key(hive, path.c_str(), KEY_ALL_ACCESS); |
| 44 const string16 kPathSep = ASCIIToUTF16("\\"); | 56 switch (value.GetType()) { |
| 57 case base::Value::TYPE_NULL: | |
| 58 return key.WriteValue(name.c_str(), L"") == ERROR_SUCCESS; | |
| 45 | 59 |
| 46 for (base::DictionaryValue::Iterator it(dict); it.HasNext(); it.Advance()) { | 60 case base::Value::TYPE_BOOLEAN: { |
| 47 string16 name(UTF8ToUTF16(it.key())); | 61 bool bool_value; |
| 48 switch (it.value().GetType()) { | 62 if (!value.GetAsBoolean(&bool_value)) |
| 49 case base::Value::TYPE_STRING: { | 63 return false; |
| 50 string16 value; | 64 return key.WriteValue(name.c_str(), bool_value ? 1 : 0) == ERROR_SUCCESS; |
| 51 if (!it.value().GetAsString(&value)) | 65 } |
| 66 | |
| 67 case base::Value::TYPE_INTEGER: { | |
| 68 int int_value; | |
| 69 if (!value.GetAsInteger(&int_value)) | |
| 70 return false; | |
| 71 return key.WriteValue(name.c_str(), int_value) == ERROR_SUCCESS; | |
| 72 } | |
| 73 | |
| 74 case base::Value::TYPE_DOUBLE: { | |
| 75 double double_value; | |
| 76 if (!value.GetAsDouble(&double_value)) | |
| 77 return false; | |
| 78 string16 str_value = UTF8ToUTF16(base::DoubleToString(double_value)); | |
| 79 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS; | |
| 80 } | |
| 81 | |
| 82 case base::Value::TYPE_STRING: { | |
| 83 string16 str_value; | |
| 84 if (!value.GetAsString(&str_value)) | |
| 85 return false; | |
| 86 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS; | |
| 87 } | |
| 88 | |
| 89 case base::Value::TYPE_DICTIONARY: { | |
| 90 const base::DictionaryValue* sub_dict = NULL; | |
| 91 if (!value.GetAsDictionary(&sub_dict)) | |
| 92 return false; | |
| 93 for (base::DictionaryValue::Iterator it(*sub_dict); | |
| 94 it.HasNext(); it.Advance()) { | |
| 95 if (!InstallValue(it.value(), hive, path + kPathSep + name, | |
| 96 UTF8ToUTF16(it.key()))) { | |
| 52 return false; | 97 return false; |
| 53 if (key.WriteValue(name.c_str(), value.c_str()) != ERROR_SUCCESS) | 98 } |
| 99 } | |
| 100 return true; | |
| 101 } | |
| 102 | |
| 103 case base::Value::TYPE_LIST: { | |
| 104 const base::ListValue* list = NULL; | |
| 105 if (!value.GetAsList(&list)) | |
| 106 return false; | |
| 107 for (size_t i = 0; i < list->GetSize(); ++i) { | |
| 108 base::Value* item; | |
| 109 if (!list->Get(i, &item)) | |
| 54 return false; | 110 return false; |
| 55 break; | 111 if (!InstallValue(*item, hive, path + kPathSep + name, |
| 112 base::UintToString16(i + 1))) { | |
| 113 return false; | |
| 114 } | |
| 56 } | 115 } |
| 116 return true; | |
| 117 } | |
| 57 | 118 |
| 58 case base::Value::TYPE_INTEGER: { | 119 case base::Value::TYPE_BINARY: |
| 59 int value; | 120 return false; |
| 60 if (!it.value().GetAsInteger(&value)) | 121 } |
| 61 return false; | 122 NOTREACHED(); |
| 62 if (key.WriteValue(name.c_str(), value) != ERROR_SUCCESS) | 123 return false; |
| 63 return false; | 124 } |
| 64 break; | 125 |
| 126 std::string BuildSchema(const base::Value& value) { | |
| 127 switch (value.GetType()) { | |
| 128 case base::Value::TYPE_NULL: | |
| 129 return "{ \"type\": \"null\" }"; | |
|
Mattias Nissler (ping if slow)
2012/06/27 12:07:17
It might be more readable if you were to build thi
Joao da Silva
2012/06/27 14:31:15
Good idea, done.
| |
| 130 case base::Value::TYPE_BOOLEAN: | |
| 131 return "{ \"type\": \"boolean\" }"; | |
| 132 case base::Value::TYPE_INTEGER: | |
| 133 return "{ \"type\": \"integer\" }"; | |
| 134 case base::Value::TYPE_DOUBLE: | |
| 135 return "{ \"type\": \"number\" }"; | |
| 136 case base::Value::TYPE_STRING: | |
| 137 return "{ \"type\": \"string\" }"; | |
| 138 | |
| 139 case base::Value::TYPE_LIST: { | |
| 140 // Assumes every list element has the same type. | |
| 141 const base::ListValue* list = NULL; | |
| 142 if (!value.GetAsList(&list)) | |
| 143 return EmptyString(); | |
| 144 std::string item_type = "{}"; | |
| 145 if (!list->empty()) | |
| 146 item_type = BuildSchema(**list->begin()); | |
| 147 return "{ \"type\": \"array\", \"items\": " + item_type + " }"; | |
| 148 } | |
| 149 | |
| 150 case base::Value::TYPE_DICTIONARY: { | |
| 151 const base::DictionaryValue* dict = NULL; | |
| 152 if (!value.GetAsDictionary(&dict)) | |
| 153 return EmptyString(); | |
| 154 std::string properties; | |
| 155 for (base::DictionaryValue::Iterator it(*dict); | |
| 156 it.HasNext(); it.Advance()) { | |
| 157 if (!properties.empty()) | |
| 158 properties += ", "; | |
| 159 properties += "\"" + it.key() + "\": " + BuildSchema(it.value()); | |
| 65 } | 160 } |
| 161 return "{ \"type\": \"object\", \"properties\": { " + properties + " } }"; | |
| 162 } | |
| 66 | 163 |
| 67 case base::Value::TYPE_DICTIONARY: { | 164 case base::Value::TYPE_BINARY: |
| 68 const base::DictionaryValue* sub_dict = NULL; | 165 return EmptyString(); |
| 69 if (!it.value().GetAsDictionary(&sub_dict)) | 166 } |
| 70 return false; | 167 NOTREACHED(); |
| 71 if (!InstallDictionary(*sub_dict, hive, path + kPathSep + name)) | 168 return EmptyString(); |
| 72 return false; | 169 } |
| 73 break; | |
| 74 } | |
| 75 | 170 |
| 76 default: | 171 bool InstallSchema(const base::Value& value, |
| 77 return false; | 172 HKEY hive, |
| 78 } | 173 const string16& path, |
| 79 } | 174 const string16& name) { |
| 80 return true; | 175 string16 schema = UTF8ToUTF16(BuildSchema(value)); |
| 176 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet. | |
| 177 RegKey key(hive, path.c_str(), KEY_ALL_ACCESS); | |
| 178 return key.WriteValue(name.c_str(), schema.c_str()) == ERROR_SUCCESS; | |
| 81 } | 179 } |
| 82 | 180 |
| 83 // This class provides sandboxing and mocking for the parts of the Windows | 181 // This class provides sandboxing and mocking for the parts of the Windows |
| 84 // Registry implementing Group Policy. It prepares two temporary sandbox keys | 182 // Registry implementing Group Policy. It prepares two temporary sandbox keys |
| 85 // in |kUnitTestRegistrySubKey|, one for HKLM and one for HKCU. A test's calls | 183 // in |kUnitTestRegistrySubKey|, one for HKLM and one for HKCU. A test's calls |
| 86 // to the registry are redirected by Windows to these sandboxes, allowing the | 184 // to the registry are redirected by Windows to these sandboxes, allowing the |
| 87 // tests to manipulate and access policy as if it were active, but without | 185 // tests to manipulate and access policy as if it were active, but without |
| 88 // actually changing the parts of the Registry that are managed by Group | 186 // actually changing the parts of the Registry that are managed by Group |
| 89 // Policy. | 187 // Policy. |
| 90 class ScopedGroupPolicyRegistrySandbox { | 188 class ScopedGroupPolicyRegistrySandbox { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 virtual void InstallIntegerPolicy(const std::string& policy_name, | 221 virtual void InstallIntegerPolicy(const std::string& policy_name, |
| 124 int policy_value) OVERRIDE; | 222 int policy_value) OVERRIDE; |
| 125 virtual void InstallBooleanPolicy(const std::string& policy_name, | 223 virtual void InstallBooleanPolicy(const std::string& policy_name, |
| 126 bool policy_value) OVERRIDE; | 224 bool policy_value) OVERRIDE; |
| 127 virtual void InstallStringListPolicy( | 225 virtual void InstallStringListPolicy( |
| 128 const std::string& policy_name, | 226 const std::string& policy_name, |
| 129 const base::ListValue* policy_value) OVERRIDE; | 227 const base::ListValue* policy_value) OVERRIDE; |
| 130 virtual void InstallDictionaryPolicy( | 228 virtual void InstallDictionaryPolicy( |
| 131 const std::string& policy_name, | 229 const std::string& policy_name, |
| 132 const base::DictionaryValue* policy_value) OVERRIDE; | 230 const base::DictionaryValue* policy_value) OVERRIDE; |
| 231 virtual void Install3rdPartyPolicy( | |
| 232 const base::DictionaryValue* policies) OVERRIDE; | |
| 133 | 233 |
| 134 // Creates a harness instance that will install policy in HKCU or HKLM, | 234 // Creates a harness instance that will install policy in HKCU or HKLM, |
| 135 // respectively. | 235 // respectively. |
| 136 static PolicyProviderTestHarness* CreateHKCU(); | 236 static PolicyProviderTestHarness* CreateHKCU(); |
| 137 static PolicyProviderTestHarness* CreateHKLM(); | 237 static PolicyProviderTestHarness* CreateHKLM(); |
| 138 | 238 |
| 139 private: | 239 private: |
| 140 HKEY hive_; | 240 HKEY hive_; |
| 141 | 241 |
| 142 ScopedGroupPolicyRegistrySandbox registry_sandbox_; | 242 ScopedGroupPolicyRegistrySandbox registry_sandbox_; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 void TestHarness::InstallDictionaryPolicy( | 340 void TestHarness::InstallDictionaryPolicy( |
| 241 const std::string& policy_name, | 341 const std::string& policy_name, |
| 242 const base::DictionaryValue* policy_value) { | 342 const base::DictionaryValue* policy_value) { |
| 243 std::string json; | 343 std::string json; |
| 244 base::JSONWriter::Write(policy_value, &json); | 344 base::JSONWriter::Write(policy_value, &json); |
| 245 RegKey key(hive_, kRegistryMandatorySubKey, KEY_ALL_ACCESS); | 345 RegKey key(hive_, kRegistryMandatorySubKey, KEY_ALL_ACCESS); |
| 246 key.WriteValue(UTF8ToUTF16(policy_name).c_str(), | 346 key.WriteValue(UTF8ToUTF16(policy_name).c_str(), |
| 247 UTF8ToUTF16(json).c_str()); | 347 UTF8ToUTF16(json).c_str()); |
| 248 } | 348 } |
| 249 | 349 |
| 350 void TestHarness::Install3rdPartyPolicy(const base::DictionaryValue* policies) { | |
| 351 // The first level entries are domains, and the second level entries map | |
| 352 // components to their policy. | |
| 353 const string16 kPathPrefix = string16(kRegistryMandatorySubKey) + kPathSep + | |
| 354 kThirdParty + kPathSep; | |
| 355 for (base::DictionaryValue::Iterator domain(*policies); | |
| 356 domain.HasNext(); domain.Advance()) { | |
| 357 const base::DictionaryValue* components = NULL; | |
| 358 if (!domain.value().GetAsDictionary(&components)) { | |
| 359 ADD_FAILURE(); | |
| 360 continue; | |
| 361 } | |
| 362 for (base::DictionaryValue::Iterator component(*components); | |
| 363 component.HasNext(); component.Advance()) { | |
| 364 const string16 path = string16(kRegistryMandatorySubKey) + kPathSep + | |
| 365 kThirdParty + kPathSep + | |
| 366 UTF8ToUTF16(domain.key()) + kPathSep + | |
| 367 UTF8ToUTF16(component.key()); | |
| 368 InstallValue(component.value(), hive_, path, kMandatory); | |
| 369 EXPECT_TRUE(InstallSchema(component.value(), hive_, path, kSchema)); | |
| 370 } | |
| 371 } | |
| 372 } | |
| 373 | |
| 250 // static | 374 // static |
| 251 PolicyProviderTestHarness* TestHarness::CreateHKCU() { | 375 PolicyProviderTestHarness* TestHarness::CreateHKCU() { |
| 252 return new TestHarness(HKEY_CURRENT_USER, POLICY_SCOPE_USER); | 376 return new TestHarness(HKEY_CURRENT_USER, POLICY_SCOPE_USER); |
| 253 } | 377 } |
| 254 | 378 |
| 255 // static | 379 // static |
| 256 PolicyProviderTestHarness* TestHarness::CreateHKLM() { | 380 PolicyProviderTestHarness* TestHarness::CreateHKLM() { |
| 257 return new TestHarness(HKEY_LOCAL_MACHINE, POLICY_SCOPE_MACHINE); | 381 return new TestHarness(HKEY_LOCAL_MACHINE, POLICY_SCOPE_MACHINE); |
| 258 } | 382 } |
| 259 | 383 |
| 260 } // namespace | 384 } // namespace |
| 261 | 385 |
| 262 // Instantiate abstract test case for basic policy reading tests. | 386 // Instantiate abstract test case for basic policy reading tests. |
| 263 INSTANTIATE_TEST_CASE_P( | 387 INSTANTIATE_TEST_CASE_P( |
| 264 PolicyProviderWinTest, | 388 PolicyProviderWinTest, |
| 265 ConfigurationPolicyProviderTest, | 389 ConfigurationPolicyProviderTest, |
| 266 testing::Values(TestHarness::CreateHKCU, TestHarness::CreateHKLM)); | 390 testing::Values(TestHarness::CreateHKCU, TestHarness::CreateHKLM)); |
| 267 | 391 |
| 392 // Instantiate abstract test case for 3rd party policy reading tests. | |
| 393 INSTANTIATE_TEST_CASE_P( | |
| 394 ThirdPartyPolicyProviderWinTest, | |
| 395 Configuration3rdPartyPolicyProviderTest, | |
| 396 testing::Values(TestHarness::CreateHKCU, TestHarness::CreateHKLM)); | |
| 397 | |
| 268 // Test cases for windows policy provider specific functionality. | 398 // Test cases for windows policy provider specific functionality. |
| 269 class PolicyLoaderWinTest : public PolicyTestBase { | 399 class PolicyLoaderWinTest : public PolicyTestBase { |
| 270 protected: | 400 protected: |
| 271 PolicyLoaderWinTest() {} | 401 PolicyLoaderWinTest() {} |
| 272 virtual ~PolicyLoaderWinTest() {} | 402 virtual ~PolicyLoaderWinTest() {} |
| 273 | 403 |
| 274 ScopedGroupPolicyRegistrySandbox registry_sandbox_; | 404 ScopedGroupPolicyRegistrySandbox registry_sandbox_; |
| 275 }; | 405 }; |
| 276 | 406 |
| 277 TEST_F(PolicyLoaderWinTest, HKLMOverHKCU) { | 407 TEST_F(PolicyLoaderWinTest, HKLMOverHKCU) { |
| 278 RegKey hklm_key(HKEY_LOCAL_MACHINE, kRegistryMandatorySubKey, KEY_ALL_ACCESS); | 408 RegKey hklm_key(HKEY_LOCAL_MACHINE, kRegistryMandatorySubKey, KEY_ALL_ACCESS); |
| 279 hklm_key.WriteValue(UTF8ToUTF16(test_policy_definitions::kKeyString).c_str(), | 409 hklm_key.WriteValue(UTF8ToUTF16(test_policy_definitions::kKeyString).c_str(), |
| 280 UTF8ToUTF16("hklm").c_str()); | 410 UTF8ToUTF16("hklm").c_str()); |
| 281 RegKey hkcu_key(HKEY_CURRENT_USER, kRegistryMandatorySubKey, KEY_ALL_ACCESS); | 411 RegKey hkcu_key(HKEY_CURRENT_USER, kRegistryMandatorySubKey, KEY_ALL_ACCESS); |
| 282 hkcu_key.WriteValue(UTF8ToUTF16(test_policy_definitions::kKeyString).c_str(), | 412 hkcu_key.WriteValue(UTF8ToUTF16(test_policy_definitions::kKeyString).c_str(), |
| 283 UTF8ToUTF16("hkcu").c_str()); | 413 UTF8ToUTF16("hkcu").c_str()); |
| 284 | 414 |
| 285 PolicyLoaderWin loader(&test_policy_definitions::kList); | 415 PolicyLoaderWin loader(&test_policy_definitions::kList); |
| 286 scoped_ptr<PolicyBundle> bundle(loader.Load()); | 416 scoped_ptr<PolicyBundle> bundle(loader.Load()); |
| 287 | 417 |
| 288 PolicyBundle expected_bundle; | 418 PolicyBundle expected_bundle; |
| 289 expected_bundle.Get(POLICY_DOMAIN_CHROME, "") | 419 expected_bundle.Get(POLICY_DOMAIN_CHROME, "") |
| 290 .Set(test_policy_definitions::kKeyString, | 420 .Set(test_policy_definitions::kKeyString, |
| 291 POLICY_LEVEL_MANDATORY, | 421 POLICY_LEVEL_MANDATORY, |
| 292 POLICY_SCOPE_MACHINE, | 422 POLICY_SCOPE_MACHINE, |
| 293 base::Value::CreateStringValue("hklm")); | 423 base::Value::CreateStringValue("hklm")); |
| 294 EXPECT_TRUE(bundle->Equals(expected_bundle)); | 424 EXPECT_TRUE(bundle->Equals(expected_bundle)); |
| 295 } | 425 } |
| 296 | 426 |
| 297 // TODO(joaodasilva): share tests for 3rd party policy with | 427 TEST_F(PolicyLoaderWinTest, Load3rdPartyWithoutSchema) { |
| 298 // ConfigDirPolicyProvider once PolicyLoaderWin is able to load all types. | |
| 299 TEST_F(PolicyLoaderWinTest, Load3rdParty) { | |
| 300 base::DictionaryValue dict; | 428 base::DictionaryValue dict; |
| 301 dict.SetString("str", "string value"); | 429 dict.SetString("str", "string value"); |
| 302 dict.SetInteger("int", 123); | 430 dict.SetInteger("int", 123); |
| 303 dict.Set("subdict", dict.DeepCopy()); | 431 dict.Set("subdict", dict.DeepCopy()); |
| 304 dict.Set("subsubdict", dict.DeepCopy()); | 432 dict.Set("subsubdict", dict.DeepCopy()); |
| 305 dict.Set("subsubsubdict", dict.DeepCopy()); | 433 dict.Set("subsubsubdict", dict.DeepCopy()); |
| 306 | 434 |
| 307 base::DictionaryValue policy_dict; | 435 base::DictionaryValue policy_dict; |
| 308 policy_dict.Set("3rdparty.extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.policy", | 436 policy_dict.Set("extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.policy", |
| 309 dict.DeepCopy()); | 437 dict.DeepCopy()); |
| 310 policy_dict.Set("3rdparty.extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.policy", | 438 policy_dict.Set("extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.policy", |
| 311 dict.DeepCopy()); | 439 dict.DeepCopy()); |
| 312 EXPECT_TRUE(InstallDictionary(policy_dict, HKEY_LOCAL_MACHINE, | 440 EXPECT_TRUE(InstallValue(policy_dict, HKEY_LOCAL_MACHINE, |
| 313 kRegistryMandatorySubKey)); | 441 kRegistryMandatorySubKey, kThirdParty)); |
| 314 | 442 |
| 315 PolicyBundle expected; | 443 PolicyBundle expected; |
| 316 expected.Get(POLICY_DOMAIN_EXTENSIONS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") | 444 expected.Get(POLICY_DOMAIN_EXTENSIONS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") |
| 317 .LoadFrom(&dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE); | 445 .LoadFrom(&dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE); |
| 318 expected.Get(POLICY_DOMAIN_EXTENSIONS, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") | 446 expected.Get(POLICY_DOMAIN_EXTENSIONS, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") |
| 319 .LoadFrom(&dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE); | 447 .LoadFrom(&dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE); |
| 320 | 448 |
| 321 PolicyLoaderWin loader(&test_policy_definitions::kList); | 449 PolicyLoaderWin loader(&test_policy_definitions::kList); |
| 322 scoped_ptr<PolicyBundle> loaded(loader.Load()); | 450 scoped_ptr<PolicyBundle> loaded(loader.Load()); |
| 323 EXPECT_TRUE(loaded->Equals(expected)); | 451 EXPECT_TRUE(loaded->Equals(expected)); |
| 324 } | 452 } |
| 325 | 453 |
| 326 TEST_F(PolicyLoaderWinTest, Merge3rdPartyPolicies) { | 454 TEST_F(PolicyLoaderWinTest, Merge3rdPartyPolicies) { |
| 327 // Policy for the same extension will be provided at the 4 level/scope | 455 // Policy for the same extension will be provided at the 4 level/scope |
| 328 // combinations, to verify that they overlap as expected. | 456 // combinations, to verify that they overlap as expected. |
| 329 | 457 |
| 330 const string16 kPathSuffix = | 458 const string16 kPathSuffix = |
| 331 kRegistryMandatorySubKey + ASCIIToUTF16("\\3rdparty\\extensions\\merge"); | 459 kRegistryMandatorySubKey + ASCIIToUTF16("\\3rdparty\\extensions\\merge"); |
| 332 const string16 kMandatoryPath = kPathSuffix + ASCIIToUTF16("\\policy"); | |
| 333 const string16 kRecommendedPath = kPathSuffix + ASCIIToUTF16("\\recommended"); | |
| 334 | 460 |
| 335 const char kUserMandatory[] = "user-mandatory"; | 461 const char kUserMandatory[] = "user-mandatory"; |
| 336 const char kUserRecommended[] = "user-recommended"; | 462 const char kUserRecommended[] = "user-recommended"; |
| 337 const char kMachineMandatory[] = "machine-mandatory"; | 463 const char kMachineMandatory[] = "machine-mandatory"; |
| 338 const char kMachineRecommended[] = "machine-recommended"; | 464 const char kMachineRecommended[] = "machine-recommended"; |
| 339 | 465 |
| 340 base::DictionaryValue policy; | 466 base::DictionaryValue policy; |
| 341 policy.SetString("a", kMachineMandatory); | 467 policy.SetString("a", kMachineMandatory); |
| 342 EXPECT_TRUE(InstallDictionary(policy, HKEY_LOCAL_MACHINE, kMandatoryPath)); | 468 EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE, |
| 469 kPathSuffix, kMandatory)); | |
| 343 policy.SetString("a", kUserMandatory); | 470 policy.SetString("a", kUserMandatory); |
| 344 policy.SetString("b", kUserMandatory); | 471 policy.SetString("b", kUserMandatory); |
| 345 EXPECT_TRUE(InstallDictionary(policy, HKEY_CURRENT_USER, kMandatoryPath)); | 472 EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER, |
| 473 kPathSuffix, kMandatory)); | |
| 346 policy.SetString("a", kMachineRecommended); | 474 policy.SetString("a", kMachineRecommended); |
| 347 policy.SetString("b", kMachineRecommended); | 475 policy.SetString("b", kMachineRecommended); |
| 348 policy.SetString("c", kMachineRecommended); | 476 policy.SetString("c", kMachineRecommended); |
| 349 EXPECT_TRUE(InstallDictionary(policy, HKEY_LOCAL_MACHINE, kRecommendedPath)); | 477 EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE, |
| 478 kPathSuffix, kRecommended)); | |
| 350 policy.SetString("a", kUserRecommended); | 479 policy.SetString("a", kUserRecommended); |
| 351 policy.SetString("b", kUserRecommended); | 480 policy.SetString("b", kUserRecommended); |
| 352 policy.SetString("c", kUserRecommended); | 481 policy.SetString("c", kUserRecommended); |
| 353 policy.SetString("d", kUserRecommended); | 482 policy.SetString("d", kUserRecommended); |
| 354 EXPECT_TRUE(InstallDictionary(policy, HKEY_CURRENT_USER, kRecommendedPath)); | 483 EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER, |
| 484 kPathSuffix, kRecommended)); | |
| 355 | 485 |
| 356 PolicyBundle expected; | 486 PolicyBundle expected; |
| 357 PolicyMap& expected_policy = expected.Get(POLICY_DOMAIN_EXTENSIONS, "merge"); | 487 PolicyMap& expected_policy = expected.Get(POLICY_DOMAIN_EXTENSIONS, "merge"); |
| 358 expected_policy.Set("a", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, | 488 expected_policy.Set("a", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, |
| 359 base::Value::CreateStringValue(kMachineMandatory)); | 489 base::Value::CreateStringValue(kMachineMandatory)); |
| 360 expected_policy.Set("b", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | 490 expected_policy.Set("b", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |
| 361 base::Value::CreateStringValue(kUserMandatory)); | 491 base::Value::CreateStringValue(kUserMandatory)); |
| 362 expected_policy.Set("c", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, | 492 expected_policy.Set("c", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, |
| 363 base::Value::CreateStringValue(kMachineRecommended)); | 493 base::Value::CreateStringValue(kMachineRecommended)); |
| 364 expected_policy.Set("d", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, | 494 expected_policy.Set("d", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, |
| 365 base::Value::CreateStringValue(kUserRecommended)); | 495 base::Value::CreateStringValue(kUserRecommended)); |
| 366 | 496 |
| 367 PolicyLoaderWin loader(&test_policy_definitions::kList); | 497 PolicyLoaderWin loader(&test_policy_definitions::kList); |
| 368 scoped_ptr<PolicyBundle> loaded(loader.Load()); | 498 scoped_ptr<PolicyBundle> loaded(loader.Load()); |
| 369 EXPECT_TRUE(loaded->Equals(expected)); | 499 EXPECT_TRUE(loaded->Equals(expected)); |
| 370 } | 500 } |
| 371 | 501 |
|
Mattias Nissler (ping if slow)
2012/06/27 12:07:17
It would be good to have a test case that cover re
Joao da Silva
2012/06/27 14:31:15
Done.
| |
| 372 } // namespace policy | 502 } // namespace policy |
| OLD | NEW |