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