summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc3
-rw-r--r--chrome/browser/net/proxy_policy_handler_unittest.cc12
-rw-r--r--chrome/browser/policy/DEPS2
-rw-r--r--chrome/browser/policy/browser_policy_connector.cc4
-rw-r--r--chrome/browser/policy/configuration_policy_pref_store_unittest.cc7
-rw-r--r--chrome/browser/policy/configuration_policy_pref_store_unittest.h2
-rw-r--r--chrome/browser/policy/configuration_policy_provider.cc57
-rw-r--r--chrome/browser/policy/configuration_policy_provider_test.cc39
-rw-r--r--chrome/browser/policy/policy_browsertest.cc36
-rw-r--r--chrome/browser/policy/policy_service_impl.cc18
-rw-r--r--chrome/browser/policy/policy_service_impl.h10
-rw-r--r--chrome/browser/policy/policy_service_impl_unittest.cc50
-rw-r--r--chrome/browser/policy/policy_transformations.cc71
-rw-r--r--chrome/browser/policy/policy_transformations.h18
-rw-r--r--chrome/browser/policy/policy_transformations_unittest.cc76
-rw-r--r--chrome/browser/policy/profile_policy_connector.cc5
-rw-r--r--chrome/browser/prefs/proxy_policy_unittest.cc5
17 files changed, 303 insertions, 112 deletions
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
index 20c15da..4f48212 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
@@ -136,7 +136,8 @@ class NetworkConfigurationUpdaterTest : public testing::Test {
provider_.Init();
PolicyServiceImpl::Providers providers;
providers.push_back(&provider_);
- policy_service_.reset(new PolicyServiceImpl(providers));
+ policy_service_.reset(new PolicyServiceImpl(
+ providers, PolicyServiceImpl::PreprocessCallback()));
scoped_ptr<base::DictionaryValue> fake_toplevel_onc =
chromeos::onc::ReadDictionaryFromJson(kFakeONC);
diff --git a/chrome/browser/net/proxy_policy_handler_unittest.cc b/chrome/browser/net/proxy_policy_handler_unittest.cc
index 7224fca..bbaa879 100644
--- a/chrome/browser/net/proxy_policy_handler_unittest.cc
+++ b/chrome/browser/net/proxy_policy_handler_unittest.cc
@@ -4,11 +4,14 @@
#include <string>
+#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/net/proxy_policy_handler.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/policy/configuration_policy_pref_store_unittest.h"
+#include "chrome/browser/policy/policy_service_impl.h"
+#include "chrome/browser/policy/policy_transformations.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "chrome/browser/prefs/proxy_prefs.h"
#include "chrome/common/pref_names.h"
@@ -22,8 +25,17 @@ class ProxyPolicyHandlerTest
: public ConfigurationPolicyPrefStoreTest {
public:
virtual void SetUp() OVERRIDE {
+ ConfigurationPolicyPrefStoreTest::SetUp();
handler_list_.AddHandler(
make_scoped_ptr<ConfigurationPolicyHandler>(new ProxyPolicyHandler));
+ // Reset the PolicyServiceImpl to one that has the policy fixup
+ // preprocessor. The previous store must be nulled out first so that it
+ // removes itself from the service's observer list.
+ store_ = NULL;
+ policy_service_.reset(
+ new PolicyServiceImpl(providers_, base::Bind(&FixDeprecatedPolicies)));
+ store_ = new ConfigurationPolicyPrefStore(
+ policy_service_.get(), &handler_list_, POLICY_LEVEL_MANDATORY);
}
protected:
diff --git a/chrome/browser/policy/DEPS b/chrome/browser/policy/DEPS
index 9231735..71d05f2 100644
--- a/chrome/browser/policy/DEPS
+++ b/chrome/browser/policy/DEPS
@@ -30,6 +30,8 @@ specific_include_rules = {
r"policy_path_parser_unittest|"
r"policy_path_parser_win|"
r"policy_prefs_browsertest|"
+ r"policy_transformations|"
+ r"policy_transformations_unittest|"
r"profile_policy_connector|"
r"profile_policy_connector_factory|"
r"url_blacklist_manager|"
diff --git a/chrome/browser/policy/browser_policy_connector.cc b/chrome/browser/policy/browser_policy_connector.cc
index f6457cb..1f0fb1e 100644
--- a/chrome/browser/policy/browser_policy_connector.cc
+++ b/chrome/browser/policy/browser_policy_connector.cc
@@ -33,6 +33,7 @@
#include "chrome/browser/policy/configuration_policy_provider.h"
#include "chrome/browser/policy/policy_service_impl.h"
#include "chrome/browser/policy/policy_statistics_collector.h"
+#include "chrome/browser/policy/policy_transformations.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
@@ -400,7 +401,8 @@ PolicyService* BrowserPolicyConnector::GetPolicyService() {
providers.push_back(&global_user_cloud_policy_provider_);
#endif
}
- policy_service_.reset(new PolicyServiceImpl(providers));
+ policy_service_.reset(new PolicyServiceImpl(
+ providers, base::Bind(&policy::FixDeprecatedPolicies)));
}
return policy_service_.get();
}
diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
index b12b10d..b304930e 100644
--- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
@@ -14,7 +14,6 @@
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/policy/external_data_fetcher.h"
#include "chrome/browser/policy/policy_map.h"
-#include "chrome/browser/policy/policy_service_impl.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -48,9 +47,9 @@ ConfigurationPolicyPrefStoreTest::ConfigurationPolicyPrefStoreTest() {
EXPECT_CALL(provider_, IsInitializationComplete(_))
.WillRepeatedly(Return(false));
provider_.Init();
- PolicyServiceImpl::Providers providers;
- providers.push_back(&provider_);
- policy_service_.reset(new PolicyServiceImpl(providers));
+ providers_.push_back(&provider_);
+ policy_service_.reset(new PolicyServiceImpl(
+ providers_, PolicyServiceImpl::PreprocessCallback()));
store_ = new ConfigurationPolicyPrefStore(
policy_service_.get(), &handler_list_, POLICY_LEVEL_MANDATORY);
}
diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.h b/chrome/browser/policy/configuration_policy_pref_store_unittest.h
index 9fdf866..0012d2b 100644
--- a/chrome/browser/policy/configuration_policy_pref_store_unittest.h
+++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.h
@@ -10,6 +10,7 @@
#include "base/message_loop/message_loop.h"
#include "chrome/browser/policy/configuration_policy_handler_list.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
+#include "chrome/browser/policy/policy_service_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace policy {
@@ -25,6 +26,7 @@ class ConfigurationPolicyPrefStoreTest : public testing::Test {
virtual void TearDown() OVERRIDE;
void UpdateProviderPolicy(const PolicyMap& policy);
+ PolicyServiceImpl::Providers providers_;
ConfigurationPolicyHandlerList handler_list_;
MockConfigurationPolicyProvider provider_;
scoped_ptr<PolicyService> policy_service_;
diff --git a/chrome/browser/policy/configuration_policy_provider.cc b/chrome/browser/policy/configuration_policy_provider.cc
index a0ae969..87c8127 100644
--- a/chrome/browser/policy/configuration_policy_provider.cc
+++ b/chrome/browser/policy/configuration_policy_provider.cc
@@ -6,64 +6,9 @@
#include "base/callback.h"
#include "chrome/browser/policy/external_data_fetcher.h"
-#include "chrome/browser/policy/policy_map.h"
-#include "policy/policy_constants.h"
namespace policy {
-namespace {
-
-const char* kProxyPolicies[] = {
- key::kProxyMode,
- key::kProxyServerMode,
- key::kProxyServer,
- key::kProxyPacUrl,
- key::kProxyBypassList,
-};
-
-// Helper that converts deprecated chrome policies into their corresponding
-// actual policies.
-void FixDeprecatedPolicies(PolicyMap* policies) {
- // Proxy settings have been configured by 5 policies that didn't mix well
- // together, and maps of policies had to take this into account when merging
- // policy sources. The proxy settings will eventually be configured by a
- // single Dictionary policy when all providers have support for that. For
- // now, the individual policies are mapped here to a single Dictionary policy
- // that the rest of the policy machinery uses.
-
- // The highest (level, scope) pair for an existing proxy policy is determined
- // first, and then only policies with those exact attributes are merged.
- PolicyMap::Entry current_priority; // Defaults to the lowest priority.
- scoped_ptr<DictionaryValue> proxy_settings(new DictionaryValue);
- for (size_t i = 0; i < arraysize(kProxyPolicies); ++i) {
- const PolicyMap::Entry* entry = policies->Get(kProxyPolicies[i]);
- if (entry) {
- if (entry->has_higher_priority_than(current_priority)) {
- proxy_settings->Clear();
- current_priority = *entry;
- }
- if (!entry->has_higher_priority_than(current_priority) &&
- !current_priority.has_higher_priority_than(*entry)) {
- proxy_settings->Set(kProxyPolicies[i], entry->value->DeepCopy());
- }
- policies->Erase(kProxyPolicies[i]);
- }
- }
- // Sets the new |proxy_settings| if kProxySettings isn't set yet, or if the
- // new priority is higher.
- const PolicyMap::Entry* existing = policies->Get(key::kProxySettings);
- if (!proxy_settings->empty() &&
- (!existing || current_priority.has_higher_priority_than(*existing))) {
- policies->Set(key::kProxySettings,
- current_priority.level,
- current_priority.scope,
- proxy_settings.release(),
- NULL);
- }
-}
-
-} // namespace
-
ConfigurationPolicyProvider::Observer::~Observer() {}
ConfigurationPolicyProvider::ConfigurationPolicyProvider()
@@ -100,8 +45,6 @@ void ConfigurationPolicyProvider::UpdatePolicy(
policy_bundle_.Swap(bundle.get());
else
policy_bundle_.Clear();
- FixDeprecatedPolicies(&policy_bundle_.Get(
- PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())));
FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
observer_list_,
OnUpdatePolicy(this));
diff --git a/chrome/browser/policy/configuration_policy_provider_test.cc b/chrome/browser/policy/configuration_policy_provider_test.cc
index 2dd3f2b..7bee548 100644
--- a/chrome/browser/policy/configuration_policy_provider_test.cc
+++ b/chrome/browser/policy/configuration_policy_provider_test.cc
@@ -14,7 +14,6 @@
#include "chrome/browser/policy/policy_bundle.h"
#include "chrome/browser/policy/policy_map.h"
#include "components/policy/core/common/policy_namespace.h"
-#include "policy/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
using ::testing::Mock;
@@ -337,44 +336,6 @@ TEST_P(ConfigurationPolicyProviderTest, RefreshPolicies) {
provider_->RemoveObserver(&observer);
}
-TEST(ConfigurationPolicyProviderTest, FixDeprecatedPolicies) {
- PolicyMap policy_map;
- policy_map.Set(key::kProxyServerMode,
- POLICY_LEVEL_MANDATORY,
- POLICY_SCOPE_USER,
- base::Value::CreateIntegerValue(3),
- NULL);
-
- // Both these policies should be ignored, since there's a higher priority
- // policy available.
- policy_map.Set(key::kProxyMode,
- POLICY_LEVEL_RECOMMENDED,
- POLICY_SCOPE_USER,
- base::Value::CreateStringValue("pac_script"),
- NULL);
- policy_map.Set(key::kProxyPacUrl,
- POLICY_LEVEL_RECOMMENDED,
- POLICY_SCOPE_USER,
- base::Value::CreateStringValue("http://example.com/wpad.dat"),
- NULL);
-
- MockConfigurationPolicyProvider provider;
- provider.Init();
- provider.UpdateChromePolicy(policy_map);
-
- PolicyBundle expected_bundle;
- base::DictionaryValue* expected_value = new base::DictionaryValue();
- expected_value->SetInteger(key::kProxyServerMode, 3);
- expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
- .Set(key::kProxySettings,
- POLICY_LEVEL_MANDATORY,
- POLICY_SCOPE_USER,
- expected_value,
- NULL);
- EXPECT_TRUE(provider.policies().Equals(expected_bundle));
- provider.Shutdown();
-}
-
Configuration3rdPartyPolicyProviderTest::
Configuration3rdPartyPolicyProviderTest() {}
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 13853f3..26b69ca 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -50,6 +50,9 @@
#include "chrome/browser/policy/external_data_fetcher.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/policy_map.h"
+#include "chrome/browser/policy/policy_service.h"
+#include "chrome/browser/policy/profile_policy_connector.h"
+#include "chrome/browser/policy/profile_policy_connector_factory.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/instant_service.h"
@@ -930,6 +933,39 @@ IN_PROC_BROWSER_TEST_F(PolicyTest, DefaultSearchProvider) {
EXPECT_EQ(GURL(content::kAboutBlankURL), web_contents->GetURL());
}
+IN_PROC_BROWSER_TEST_F(PolicyTest, PolicyPreprocessing) {
+ // Add an individual proxy policy value.
+ PolicyMap policies;
+ policies.Set(key::kProxyServerMode,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(3),
+ NULL);
+ UpdateProviderPolicy(policies);
+
+ // It should be removed and replaced with a dictionary.
+ PolicyMap expected;
+ scoped_ptr<base::DictionaryValue> expected_value(new base::DictionaryValue);
+ expected_value->SetInteger(key::kProxyServerMode, 3);
+ expected.Set(key::kProxySettings,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ expected_value.release(),
+ NULL);
+
+ // Check both the browser and the profile.
+ const PolicyMap& actual_from_browser =
+ g_browser_process->browser_policy_connector()
+ ->GetPolicyService()
+ ->GetPolicies(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
+ EXPECT_TRUE(expected.Equals(actual_from_browser));
+ const PolicyMap& actual_from_profile =
+ ProfilePolicyConnectorFactory::GetForProfile(browser()->profile())
+ ->policy_service()
+ ->GetPolicies(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
+ EXPECT_TRUE(expected.Equals(actual_from_profile));
+}
+
IN_PROC_BROWSER_TEST_F(PolicyTest, ForceSafeSearch) {
// Makes the requests fail since all we want to check is that the redirection
// is done properly.
diff --git a/chrome/browser/policy/policy_service_impl.cc b/chrome/browser/policy/policy_service_impl.cc
index 4604f75..7820559 100644
--- a/chrome/browser/policy/policy_service_impl.cc
+++ b/chrome/browser/policy/policy_service_impl.cc
@@ -9,14 +9,17 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
-#include "chrome/browser/policy/policy_map.h"
+#include "chrome/browser/policy/policy_bundle.h"
namespace policy {
typedef PolicyServiceImpl::Providers::const_iterator Iterator;
-PolicyServiceImpl::PolicyServiceImpl(const Providers& providers)
- : update_task_ptr_factory_(this) {
+PolicyServiceImpl::PolicyServiceImpl(
+ const Providers& providers,
+ const PreprocessCallback& preprocess_callback)
+ : preprocess_callback_(preprocess_callback),
+ update_task_ptr_factory_(this) {
for (int domain = 0; domain < POLICY_DOMAIN_SIZE; ++domain)
initialization_complete_[domain] = true;
providers_ = providers;
@@ -127,8 +130,13 @@ void PolicyServiceImpl::NotifyNamespaceUpdated(
void PolicyServiceImpl::MergeAndTriggerUpdates() {
// Merge from each provider in their order of priority.
PolicyBundle bundle;
- for (Iterator it = providers_.begin(); it != providers_.end(); ++it)
- bundle.MergeFrom((*it)->policies());
+ for (Iterator it = providers_.begin(); it != providers_.end(); ++it) {
+ PolicyBundle provided_bundle;
+ provided_bundle.CopyFrom((*it)->policies());
+ if (!preprocess_callback_.is_null())
+ preprocess_callback_.Run(&provided_bundle);
+ bundle.MergeFrom(provided_bundle);
+ }
// Swap first, so that observers that call GetPolicies() see the current
// values.
diff --git a/chrome/browser/policy/policy_service_impl.h b/chrome/browser/policy/policy_service_impl.h
index 6817574..b199c51 100644
--- a/chrome/browser/policy/policy_service_impl.h
+++ b/chrome/browser/policy/policy_service_impl.h
@@ -11,6 +11,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
@@ -25,12 +26,16 @@ class PolicyServiceImpl : public PolicyService,
public ConfigurationPolicyProvider::Observer {
public:
typedef std::vector<ConfigurationPolicyProvider*> Providers;
+ typedef base::Callback<void(PolicyBundle*)> PreprocessCallback;
// The PolicyServiceImpl will merge policies from |providers|. |providers|
// must be sorted in decreasing order of priority; the first provider will
// have the highest priority. The PolicyServiceImpl does not take ownership of
// the providers, and they must outlive the PolicyServiceImpl.
- explicit PolicyServiceImpl(const Providers& providers);
+ // |preprocess_callback| will be applied every PolicyBundle before merginng.
+ PolicyServiceImpl(const Providers& providers,
+ const PreprocessCallback& preprocess_callback);
+
virtual ~PolicyServiceImpl();
// PolicyService overrides:
@@ -83,6 +88,9 @@ class PolicyServiceImpl : public PolicyService,
// call to RefreshPolicies().
std::set<ConfigurationPolicyProvider*> refresh_pending_;
+ // Callback invoked to manipulate a PolicyBundle before it is merged.
+ PreprocessCallback preprocess_callback_;
+
// List of callbacks to invoke once all providers refresh after a
// RefreshPolicies() call.
std::vector<base::Closure> refresh_callbacks_;
diff --git a/chrome/browser/policy/policy_service_impl_unittest.cc b/chrome/browser/policy/policy_service_impl_unittest.cc
index 365e5ff..c43a5efb 100644
--- a/chrome/browser/policy/policy_service_impl_unittest.cc
+++ b/chrome/browser/policy/policy_service_impl_unittest.cc
@@ -29,6 +29,17 @@ const char kExtension[] = "extension-id";
const char kSameLevelPolicy[] = "policy-same-level-and-scope";
const char kDiffLevelPolicy[] = "chrome-diff-level-and-scope";
+void SetPolicyMapValue(const std::string& key,
+ const std::string& value,
+ PolicyBundle* bundle) {
+ bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+ .Set(key,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ new base::StringValue(value),
+ NULL);
+}
+
// Helper to compare the arguments to an EXPECT_CALL of OnPolicyUpdated() with
// their expected values.
MATCHER_P(PolicyEquals, expected, "") {
@@ -111,7 +122,8 @@ class PolicyServiceTest : public testing::Test {
providers.push_back(&provider0_);
providers.push_back(&provider1_);
providers.push_back(&provider2_);
- policy_service_.reset(new PolicyServiceImpl(providers));
+ policy_service_.reset(new PolicyServiceImpl(
+ providers, PolicyServiceImpl::PreprocessCallback()));
}
virtual void TearDown() OVERRIDE {
@@ -522,6 +534,39 @@ TEST_F(PolicyServiceTest, NamespaceMerge) {
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension)).Equals(expected));
}
+TEST_F(PolicyServiceTest, PolicyPreprocessing) {
+ // Reset the PolicyServiceImpl to one that has the preprocessor.
+ PolicyServiceImpl::Providers providers;
+ providers.push_back(&provider0_);
+ policy_service_.reset(new PolicyServiceImpl(
+ providers, base::Bind(&SetPolicyMapValue, kSameLevelPolicy, "bar")));
+
+ // Set the policy value to "foo".
+ scoped_ptr<PolicyBundle> bundle(new PolicyBundle());
+ PolicyMap& map =
+ bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
+ map.Set(kSameLevelPolicy,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateStringValue("foo"),
+ NULL);
+
+ // Push the update through the provider.
+ provider0_.UpdatePolicy(bundle.Pass());
+ RunUntilIdle();
+
+ // The value should have been changed from "foo" to "bar".
+ const PolicyMap& actual = policy_service_->GetPolicies(
+ PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
+ PolicyMap expected;
+ expected.Set(kSameLevelPolicy,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateStringValue("bar"),
+ NULL);
+ EXPECT_TRUE(actual.Equals(expected));
+}
+
TEST_F(PolicyServiceTest, IsInitializationComplete) {
// |provider0| has all domains initialized.
Mock::VerifyAndClearExpectations(&provider1_);
@@ -534,7 +579,8 @@ TEST_F(PolicyServiceTest, IsInitializationComplete) {
providers.push_back(&provider0_);
providers.push_back(&provider1_);
providers.push_back(&provider2_);
- policy_service_.reset(new PolicyServiceImpl(providers));
+ policy_service_.reset(new PolicyServiceImpl(
+ providers, PolicyServiceImpl::PreprocessCallback()));
EXPECT_FALSE(policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
EXPECT_FALSE(
policy_service_->IsInitializationComplete(POLICY_DOMAIN_EXTENSIONS));
diff --git a/chrome/browser/policy/policy_transformations.cc b/chrome/browser/policy/policy_transformations.cc
new file mode 100644
index 0000000..3504e2a
--- /dev/null
+++ b/chrome/browser/policy/policy_transformations.cc
@@ -0,0 +1,71 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/policy_transformations.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "chrome/browser/policy/policy_bundle.h"
+#include "chrome/browser/policy/policy_map.h"
+#include "policy/policy_constants.h"
+
+namespace policy {
+
+namespace {
+
+const char* kProxyPolicies[] = {
+ key::kProxyMode,
+ key::kProxyServerMode,
+ key::kProxyServer,
+ key::kProxyPacUrl,
+ key::kProxyBypassList,
+};
+
+void FixDeprecatedPolicies(PolicyMap* policies) {
+ // Proxy settings have been configured by 5 policies that didn't mix well
+ // together, and maps of policies had to take this into account when merging
+ // policy sources. The proxy settings will eventually be configured by a
+ // single Dictionary policy when all providers have support for that. For
+ // now, the individual policies are mapped here to a single Dictionary policy
+ // that the rest of the policy machinery uses.
+
+ // The highest (level, scope) pair for an existing proxy policy is determined
+ // first, and then only policies with those exact attributes are merged.
+ PolicyMap::Entry current_priority; // Defaults to the lowest priority.
+ scoped_ptr<base::DictionaryValue> proxy_settings(new base::DictionaryValue);
+ for (size_t i = 0; i < arraysize(kProxyPolicies); ++i) {
+ const PolicyMap::Entry* entry = policies->Get(kProxyPolicies[i]);
+ if (entry) {
+ if (entry->has_higher_priority_than(current_priority)) {
+ proxy_settings->Clear();
+ current_priority = *entry;
+ }
+ if (!entry->has_higher_priority_than(current_priority) &&
+ !current_priority.has_higher_priority_than(*entry)) {
+ proxy_settings->Set(kProxyPolicies[i], entry->value->DeepCopy());
+ }
+ policies->Erase(kProxyPolicies[i]);
+ }
+ }
+ // Sets the new |proxy_settings| if kProxySettings isn't set yet, or if the
+ // new priority is higher.
+ const PolicyMap::Entry* existing = policies->Get(key::kProxySettings);
+ if (!proxy_settings->empty() &&
+ (!existing || current_priority.has_higher_priority_than(*existing))) {
+ policies->Set(key::kProxySettings,
+ current_priority.level,
+ current_priority.scope,
+ proxy_settings.release(),
+ NULL);
+ }
+}
+
+} // namespace
+
+void FixDeprecatedPolicies(PolicyBundle* bundle) {
+ FixDeprecatedPolicies(
+ &bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())));
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/policy_transformations.h b/chrome/browser/policy/policy_transformations.h
new file mode 100644
index 0000000..12f4c9f
--- /dev/null
+++ b/chrome/browser/policy/policy_transformations.h
@@ -0,0 +1,18 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_POLICY_TRANSFORMATIONS_H_
+#define CHROME_BROWSER_POLICY_POLICY_TRANSFORMATIONS_H_
+
+namespace policy {
+
+class PolicyBundle;
+
+// Helper that converts deprecated chrome policies into their corresponding
+// actual policies.
+void FixDeprecatedPolicies(PolicyBundle* bundle);
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_POLICY_TRANSFORMATIONS_H_
diff --git a/chrome/browser/policy/policy_transformations_unittest.cc b/chrome/browser/policy/policy_transformations_unittest.cc
new file mode 100644
index 0000000..53cfdd8
--- /dev/null
+++ b/chrome/browser/policy/policy_transformations_unittest.cc
@@ -0,0 +1,76 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/policy_transformations.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "chrome/browser/policy/policy_bundle.h"
+#include "chrome/browser/policy/policy_map.h"
+#include "policy/policy_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+TEST(PolicyTransformationsTest, FixDeprecatedPolicies) {
+ PolicyBundle policy_bundle;
+ PolicyMap& policy_map =
+ policy_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
+
+ // Individual proxy policy values in the Chrome namespace should be collected
+ // into a dictionary.
+ policy_map.Set(key::kProxyServerMode,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(3),
+ NULL);
+
+ // Both these policies should be ignored, since there's a higher priority
+ // policy available.
+ policy_map.Set(key::kProxyMode,
+ POLICY_LEVEL_RECOMMENDED,
+ POLICY_SCOPE_USER,
+ base::Value::CreateStringValue("pac_script"),
+ NULL);
+ policy_map.Set(key::kProxyPacUrl,
+ POLICY_LEVEL_RECOMMENDED,
+ POLICY_SCOPE_USER,
+ base::Value::CreateStringValue("http://example.com/wpad.dat"),
+ NULL);
+
+ // Add a value to a non-Chrome namespace.
+ policy_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, std::string()))
+ .Set(key::kProxyServerMode,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(3),
+ NULL);
+
+ PolicyBundle actual_bundle;
+ actual_bundle.CopyFrom(policy_bundle);
+ FixDeprecatedPolicies(&actual_bundle);
+
+ PolicyBundle expected_bundle;
+ // The resulting Chrome namespace map should have the collected policy.
+ PolicyMap& expected_map =
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
+ scoped_ptr<base::DictionaryValue> expected_value(new base::DictionaryValue);
+ expected_value->SetInteger(key::kProxyServerMode, 3);
+ expected_map.Set(key::kProxySettings,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ expected_value.release(),
+ NULL);
+ // The resulting Extensions namespace map shouldn't have been modified.
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, std::string()))
+ .Set(key::kProxyServerMode,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(3),
+ NULL);
+
+ EXPECT_TRUE(expected_bundle.Equals(actual_bundle));
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/profile_policy_connector.cc b/chrome/browser/policy/profile_policy_connector.cc
index 73eea77..61ac00d 100644
--- a/chrome/browser/policy/profile_policy_connector.cc
+++ b/chrome/browser/policy/profile_policy_connector.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "base/bind.h"
#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/policy/browser_policy_connector.h"
@@ -13,6 +14,7 @@
#include "chrome/browser/policy/configuration_policy_provider.h"
#include "chrome/browser/policy/forwarding_policy_provider.h"
#include "chrome/browser/policy/policy_service_impl.h"
+#include "chrome/browser/policy/policy_transformations.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/user.h"
@@ -80,7 +82,8 @@ void ProfilePolicyConnector::Init(
providers.push_back(special_user_policy_provider_.get());
#endif
- policy_service_.reset(new PolicyServiceImpl(providers));
+ policy_service_.reset(new PolicyServiceImpl(
+ providers, base::Bind(&policy::FixDeprecatedPolicies)));
#if defined(OS_CHROMEOS)
if (is_primary_user_) {
diff --git a/chrome/browser/prefs/proxy_policy_unittest.cc b/chrome/browser/prefs/proxy_policy_unittest.cc
index 7be9764..9163d47 100644
--- a/chrome/browser/prefs/proxy_policy_unittest.cc
+++ b/chrome/browser/prefs/proxy_policy_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/memory/ref_counted.h"
@@ -10,6 +11,7 @@
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/policy_map.h"
#include "chrome/browser/policy/policy_service_impl.h"
+#include "chrome/browser/policy/policy_transformations.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/pref_service_mock_factory.h"
#include "chrome/browser/prefs/pref_service_syncable.h"
@@ -89,7 +91,8 @@ class ProxyPolicyTest : public testing::Test {
PolicyServiceImpl::Providers providers;
providers.push_back(&provider_);
- policy_service_.reset(new PolicyServiceImpl(providers));
+ policy_service_.reset(
+ new PolicyServiceImpl(providers, base::Bind(&FixDeprecatedPolicies)));
provider_.Init();
}