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/policy/core/browser/policy_error_map.h"
12 #include "components/policy/core/common/policy_map.h"
13 #include "extensions/browser/pref_names.h"
14 #include "extensions/common/extension.h"
15 #include "grit/component_strings.h"
16 #include "policy/policy_constants.h"
18 namespace extensions
{
20 // ExtensionListPolicyHandler implementation -----------------------------------
22 ExtensionListPolicyHandler::ExtensionListPolicyHandler(const char* policy_name
,
23 const char* pref_path
,
25 : policy::TypeCheckingPolicyHandler(policy_name
, base::Value::TYPE_LIST
),
26 pref_path_(pref_path
),
27 allow_wildcards_(allow_wildcards
) {}
29 ExtensionListPolicyHandler::~ExtensionListPolicyHandler() {}
31 bool ExtensionListPolicyHandler::CheckPolicySettings(
32 const policy::PolicyMap
& policies
,
33 policy::PolicyErrorMap
* errors
) {
34 return CheckAndGetList(policies
, errors
, NULL
);
37 void ExtensionListPolicyHandler::ApplyPolicySettings(
38 const policy::PolicyMap
& policies
,
39 PrefValueMap
* prefs
) {
40 scoped_ptr
<base::ListValue
> list
;
41 policy::PolicyErrorMap errors
;
42 if (CheckAndGetList(policies
, &errors
, &list
) && list
)
43 prefs
->SetValue(pref_path(), list
.release());
46 const char* ExtensionListPolicyHandler::pref_path() const {
50 bool ExtensionListPolicyHandler::CheckAndGetList(
51 const policy::PolicyMap
& policies
,
52 policy::PolicyErrorMap
* errors
,
53 scoped_ptr
<base::ListValue
>* extension_ids
) {
55 extension_ids
->reset();
57 const base::Value
* value
= NULL
;
58 if (!CheckAndGetValue(policies
, errors
, &value
))
64 const base::ListValue
* list_value
= NULL
;
65 if (!value
->GetAsList(&list_value
)) {
70 // Filter the list, rejecting any invalid extension IDs.
71 scoped_ptr
<base::ListValue
> filtered_list(new base::ListValue());
72 for (base::ListValue::const_iterator
entry(list_value
->begin());
73 entry
!= list_value
->end(); ++entry
) {
75 if (!(*entry
)->GetAsString(&id
)) {
76 errors
->AddError(policy_name(),
77 entry
- list_value
->begin(),
78 IDS_POLICY_TYPE_ERROR
,
79 ValueTypeToString(base::Value::TYPE_STRING
));
82 if (!(allow_wildcards_
&& id
== "*") &&
83 !extensions::Extension::IdIsValid(id
)) {
84 errors
->AddError(policy_name(),
85 entry
- list_value
->begin(),
86 IDS_POLICY_VALUE_FORMAT_ERROR
);
89 filtered_list
->Append(base::Value::CreateStringValue(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 (!extensions::Extension::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