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/browser/policy/policy_error_map.h"
11 #include "chrome/browser/policy/policy_map.h"
12 #include "chrome/common/extensions/extension.h"
13 #include "chrome/common/pref_names.h"
14 #include "grit/generated_resources.h"
15 #include "policy/policy_constants.h"
17 namespace extensions {
19 // ExtensionListPolicyHandler implementation -----------------------------------
21 ExtensionListPolicyHandler::ExtensionListPolicyHandler(const char* policy_name,
22 const char* pref_path,
24 : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
25 pref_path_(pref_path),
26 allow_wildcards_(allow_wildcards) {}
28 ExtensionListPolicyHandler::~ExtensionListPolicyHandler() {}
30 bool ExtensionListPolicyHandler::CheckPolicySettings(
31 const policy::PolicyMap& policies,
32 policy::PolicyErrorMap* errors) {
33 return CheckAndGetList(policies, errors, NULL);
36 void ExtensionListPolicyHandler::ApplyPolicySettings(
37 const policy::PolicyMap& policies,
38 PrefValueMap* prefs) {
39 scoped_ptr<base::ListValue> list;
40 policy::PolicyErrorMap errors;
41 if (CheckAndGetList(policies, &errors, &list) && list)
42 prefs->SetValue(pref_path(), list.release());
45 const char* ExtensionListPolicyHandler::pref_path() const {
49 bool ExtensionListPolicyHandler::CheckAndGetList(
50 const policy::PolicyMap& policies,
51 policy::PolicyErrorMap* errors,
52 scoped_ptr<base::ListValue>* extension_ids) {
54 extension_ids->reset();
56 const base::Value* value = NULL;
57 if (!CheckAndGetValue(policies, errors, &value))
63 const base::ListValue* list_value = NULL;
64 if (!value->GetAsList(&list_value)) {
69 // Filter the list, rejecting any invalid extension IDs.
70 scoped_ptr<base::ListValue> filtered_list(new base::ListValue());
71 for (base::ListValue::const_iterator entry(list_value->begin());
72 entry != list_value->end(); ++entry) {
74 if (!(*entry)->GetAsString(&id)) {
75 errors->AddError(policy_name(),
76 entry - list_value->begin(),
77 IDS_POLICY_TYPE_ERROR,
78 ValueTypeToString(base::Value::TYPE_STRING));
81 if (!(allow_wildcards_ && id == "*") &&
82 !extensions::Extension::IdIsValid(id)) {
83 errors->AddError(policy_name(),
84 entry - list_value->begin(),
85 IDS_POLICY_VALUE_FORMAT_ERROR);
88 filtered_list->Append(base::Value::CreateStringValue(id));
92 *extension_ids = filtered_list.Pass();
97 // ExtensionInstallForcelistPolicyHandler implementation -----------------------
99 ExtensionInstallForcelistPolicyHandler::ExtensionInstallForcelistPolicyHandler()
100 : policy::TypeCheckingPolicyHandler(policy::key::kExtensionInstallForcelist,
101 base::Value::TYPE_LIST) {}
103 ExtensionInstallForcelistPolicyHandler::
104 ~ExtensionInstallForcelistPolicyHandler() {}
106 bool ExtensionInstallForcelistPolicyHandler::CheckPolicySettings(
107 const policy::PolicyMap& policies,
108 policy::PolicyErrorMap* errors) {
109 const base::Value* value;
110 return CheckAndGetValue(policies, errors, &value) &&
111 ParseList(value, NULL, errors);
114 void ExtensionInstallForcelistPolicyHandler::ApplyPolicySettings(
115 const policy::PolicyMap& policies,
116 PrefValueMap* prefs) {
117 const base::Value* value = NULL;
118 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
119 if (CheckAndGetValue(policies, NULL, &value) &&
121 ParseList(value, dict.get(), NULL)) {
122 prefs->SetValue(prefs::kExtensionInstallForceList, dict.release());
126 bool ExtensionInstallForcelistPolicyHandler::ParseList(
127 const base::Value* policy_value,
128 base::DictionaryValue* extension_dict,
129 policy::PolicyErrorMap* errors) {
133 const base::ListValue* policy_list_value = NULL;
134 if (!policy_value->GetAsList(&policy_list_value)) {
135 // This should have been caught in CheckPolicySettings.
140 for (base::ListValue::const_iterator entry(policy_list_value->begin());
141 entry != policy_list_value->end(); ++entry) {
142 std::string entry_string;
143 if (!(*entry)->GetAsString(&entry_string)) {
145 errors->AddError(policy_name(),
146 entry - policy_list_value->begin(),
147 IDS_POLICY_TYPE_ERROR,
148 ValueTypeToString(base::Value::TYPE_STRING));
153 // Each string item of the list has the following form:
154 // <extension_id>;<update_url>
155 // Note: The update URL might also contain semicolons.
156 size_t pos = entry_string.find(';');
157 if (pos == std::string::npos) {
159 errors->AddError(policy_name(),
160 entry - policy_list_value->begin(),
161 IDS_POLICY_VALUE_FORMAT_ERROR);
166 std::string extension_id = entry_string.substr(0, pos);
167 std::string update_url = entry_string.substr(pos+1);
168 if (!extensions::Extension::IdIsValid(extension_id) ||
169 !GURL(update_url).is_valid()) {
171 errors->AddError(policy_name(),
172 entry - policy_list_value->begin(),
173 IDS_POLICY_VALUE_FORMAT_ERROR);
178 if (extension_dict) {
179 extensions::ExternalPolicyLoader::AddExtension(
180 extension_dict, extension_id, update_url);
187 // ExtensionURLPatternListPolicyHandler implementation -------------------------
189 ExtensionURLPatternListPolicyHandler::ExtensionURLPatternListPolicyHandler(
190 const char* policy_name,
191 const char* pref_path)
192 : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
193 pref_path_(pref_path) {}
195 ExtensionURLPatternListPolicyHandler::~ExtensionURLPatternListPolicyHandler() {}
197 bool ExtensionURLPatternListPolicyHandler::CheckPolicySettings(
198 const policy::PolicyMap& policies,
199 policy::PolicyErrorMap* errors) {
200 const base::Value* value = NULL;
201 if (!CheckAndGetValue(policies, errors, &value))
207 const base::ListValue* list_value = NULL;
208 if (!value->GetAsList(&list_value)) {
213 // Check that the list contains valid URLPattern strings only.
214 for (base::ListValue::const_iterator entry(list_value->begin());
215 entry != list_value->end(); ++entry) {
216 std::string url_pattern_string;
217 if (!(*entry)->GetAsString(&url_pattern_string)) {
218 errors->AddError(policy_name(),
219 entry - list_value->begin(),
220 IDS_POLICY_TYPE_ERROR,
221 ValueTypeToString(base::Value::TYPE_STRING));
225 URLPattern pattern(URLPattern::SCHEME_ALL);
226 if (pattern.Parse(url_pattern_string) != URLPattern::PARSE_SUCCESS) {
227 errors->AddError(policy_name(),
228 entry - list_value->begin(),
229 IDS_POLICY_VALUE_FORMAT_ERROR);
237 void ExtensionURLPatternListPolicyHandler::ApplyPolicySettings(
238 const policy::PolicyMap& policies,
239 PrefValueMap* prefs) {
242 const Value* value = policies.GetValue(policy_name());
244 prefs->SetValue(pref_path_, value->DeepCopy());
247 } // namespace extensions