Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / policy_handlers.cc
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.
4
5 #include "chrome/browser/extensions/policy_handlers.h"
6
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/components_strings.h"
16 #include "policy/policy_constants.h"
17
18 namespace extensions {
19
20 // ExtensionListPolicyHandler implementation -----------------------------------
21
22 ExtensionListPolicyHandler::ExtensionListPolicyHandler(const char* policy_name,
23                                                        const char* pref_path,
24                                                        bool allow_wildcards)
25     : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
26       pref_path_(pref_path),
27       allow_wildcards_(allow_wildcards) {}
28
29 ExtensionListPolicyHandler::~ExtensionListPolicyHandler() {}
30
31 bool ExtensionListPolicyHandler::CheckPolicySettings(
32     const policy::PolicyMap& policies,
33     policy::PolicyErrorMap* errors) {
34   return CheckAndGetList(policies, errors, NULL);
35 }
36
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());
44 }
45
46 const char* ExtensionListPolicyHandler::pref_path() const {
47   return pref_path_;
48 }
49
50 bool ExtensionListPolicyHandler::CheckAndGetList(
51     const policy::PolicyMap& policies,
52     policy::PolicyErrorMap* errors,
53     scoped_ptr<base::ListValue>* extension_ids) {
54   if (extension_ids)
55     extension_ids->reset();
56
57   const base::Value* value = NULL;
58   if (!CheckAndGetValue(policies, errors, &value))
59     return false;
60
61   if (!value)
62     return true;
63
64   const base::ListValue* list_value = NULL;
65   if (!value->GetAsList(&list_value)) {
66     NOTREACHED();
67     return false;
68   }
69
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) {
74     std::string id;
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));
80       continue;
81     }
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);
87       continue;
88     }
89     filtered_list->Append(new base::StringValue(id));
90   }
91
92   if (extension_ids)
93     *extension_ids = filtered_list.Pass();
94
95   return true;
96 }
97
98 // ExtensionInstallForcelistPolicyHandler implementation -----------------------
99
100 ExtensionInstallForcelistPolicyHandler::ExtensionInstallForcelistPolicyHandler()
101     : policy::TypeCheckingPolicyHandler(policy::key::kExtensionInstallForcelist,
102                                         base::Value::TYPE_LIST) {}
103
104 ExtensionInstallForcelistPolicyHandler::
105     ~ExtensionInstallForcelistPolicyHandler() {}
106
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);
113 }
114
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) &&
121       value &&
122       ParseList(value, dict.get(), NULL)) {
123     prefs->SetValue(pref_names::kInstallForceList, dict.release());
124   }
125 }
126
127 bool ExtensionInstallForcelistPolicyHandler::ParseList(
128     const base::Value* policy_value,
129     base::DictionaryValue* extension_dict,
130     policy::PolicyErrorMap* errors) {
131   if (!policy_value)
132     return true;
133
134   const base::ListValue* policy_list_value = NULL;
135   if (!policy_value->GetAsList(&policy_list_value)) {
136     // This should have been caught in CheckPolicySettings.
137     NOTREACHED();
138     return false;
139   }
140
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)) {
145       if (errors) {
146         errors->AddError(policy_name(),
147                          entry - policy_list_value->begin(),
148                          IDS_POLICY_TYPE_ERROR,
149                          ValueTypeToString(base::Value::TYPE_STRING));
150       }
151       continue;
152     }
153
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) {
159       if (errors) {
160         errors->AddError(policy_name(),
161                          entry - policy_list_value->begin(),
162                          IDS_POLICY_VALUE_FORMAT_ERROR);
163       }
164       continue;
165     }
166
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()) {
171       if (errors) {
172         errors->AddError(policy_name(),
173                          entry - policy_list_value->begin(),
174                          IDS_POLICY_VALUE_FORMAT_ERROR);
175       }
176       continue;
177     }
178
179     if (extension_dict) {
180       extensions::ExternalPolicyLoader::AddExtension(
181           extension_dict, extension_id, update_url);
182     }
183   }
184
185   return true;
186 }
187
188 // ExtensionURLPatternListPolicyHandler implementation -------------------------
189
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) {}
195
196 ExtensionURLPatternListPolicyHandler::~ExtensionURLPatternListPolicyHandler() {}
197
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))
203     return false;
204
205   if (!value)
206     return true;
207
208   const base::ListValue* list_value = NULL;
209   if (!value->GetAsList(&list_value)) {
210     NOTREACHED();
211     return false;
212   }
213
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));
223       return false;
224     }
225
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);
231       return false;
232     }
233   }
234
235   return true;
236 }
237
238 void ExtensionURLPatternListPolicyHandler::ApplyPolicySettings(
239     const policy::PolicyMap& policies,
240     PrefValueMap* prefs) {
241   if (!pref_path_)
242     return;
243   const base::Value* value = policies.GetValue(policy_name());
244   if (value)
245     prefs->SetValue(pref_path_, value->DeepCopy());
246 }
247
248 }  // namespace extensions