diff options
author | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-16 14:37:53 +0000 |
---|---|---|
committer | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-16 14:37:53 +0000 |
commit | 69554ef8f8e60c68512e7ddaa67ff26cf04dad22 (patch) | |
tree | e30152607fb66a14778f08562c71177f5b5d7d56 | |
parent | 3be9f0f977723bb5520c1d63058d541364da14ef (diff) | |
download | chromium_src-69554ef8f8e60c68512e7ddaa67ff26cf04dad22.zip chromium_src-69554ef8f8e60c68512e7ddaa67ff26cf04dad22.tar.gz chromium_src-69554ef8f8e60c68512e7ddaa67ff26cf04dad22.tar.bz2 |
Load 3rd party policy on Linux.
BUG=108996, 108993
TEST=unit tests are green
Review URL: https://chromiumcodereview.appspot.com/10332174
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137419 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/policy/config_dir_policy_provider.cc | 70 | ||||
-rw-r--r-- | chrome/browser/policy/config_dir_policy_provider.h | 10 | ||||
-rw-r--r-- | chrome/browser/policy/config_dir_policy_provider_unittest.cc | 46 |
3 files changed, 121 insertions, 5 deletions
diff --git a/chrome/browser/policy/config_dir_policy_provider.cc b/chrome/browser/policy/config_dir_policy_provider.cc index a98a28c..c86fa50 100644 --- a/chrome/browser/policy/config_dir_policy_provider.cc +++ b/chrome/browser/policy/config_dir_policy_provider.cc @@ -13,6 +13,7 @@ #include "base/json/json_file_value_serializer.h" #include "base/logging.h" #include "base/platform_file.h" +#include "base/stl_util.h" #include "chrome/browser/policy/policy_bundle.h" namespace policy { @@ -45,21 +46,31 @@ scoped_ptr<PolicyBundle> ConfigDirPolicyProviderDelegate::Load() { deserializer.set_allow_trailing_comma(true); int error_code = 0; std::string error_msg; - scoped_ptr<Value> value(deserializer.Deserialize(&error_code, &error_msg)); + scoped_ptr<base::Value> value( + deserializer.Deserialize(&error_code, &error_msg)); if (!value.get()) { LOG(WARNING) << "Failed to read configuration file " << config_file_iter->value() << ": " << error_msg; continue; } - DictionaryValue* dictionary_value = NULL; + base::DictionaryValue* dictionary_value = NULL; if (!value->GetAsDictionary(&dictionary_value)) { LOG(WARNING) << "Expected JSON dictionary in configuration file " << config_file_iter->value(); continue; } - PolicyMap file_policy; - file_policy.LoadFrom(dictionary_value, level_, scope_); - bundle->Get(POLICY_DOMAIN_CHROME, std::string()).MergeFrom(file_policy); + + // Detach the "3rdparty" node. + base::Value* third_party = NULL; + if (dictionary_value->Remove("3rdparty", &third_party)) { + Merge3rdPartyPolicy(bundle.get(), third_party); + delete third_party; + } + + // Add chrome policy. + PolicyMap policy_map; + policy_map.LoadFrom(dictionary_value, level_, scope_); + bundle->Get(POLICY_DOMAIN_CHROME, "").MergeFrom(policy_map); } return bundle.Pass(); @@ -91,6 +102,55 @@ base::Time ConfigDirPolicyProviderDelegate::GetLastModification() { return last_modification; } +void ConfigDirPolicyProviderDelegate::Merge3rdPartyPolicy( + PolicyBundle* bundle, + const base::Value* value) { + // The first-level entries in |value| are PolicyDomains. The second-level + // entries are component IDs, and the third-level entries are the policies + // for that domain/component namespace. + + const base::DictionaryValue* domains_dictionary; + if (!value->GetAsDictionary(&domains_dictionary)) { + LOG(WARNING) << "3rdparty value is not a dictionary!"; + return; + } + + // Helper to lookup a domain given its string name. + std::map<std::string, PolicyDomain> supported_domains; + supported_domains["extensions"] = POLICY_DOMAIN_EXTENSIONS; + + for (base::DictionaryValue::Iterator domains_it(*domains_dictionary); + domains_it.HasNext(); domains_it.Advance()) { + if (!ContainsKey(supported_domains, domains_it.key())) { + LOG(WARNING) << "Unsupported 3rd party policy domain: " + << domains_it.key(); + continue; + } + + const base::DictionaryValue* components_dictionary; + if (!domains_it.value().GetAsDictionary(&components_dictionary)) { + LOG(WARNING) << "3rdparty/" << domains_it.key() + << " value is not a dictionary!"; + continue; + } + + PolicyDomain domain = supported_domains[domains_it.key()]; + for (base::DictionaryValue::Iterator components_it(*components_dictionary); + components_it.HasNext(); components_it.Advance()) { + const base::DictionaryValue* policy_dictionary; + if (!components_it.value().GetAsDictionary(&policy_dictionary)) { + LOG(WARNING) << "3rdparty/" << domains_it.key() << "/" + << components_it.key() << " value is not a dictionary!"; + continue; + } + + PolicyMap policy; + policy.LoadFrom(policy_dictionary, level_, scope_); + bundle->Get(domain, components_it.key()).MergeFrom(policy); + } + } +} + ConfigDirPolicyProvider::ConfigDirPolicyProvider( const PolicyDefinitionList* policy_list, PolicyLevel level, diff --git a/chrome/browser/policy/config_dir_policy_provider.h b/chrome/browser/policy/config_dir_policy_provider.h index 1a8fbbb..e938c1d 100644 --- a/chrome/browser/policy/config_dir_policy_provider.h +++ b/chrome/browser/policy/config_dir_policy_provider.h @@ -11,8 +11,14 @@ class FilePath; +namespace base { +class Value; +} + namespace policy { +class PolicyBundle; + // Policy provider backed by JSON files in a configuration directory. class ConfigDirPolicyProvider : public FileBasedPolicyProvider { public: @@ -42,6 +48,10 @@ class ConfigDirPolicyProviderDelegate virtual base::Time GetLastModification() OVERRIDE; private: + // Merges the 3rd party |policies| into the |bundle|. + void Merge3rdPartyPolicy(PolicyBundle* bundle, + const base::Value* policies); + // Policies loaded by this provider will have these attributes. PolicyLevel level_; PolicyScope scope_; diff --git a/chrome/browser/policy/config_dir_policy_provider_unittest.cc b/chrome/browser/policy/config_dir_policy_provider_unittest.cc index 24bb85d..087878b 100644 --- a/chrome/browser/policy/config_dir_policy_provider_unittest.cc +++ b/chrome/browser/policy/config_dir_policy_provider_unittest.cc @@ -199,4 +199,50 @@ TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsMergePrefs) { EXPECT_TRUE(bundle->Equals(expected_bundle)); } +// Tests loading of policy for 3rd parties. +TEST_F(ConfigDirPolicyLoaderTest, Load3rdParty) { + base::DictionaryValue policy_dict; + policy_dict.SetBoolean("bool", true); + policy_dict.SetString("str", "string value"); + policy_dict.SetDouble("double", 123.456); + policy_dict.SetInteger("int", 789); + + base::ListValue* list = new base::ListValue(); + for (int i = 0; i < 5; ++i) { + base::DictionaryValue* dict = new base::DictionaryValue(); + dict->SetInteger("subdictindex", i); + dict->Set("subdict", policy_dict.DeepCopy()); + list->Append(dict); + } + policy_dict.Set("list", list); + + base::DictionaryValue json_dict; + // Merge |policy_dict|, which will become the chrome policies. + json_dict.MergeDictionary(&policy_dict); + json_dict.Set("3rdparty.extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + policy_dict.DeepCopy()); + json_dict.Set("3rdparty.extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + policy_dict.DeepCopy()); + + harness_.WriteConfigFile(json_dict, "policy.json"); + ConfigDirPolicyProviderDelegate loader(harness_.test_dir(), + POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER); + scoped_ptr<PolicyBundle> bundle(loader.Load()); + ASSERT_TRUE(bundle.get()); + PolicyMap expected_policy; + expected_policy.LoadFrom(&policy_dict, + POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER); + PolicyBundle expected_bundle; + expected_bundle.Get(POLICY_DOMAIN_CHROME, "").CopyFrom(expected_policy); + expected_bundle.Get(POLICY_DOMAIN_EXTENSIONS, + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + .CopyFrom(expected_policy); + expected_bundle.Get(POLICY_DOMAIN_EXTENSIONS, + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") + .CopyFrom(expected_policy); + EXPECT_TRUE(bundle->Equals(expected_bundle)); +} + } // namespace policy |