summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaliamoorthi@chromium.org <kaliamoorthi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-16 17:24:13 +0000
committerkaliamoorthi@chromium.org <kaliamoorthi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-16 17:24:13 +0000
commit4e76f00baaceb9adcdab4569a419bf450574a5e0 (patch)
treeed8efd99b2a61aa35d07feba019c9fa55b84cd3c
parent96bb613e8d0b88d011a9e9ac7ec6cc0bfa8dc015 (diff)
downloadchromium_src-4e76f00baaceb9adcdab4569a419bf450574a5e0.zip
chromium_src-4e76f00baaceb9adcdab4569a419bf450574a5e0.tar.gz
chromium_src-4e76f00baaceb9adcdab4569a419bf450574a5e0.tar.bz2
Enable policy support for registering protocol handler.
The CL adds a new policy for registering protocol handlers. BUG=116119 Review URL: https://codereview.chromium.org/309553011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277475 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--build/ios/grit_whitelist.txt1
-rw-r--r--chrome/browser/policy/configuration_policy_handler_list_factory.cc9
-rw-r--r--chrome/test/data/policy/policy_test_cases.json11
-rw-r--r--components/policy/core/browser/configuration_policy_handler.cc48
-rw-r--r--components/policy/core/browser/configuration_policy_handler.h35
-rw-r--r--components/policy/core/browser/configuration_policy_handler_unittest.cc147
-rw-r--r--components/policy/resources/policy_templates.json38
-rw-r--r--components/policy_strings.grdp3
-rw-r--r--tools/metrics/histograms/histograms.xml1
9 files changed, 286 insertions, 7 deletions
diff --git a/build/ios/grit_whitelist.txt b/build/ios/grit_whitelist.txt
index acbc400..0915a9c 100644
--- a/build/ios/grit_whitelist.txt
+++ b/build/ios/grit_whitelist.txt
@@ -688,6 +688,7 @@ IDS_POLICY_DM_STATUS_UNKNOWN_ERROR
IDS_POLICY_INVALID_BOOKMARK
IDS_POLICY_INVALID_PROXY_MODE_ERROR
IDS_POLICY_INVALID_SEARCH_URL_ERROR
+IDS_POLICY_LEVEL_ERROR
IDS_POLICY_LIST_ENTRY_ERROR
IDS_POLICY_NOT_SPECIFIED_ERROR
IDS_POLICY_OUT_OF_RANGE_ERROR
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index bb0e357..d53f1f0 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -584,6 +584,15 @@ scoped_ptr<ConfigurationPolicyHandlerList> BuildHandlerList(
#if !defined(OS_ANDROID) && !defined(OS_IOS)
handlers->AddHandler(make_scoped_ptr<ConfigurationPolicyHandler>(
new DownloadDirPolicyHandler));
+
+ handlers->AddHandler(make_scoped_ptr<ConfigurationPolicyHandler>(
+ new SimpleSchemaValidatingPolicyHandler(
+ key::kRegisteredProtocolHandlers,
+ prefs::kPolicyRegisteredProtocolHandlers,
+ chrome_schema,
+ SCHEMA_STRICT,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_ALLOWED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_PROHIBITED)));
#endif
#if defined(OS_CHROMEOS)
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index c2e49c9..91edb9d 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -1575,6 +1575,17 @@
]
},
+ "RegisteredProtocolHandlers": {
+ "os": ["win", "linux", "mac", "chromeos"],
+ "can_be_recommended": true,
+ "test_policy": { "RegisteredProtocolHandlers": {"protocol": "test", "url": "http://example.com/%s", "default": "true"} },
+ "pref_mappings": [
+ { "pref": "custom_handlers.policy.registered_protocol_handlers",
+ "check_for_mandatory": false
+ }
+ ]
+ },
+
"HideWebStoreIcon": {
"os": ["win", "linux", "mac", "chromeos"],
"test_policy": { "HideWebStoreIcon": true },
diff --git a/components/policy/core/browser/configuration_policy_handler.cc b/components/policy/core/browser/configuration_policy_handler.cc
index f4918a6..65d0a56 100644
--- a/components/policy/core/browser/configuration_policy_handler.cc
+++ b/components/policy/core/browser/configuration_policy_handler.cc
@@ -368,6 +368,54 @@ bool SchemaValidatingPolicyHandler::CheckAndGetValue(
return result;
}
+// SimpleSchemaValidatingPolicyHandler implementation --------------------------
+
+SimpleSchemaValidatingPolicyHandler::SimpleSchemaValidatingPolicyHandler(
+ const char* policy_name,
+ const char* pref_path,
+ Schema schema,
+ SchemaOnErrorStrategy strategy,
+ RecommendedPermission recommended_permission,
+ MandatoryPermission mandatory_permission)
+ : SchemaValidatingPolicyHandler(policy_name,
+ schema.GetKnownProperty(policy_name),
+ strategy),
+ pref_path_(pref_path),
+ allow_recommended_(recommended_permission == RECOMMENDED_ALLOWED),
+ allow_mandatory_(mandatory_permission == MANDATORY_ALLOWED) {
+}
+
+SimpleSchemaValidatingPolicyHandler::~SimpleSchemaValidatingPolicyHandler() {
+}
+
+bool SimpleSchemaValidatingPolicyHandler::CheckPolicySettings(
+ const PolicyMap& policies,
+ PolicyErrorMap* errors) {
+ const PolicyMap::Entry* policy_entry = policies.Get(policy_name());
+ if (!policy_entry)
+ return true;
+ if ((policy_entry->level == policy::POLICY_LEVEL_MANDATORY &&
+ !allow_mandatory_) ||
+ (policy_entry->level == policy::POLICY_LEVEL_RECOMMENDED &&
+ !allow_recommended_)) {
+ if (errors)
+ errors->AddError(policy_name(), IDS_POLICY_LEVEL_ERROR);
+ return false;
+ }
+
+ return SchemaValidatingPolicyHandler::CheckPolicySettings(policies, errors);
+}
+
+void SimpleSchemaValidatingPolicyHandler::ApplyPolicySettings(
+ const PolicyMap& policies,
+ PrefValueMap* prefs) {
+ if (!pref_path_)
+ return;
+ const base::Value* value = policies.GetValue(policy_name());
+ if (value)
+ prefs->SetValue(pref_path_, value->DeepCopy());
+}
+
// LegacyPoliciesDeprecatingPolicyHandler implementation -----------------------
// TODO(binjin): Add a new common base class for SchemaValidatingPolicyHandler
diff --git a/components/policy/core/browser/configuration_policy_handler.h b/components/policy/core/browser/configuration_policy_handler.h
index 814f65b..54e77a2 100644
--- a/components/policy/core/browser/configuration_policy_handler.h
+++ b/components/policy/core/browser/configuration_policy_handler.h
@@ -273,6 +273,41 @@ class POLICY_EXPORT SchemaValidatingPolicyHandler
DISALLOW_COPY_AND_ASSIGN(SchemaValidatingPolicyHandler);
};
+// Maps policy to pref like SimplePolicyHandler while ensuring that the value
+// set matches the schema. |schema| is the schema used for policies, and
+// |strategy| is the strategy used for schema validation errors. The
+// |recommended_permission| and |mandatory_permission| flags indicate the levels
+// at which the policy can be set. A value set at an unsupported level will be
+// ignored.
+class POLICY_EXPORT SimpleSchemaValidatingPolicyHandler
+ : public SchemaValidatingPolicyHandler {
+ public:
+ enum MandatoryPermission { MANDATORY_ALLOWED, MANDATORY_PROHIBITED };
+ enum RecommendedPermission { RECOMMENDED_ALLOWED, RECOMMENDED_PROHIBITED };
+
+ SimpleSchemaValidatingPolicyHandler(
+ const char* policy_name,
+ const char* pref_path,
+ Schema schema,
+ SchemaOnErrorStrategy strategy,
+ RecommendedPermission recommended_permission,
+ MandatoryPermission mandatory_permission);
+ virtual ~SimpleSchemaValidatingPolicyHandler();
+
+ // ConfigurationPolicyHandler:
+ virtual bool CheckPolicySettings(const PolicyMap& policies,
+ PolicyErrorMap* errors) OVERRIDE;
+ virtual void ApplyPolicySettings(const PolicyMap& policies,
+ PrefValueMap* prefs) OVERRIDE;
+
+ private:
+ const char* pref_path_;
+ const bool allow_recommended_;
+ const bool allow_mandatory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SimpleSchemaValidatingPolicyHandler);
+};
+
// A policy handler to deprecate multiple legacy policies with a new one.
// This handler will completely ignore any of legacy policy values if the new
// one is set.
diff --git a/components/policy/core/browser/configuration_policy_handler_unittest.cc b/components/policy/core/browser/configuration_policy_handler_unittest.cc
index 4947dbf..6145ae9 100644
--- a/components/policy/core/browser/configuration_policy_handler_unittest.cc
+++ b/components/policy/core/browser/configuration_policy_handler_unittest.cc
@@ -25,13 +25,12 @@ StringToIntEnumListPolicyHandler::MappingEntry kTestTypeMap[] = {
const char kTestPolicy[] = "unit_test.test_policy";
const char kTestPref[] = "unit_test.test_pref";
-class SimpleSchemaValidatingPolicyHandler
- : public SchemaValidatingPolicyHandler {
+class TestSchemaValidatingPolicyHandler : public SchemaValidatingPolicyHandler {
public:
- SimpleSchemaValidatingPolicyHandler(const Schema& schema,
- SchemaOnErrorStrategy strategy)
+ TestSchemaValidatingPolicyHandler(const Schema& schema,
+ SchemaOnErrorStrategy strategy)
: SchemaValidatingPolicyHandler("PolicyForTesting", schema, strategy) {}
- virtual ~SimpleSchemaValidatingPolicyHandler() {}
+ virtual ~TestSchemaValidatingPolicyHandler() {}
virtual void ApplyPolicySettings(const policy::PolicyMap&,
PrefValueMap*) OVERRIDE {
@@ -543,7 +542,7 @@ TEST(SchemaValidatingPolicyHandlerTest, CheckAndGetValue) {
policy_map.LoadFrom(
policy_map_dict, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER);
- SimpleSchemaValidatingPolicyHandler handler(schema, SCHEMA_ALLOW_INVALID);
+ TestSchemaValidatingPolicyHandler handler(schema, SCHEMA_ALLOW_INVALID);
scoped_ptr<base::Value> output_value;
ASSERT_TRUE(handler.CheckAndGetValueForTest(policy_map, &output_value));
ASSERT_TRUE(output_value);
@@ -558,4 +557,140 @@ TEST(SchemaValidatingPolicyHandlerTest, CheckAndGetValue) {
EXPECT_FALSE(dict->HasKey("Colors"));
}
+TEST(SimpleSchemaValidatingPolicyHandlerTest, CheckAndGetValue) {
+ const char policy_name[] = "PolicyForTesting";
+ static const char kSchemaJson[] =
+ "{"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"PolicyForTesting\": {"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"OneToThree\": {"
+ " \"type\": \"integer\","
+ " \"minimum\": 1,"
+ " \"maximum\": 3"
+ " },"
+ " \"Colors\": {"
+ " \"type\": \"string\","
+ " \"enum\": [ \"Red\", \"Green\", \"Blue\" ]"
+ " }"
+ " }"
+ " }"
+ " }"
+ "}";
+ std::string error;
+ Schema schema = Schema::Parse(kSchemaJson, &error);
+ ASSERT_TRUE(schema.valid()) << error;
+
+ static const char kPolicyMapJson[] =
+ "{"
+ " \"PolicyForTesting\": {"
+ " \"OneToThree\": 2,"
+ " \"Colors\": \"Green\""
+ " }"
+ "}";
+ scoped_ptr<base::Value> policy_map_value(base::JSONReader::ReadAndReturnError(
+ kPolicyMapJson, base::JSON_PARSE_RFC, NULL, &error));
+ ASSERT_TRUE(policy_map_value) << error;
+
+ const base::DictionaryValue* policy_map_dict = NULL;
+ ASSERT_TRUE(policy_map_value->GetAsDictionary(&policy_map_dict));
+
+ PolicyMap policy_map_recommended;
+ policy_map_recommended.LoadFrom(
+ policy_map_dict, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER);
+
+ PolicyMap policy_map_mandatory;
+ policy_map_mandatory.LoadFrom(
+ policy_map_dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
+
+ SimpleSchemaValidatingPolicyHandler handler_all(
+ policy_name,
+ kTestPref,
+ schema,
+ SCHEMA_STRICT,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_ALLOWED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED);
+
+ SimpleSchemaValidatingPolicyHandler handler_recommended(
+ policy_name,
+ kTestPref,
+ schema,
+ SCHEMA_STRICT,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_ALLOWED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_PROHIBITED);
+
+ SimpleSchemaValidatingPolicyHandler handler_mandatory(
+ policy_name,
+ kTestPref,
+ schema,
+ SCHEMA_STRICT,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED);
+
+ SimpleSchemaValidatingPolicyHandler handler_none(
+ policy_name,
+ kTestPref,
+ schema,
+ SCHEMA_STRICT,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_PROHIBITED);
+
+ const base::Value* value_expected_in_pref;
+ policy_map_dict->Get(policy_name, &value_expected_in_pref);
+
+ PolicyErrorMap errors;
+ PrefValueMap prefs;
+ base::Value* value_set_in_pref;
+
+ EXPECT_TRUE(handler_all.CheckPolicySettings(policy_map_mandatory, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler_all.ApplyPolicySettings(policy_map_mandatory, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_TRUE(value_expected_in_pref->Equals(value_set_in_pref));
+
+ EXPECT_FALSE(
+ handler_recommended.CheckPolicySettings(policy_map_mandatory, &errors));
+ EXPECT_FALSE(errors.empty());
+ errors.Clear();
+
+ EXPECT_TRUE(
+ handler_mandatory.CheckPolicySettings(policy_map_mandatory, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler_mandatory.ApplyPolicySettings(policy_map_mandatory, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_TRUE(value_expected_in_pref->Equals(value_set_in_pref));
+
+ EXPECT_FALSE(handler_none.CheckPolicySettings(policy_map_mandatory, &errors));
+ EXPECT_FALSE(errors.empty());
+ errors.Clear();
+
+ EXPECT_TRUE(handler_all.CheckPolicySettings(policy_map_recommended, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler_all.ApplyPolicySettings(policy_map_mandatory, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_TRUE(value_expected_in_pref->Equals(value_set_in_pref));
+
+ EXPECT_FALSE(
+ handler_mandatory.CheckPolicySettings(policy_map_recommended, &errors));
+ EXPECT_FALSE(errors.empty());
+ errors.Clear();
+
+ EXPECT_TRUE(
+ handler_recommended.CheckPolicySettings(policy_map_recommended, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler_recommended.ApplyPolicySettings(policy_map_mandatory, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_TRUE(value_expected_in_pref->Equals(value_set_in_pref));
+
+ EXPECT_FALSE(
+ handler_none.CheckPolicySettings(policy_map_recommended, &errors));
+ EXPECT_FALSE(errors.empty());
+}
+
} // namespace policy
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index c6f0a43..cca7368 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -118,7 +118,7 @@
# persistent IDs for all fields (but not for groups!) are needed. These are
# specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
# because doing so would break the deployed wire format!
-# For your editing convenience: highest ID currently used: 267
+# For your editing convenience: highest ID currently used: 268
#
# Placeholders:
# The following placeholder strings are automatically substituted:
@@ -2668,6 +2668,42 @@
If this policy is left not set the global default value will be used for all sites either from the 'DefaultPopupsSetting' policy if it is set, or the user's personal configuration otherwise.''',
},
{
+ 'name': 'RegisteredProtocolHandlers',
+ 'type': 'dict',
+ 'schema': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'default': {
+ 'description': 'A boolean flag indicating if the protocol handler should be set as the default.',
+ 'type': 'boolean'
+ },
+ 'protocol': {
+ 'description': 'The protocol for the protocol handler.',
+ 'type': 'string'
+ },
+ 'url': {
+ 'description': 'The URL of the protocol handler.',
+ 'type': 'string'
+ }
+ },
+ 'required': ['protocol', 'url']
+ }
+ },
+ 'supported_on': ['chrome.*:37-', 'chrome_os:37-'],
+ 'features': {
+ 'dynamic_refresh': False,
+ 'per_profile': True,
+ },
+ 'example_value': [{'protocol': 'mailto', 'url': 'https://mail.google.com/mail/?extsrc=mailto&url=%s', 'default': 'true'}],
+ 'id': 268,
+ 'caption': '''Register protocol handlers''',
+ 'desc': '''Allows you to register a list of protocol handlers. This can only be a recommended policy. The property |protocol| should be set to the scheme such as 'mailto' and the property |url| should be set to the URL pattern of the application that handles the scheme. The pattern can include a '%s', which if present will be replaced by the handled URL.
+
+ The protocol handlers registered by policy are merged with the ones registered by the user and both are available for use. The user can override the protocol handlers installed by policy by installing a new default handler, but cannot remove a protocol handler registered by policy.''',
+ },
+ {
'name': 'PopupsBlockedForUrls',
'type': 'list',
'schema': {
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp
index de2e5eb..7d9e3f8 100644
--- a/components/policy_strings.grdp
+++ b/components/policy_strings.grdp
@@ -202,6 +202,9 @@
Policy scope is not supported.
</message>
</if>
+ <message name="IDS_POLICY_LEVEL_ERROR" desc="Text displayed in the status column when a policy is set at an unsupported level.">
+ Policy level is not supported.
+ </message>
<message name="IDS_POLICY_OK" desc="Text displayed in the status column when a valid value is set for a policy.">
OK
</message>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index fa6ae55..e0710b1 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -35405,6 +35405,7 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="265" label="Enables the old web-based signin"/>
<int value="266" label="Block developer mode"/>
<int value="267" label="Show the apps shortcut in the bookmark bar"/>
+ <int value="268" label="Register protocol handlers"/>
</enum>
<enum name="EnterprisePolicyInvalidations" type="int">