1 // Copyright 2013 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 "chrome/browser/extensions/policy_handlers.h"
7 #include "base/logging.h"
8 #include "base/prefs/pref_value_map.h"
9 #include "chrome/browser/extensions/external_policy_loader.h"
10 #include "chrome/common/pref_names.h"
11 #include "components/crx_file/id_util.h"
12 #include "components/policy/core/browser/policy_error_map.h"
13 #include "components/policy/core/common/policy_map.h"
14 #include "extensions/browser/pref_names.h"
15 #include "extensions/common/extension.h"
16 #include "grit/components_strings.h"
17 #include "policy/policy_constants.h"
19 namespace extensions {
21 // ExtensionListPolicyHandler implementation -----------------------------------
23 ExtensionListPolicyHandler::ExtensionListPolicyHandler(const char* policy_name,
24 const char* pref_path,
26 : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
27 pref_path_(pref_path),
28 allow_wildcards_(allow_wildcards) {}
30 ExtensionListPolicyHandler::~ExtensionListPolicyHandler() {}
32 bool ExtensionListPolicyHandler::CheckPolicySettings(
33 const policy::PolicyMap& policies,
34 policy::PolicyErrorMap* errors) {
35 return CheckAndGetList(policies, errors, NULL);
38 void ExtensionListPolicyHandler::ApplyPolicySettings(
39 const policy::PolicyMap& policies,
40 PrefValueMap* prefs) {
41 scoped_ptr<base::ListValue> list;
42 policy::PolicyErrorMap errors;
43 if (CheckAndGetList(policies, &errors, &list) && list)
44 prefs->SetValue(pref_path(), list.release());
47 const char* ExtensionListPolicyHandler::pref_path() const {
51 bool ExtensionListPolicyHandler::CheckAndGetList(
52 const policy::PolicyMap& policies,
53 policy::PolicyErrorMap* errors,
54 scoped_ptr<base::ListValue>* extension_ids) {
56 extension_ids->reset();
58 const base::Value* value = NULL;
59 if (!CheckAndGetValue(policies, errors, &value))
65 const base::ListValue* list_value = NULL;
66 if (!value->GetAsList(&list_value)) {
71 // Filter the list, rejecting any invalid extension IDs.
72 scoped_ptr<base::ListValue> filtered_list(new base::ListValue());
73 for (base::ListValue::const_iterator entry(list_value->begin());
74 entry != list_value->end(); ++entry) {
76 if (!(*entry)->GetAsString(&id)) {
77 errors->AddError(policy_name(),
78 entry - list_value->begin(),
79 IDS_POLICY_TYPE_ERROR,
80 ValueTypeToString(base::Value::TYPE_STRING));
83 if (!(allow_wildcards_ && id == "*") && !crx_file::id_util::IdIsValid(id)) {
84 errors->AddError(policy_name(),
85 entry - list_value->begin(),
86 IDS_POLICY_VALUE_FORMAT_ERROR);
89 filtered_list->Append(new base::StringValue(id));
93 *extension_ids = filtered_list.Pass();
98 // ExtensionInstallForcelistPolicyHandler implementation -----------------------
100 ExtensionInstallForcelistPolicyHandler::ExtensionInstallForcelistPolicyHandler()
101 : policy::TypeCheckingPolicyHandler(policy::key::kExtensionInstallForcelist,
102 base::Value::TYPE_LIST) {}
104 ExtensionInstallForcelistPolicyHandler::
105 ~ExtensionInstallForcelistPolicyHandler() {}
107 bool ExtensionInstallForcelistPolicyHandler::CheckPolicySettings(
108 const policy::PolicyMap& policies,
109 policy::PolicyErrorMap* errors) {
110 const base::Value* value;
111 return CheckAndGetValue(policies, errors, &value) &&
112 ParseList(value, NULL, errors);
115 void ExtensionInstallForcelistPolicyHandler::ApplyPolicySettings(
116 const policy::PolicyMap& policies,
117 PrefValueMap* prefs) {
118 const base::Value* value = NULL;
119 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
120 if (CheckAndGetValue(policies, NULL, &value) &&
122 ParseList(value, dict.get(), NULL)) {
123 prefs->SetValue(pref_names::kInstallForceList, dict.release());
127 bool ExtensionInstallForcelistPolicyHandler::ParseList(
128 const base::Value* policy_value,
129 base::DictionaryValue* extension_dict,
130 policy::PolicyErrorMap* errors) {
134 const base::ListValue* policy_list_value = NULL;
135 if (!policy_value->GetAsList(&policy_list_value)) {
136 // This should have been caught in CheckPolicySettings.
141 for (base::ListValue::const_iterator entry(policy_list_value->begin());
142 entry != policy_list_value->end(); ++entry) {
143 std::string entry_string;
144 if (!(*entry)->GetAsString(&entry_string)) {
146 errors->AddError(policy_name(),
147 entry - policy_list_value->begin(),
148 IDS_POLICY_TYPE_ERROR,
149 ValueTypeToString(base::Value::TYPE_STRING));
154 // Each string item of the list has the following form:
155 // <extension_id>;<update_url>
156 // Note: The update URL might also contain semicolons.
157 size_t pos = entry_string.find(';');
158 if (pos == std::string::npos) {
160 errors->AddError(policy_name(),
161 entry - policy_list_value->begin(),
162 IDS_POLICY_VALUE_FORMAT_ERROR);
167 std::string extension_id = entry_string.substr(0, pos);
168 std::string update_url = entry_string.substr(pos+1);
169 if (!crx_file::id_util::IdIsValid(extension_id) ||
170 !GURL(update_url).is_valid()) {
172 errors->AddError(policy_name(),
173 entry - policy_list_value->begin(),
174 IDS_POLICY_VALUE_FORMAT_ERROR);
179 if (extension_dict) {
180 extensions::ExternalPolicyLoader::AddExtension(
181 extension_dict, extension_id, update_url);
188 // ExtensionURLPatternListPolicyHandler implementation -------------------------
190 ExtensionURLPatternListPolicyHandler::ExtensionURLPatternListPolicyHandler(
191 const char* policy_name,
192 const char* pref_path)
193 : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
194 pref_path_(pref_path) {}
196 ExtensionURLPatternListPolicyHandler::~ExtensionURLPatternListPolicyHandler() {}
198 bool ExtensionURLPatternListPolicyHandler::CheckPolicySettings(
199 const policy::PolicyMap& policies,
200 policy::PolicyErrorMap* errors) {
201 const base::Value* value = NULL;
202 if (!CheckAndGetValue(policies, errors, &value))
208 const base::ListValue* list_value = NULL;
209 if (!value->GetAsList(&list_value)) {
214 // Check that the list contains valid URLPattern strings only.
215 for (base::ListValue::const_iterator entry(list_value->begin());
216 entry != list_value->end(); ++entry) {
217 std::string url_pattern_string;
218 if (!(*entry)->GetAsString(&url_pattern_string)) {
219 errors->AddError(policy_name(),
220 entry - list_value->begin(),
221 IDS_POLICY_TYPE_ERROR,
222 ValueTypeToString(base::Value::TYPE_STRING));
226 URLPattern pattern(URLPattern::SCHEME_ALL);
227 if (pattern.Parse(url_pattern_string) != URLPattern::PARSE_SUCCESS) {
228 errors->AddError(policy_name(),
229 entry - list_value->begin(),
230 IDS_POLICY_VALUE_FORMAT_ERROR);
238 void ExtensionURLPatternListPolicyHandler::ApplyPolicySettings(
239 const policy::PolicyMap& policies,
240 PrefValueMap* prefs) {
243 const base::Value* value = policies.GetValue(policy_name());
245 prefs->SetValue(pref_path_, value->DeepCopy());
248 } // namespace extensions