Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / components / policy / core / browser / configuration_policy_handler.cc
1 // Copyright (c) 2012 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 "components/policy/core/browser/configuration_policy_handler.h"
6
7 #include <algorithm>
8
9 #include "base/callback.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/prefs/pref_value_map.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "components/policy/core/browser/policy_error_map.h"
17 #include "components/policy/core/common/policy_map.h"
18 #include "grit/component_strings.h"
19 #include "url/gurl.h"
20
21 namespace policy {
22
23 // ConfigurationPolicyHandler implementation -----------------------------------
24
25 // static
26 std::string ConfigurationPolicyHandler::ValueTypeToString(
27     base::Value::Type type) {
28   static const char* strings[] = {
29     "null",
30     "boolean",
31     "integer",
32     "double",
33     "string",
34     "binary",
35     "dictionary",
36     "list"
37   };
38   CHECK(static_cast<size_t>(type) < arraysize(strings));
39   return std::string(strings[type]);
40 }
41
42 ConfigurationPolicyHandler::ConfigurationPolicyHandler() {
43 }
44
45 ConfigurationPolicyHandler::~ConfigurationPolicyHandler() {
46 }
47
48 void ConfigurationPolicyHandler::PrepareForDisplaying(
49     PolicyMap* policies) const {}
50
51
52 // TypeCheckingPolicyHandler implementation ------------------------------------
53
54 TypeCheckingPolicyHandler::TypeCheckingPolicyHandler(
55     const char* policy_name,
56     base::Value::Type value_type)
57     : policy_name_(policy_name),
58       value_type_(value_type) {
59 }
60
61 TypeCheckingPolicyHandler::~TypeCheckingPolicyHandler() {
62 }
63
64 const char* TypeCheckingPolicyHandler::policy_name() const {
65   return policy_name_;
66 }
67
68 bool TypeCheckingPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
69                                                     PolicyErrorMap* errors) {
70   const base::Value* value = NULL;
71   return CheckAndGetValue(policies, errors, &value);
72 }
73
74 bool TypeCheckingPolicyHandler::CheckAndGetValue(const PolicyMap& policies,
75                                                  PolicyErrorMap* errors,
76                                                  const base::Value** value) {
77   *value = policies.GetValue(policy_name_);
78   if (*value && !(*value)->IsType(value_type_)) {
79     errors->AddError(policy_name_,
80                      IDS_POLICY_TYPE_ERROR,
81                      ValueTypeToString(value_type_));
82     return false;
83   }
84   return true;
85 }
86
87
88 // IntRangePolicyHandlerBase implementation ------------------------------------
89
90 IntRangePolicyHandlerBase::IntRangePolicyHandlerBase(
91     const char* policy_name,
92     int min,
93     int max,
94     bool clamp)
95     : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_INTEGER),
96       min_(min),
97       max_(max),
98       clamp_(clamp) {
99 }
100
101 bool IntRangePolicyHandlerBase::CheckPolicySettings(const PolicyMap& policies,
102                                                     PolicyErrorMap* errors) {
103   const base::Value* value;
104   return CheckAndGetValue(policies, errors, &value) &&
105       EnsureInRange(value, NULL, errors);
106 }
107
108 IntRangePolicyHandlerBase::~IntRangePolicyHandlerBase() {
109 }
110
111 bool IntRangePolicyHandlerBase::EnsureInRange(const base::Value* input,
112                                               int* output,
113                                               PolicyErrorMap* errors) {
114   if (!input)
115     return true;
116
117   int value;
118   if (!input->GetAsInteger(&value)) {
119     NOTREACHED();
120     return false;
121   }
122
123   if (value < min_ || value > max_) {
124     if (errors) {
125       errors->AddError(policy_name(),
126                        IDS_POLICY_OUT_OF_RANGE_ERROR,
127                        base::IntToString(value));
128     }
129
130     if (!clamp_)
131       return false;
132
133     value = std::min(std::max(value, min_), max_);
134   }
135
136   if (output)
137     *output = value;
138   return true;
139 }
140
141
142 // StringToIntEnumListPolicyHandler implementation -----------------------------
143
144 StringToIntEnumListPolicyHandler::StringToIntEnumListPolicyHandler(
145     const char* policy_name,
146     const char* pref_path,
147     const MappingEntry* mapping_begin,
148     const MappingEntry* mapping_end)
149     : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
150       pref_path_(pref_path),
151       mapping_begin_(mapping_begin),
152       mapping_end_(mapping_end) {}
153
154 bool StringToIntEnumListPolicyHandler::CheckPolicySettings(
155     const PolicyMap& policies,
156     PolicyErrorMap* errors) {
157   const base::Value* value;
158   return CheckAndGetValue(policies, errors, &value) &&
159       Convert(value, NULL, errors);
160 }
161
162 void StringToIntEnumListPolicyHandler::ApplyPolicySettings(
163     const PolicyMap& policies,
164     PrefValueMap* prefs) {
165   if (!pref_path_)
166     return;
167   const base::Value* value = policies.GetValue(policy_name());
168   scoped_ptr<base::ListValue> list(new base::ListValue());
169   if (value && Convert(value, list.get(), NULL))
170     prefs->SetValue(pref_path_, list.release());
171 }
172
173 bool StringToIntEnumListPolicyHandler::Convert(const base::Value* input,
174                                                base::ListValue* output,
175                                                PolicyErrorMap* errors) {
176   if (!input)
177     return true;
178
179   const base::ListValue* list_value = NULL;
180   if (!input->GetAsList(&list_value)) {
181     NOTREACHED();
182     return false;
183   }
184
185   for (base::ListValue::const_iterator entry(list_value->begin());
186        entry != list_value->end(); ++entry) {
187     std::string entry_value;
188     if (!(*entry)->GetAsString(&entry_value)) {
189       if (errors) {
190         errors->AddError(policy_name(),
191                          entry - list_value->begin(),
192                          IDS_POLICY_TYPE_ERROR,
193                          ValueTypeToString(base::Value::TYPE_STRING));
194       }
195       continue;
196     }
197     bool found = false;
198     for (const MappingEntry* mapping_entry(mapping_begin_);
199          mapping_entry != mapping_end_; ++mapping_entry) {
200       if (mapping_entry->enum_value == entry_value) {
201         found = true;
202         if (output)
203           output->AppendInteger(mapping_entry->int_value);
204         break;
205       }
206     }
207     if (!found) {
208       if (errors) {
209         errors->AddError(policy_name(),
210                          entry - list_value->begin(),
211                          IDS_POLICY_OUT_OF_RANGE_ERROR);
212       }
213     }
214   }
215
216   return true;
217 }
218
219
220 // IntRangePolicyHandler implementation ----------------------------------------
221
222 IntRangePolicyHandler::IntRangePolicyHandler(const char* policy_name,
223                                              const char* pref_path,
224                                              int min,
225                                              int max,
226                                              bool clamp)
227     : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
228       pref_path_(pref_path) {
229 }
230
231 IntRangePolicyHandler::~IntRangePolicyHandler() {
232 }
233
234 void IntRangePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
235                                                 PrefValueMap* prefs) {
236   if (!pref_path_)
237     return;
238   const base::Value* value = policies.GetValue(policy_name());
239   int value_in_range;
240   if (value && EnsureInRange(value, &value_in_range, NULL)) {
241     prefs->SetValue(pref_path_,
242                     base::Value::CreateIntegerValue(value_in_range));
243   }
244 }
245
246
247 // IntPercentageToDoublePolicyHandler implementation ---------------------------
248
249 IntPercentageToDoublePolicyHandler::IntPercentageToDoublePolicyHandler(
250     const char* policy_name,
251     const char* pref_path,
252     int min,
253     int max,
254     bool clamp)
255     : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
256       pref_path_(pref_path) {
257 }
258
259 IntPercentageToDoublePolicyHandler::~IntPercentageToDoublePolicyHandler() {
260 }
261
262 void IntPercentageToDoublePolicyHandler::ApplyPolicySettings(
263     const PolicyMap& policies,
264     PrefValueMap* prefs) {
265   if (!pref_path_)
266     return;
267   const base::Value* value = policies.GetValue(policy_name());
268   int percentage;
269   if (value && EnsureInRange(value, &percentage, NULL)) {
270     prefs->SetValue(pref_path_, base::Value::CreateDoubleValue(
271         static_cast<double>(percentage) / 100.));
272   }
273 }
274
275
276 // SimplePolicyHandler implementation ------------------------------------------
277
278 SimplePolicyHandler::SimplePolicyHandler(
279     const char* policy_name,
280     const char* pref_path,
281     base::Value::Type value_type)
282     : TypeCheckingPolicyHandler(policy_name, value_type),
283       pref_path_(pref_path) {
284 }
285
286 SimplePolicyHandler::~SimplePolicyHandler() {
287 }
288
289 void SimplePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
290                                               PrefValueMap* prefs) {
291   if (!pref_path_)
292     return;
293   const base::Value* value = policies.GetValue(policy_name());
294   if (value)
295     prefs->SetValue(pref_path_, value->DeepCopy());
296 }
297
298
299 // SchemaValidatingPolicyHandler implementation --------------------------------
300
301 SchemaValidatingPolicyHandler::SchemaValidatingPolicyHandler(
302     const char* policy_name,
303     Schema schema,
304     SchemaOnErrorStrategy strategy)
305     : policy_name_(policy_name), schema_(schema), strategy_(strategy) {
306   DCHECK(schema_.valid());
307 }
308
309 SchemaValidatingPolicyHandler::~SchemaValidatingPolicyHandler() {
310 }
311
312 const char* SchemaValidatingPolicyHandler::policy_name() const {
313   return policy_name_;
314 }
315
316 bool SchemaValidatingPolicyHandler::CheckPolicySettings(
317     const PolicyMap& policies,
318     PolicyErrorMap* errors) {
319   const base::Value* value = policies.GetValue(policy_name());
320   if (!value)
321     return true;
322
323   std::string error_path;
324   std::string error;
325   bool result = schema_.Validate(*value, strategy_, &error_path, &error);
326
327   if (errors && !error.empty()) {
328     if (error_path.empty())
329       error_path = "(ROOT)";
330     errors->AddError(policy_name_, error_path, error);
331   }
332
333   return result;
334 }
335
336 bool SchemaValidatingPolicyHandler::CheckAndGetValue(
337     const PolicyMap& policies,
338     PolicyErrorMap* errors,
339     scoped_ptr<base::Value>* output) {
340   const base::Value* value = policies.GetValue(policy_name());
341   if (!value)
342     return true;
343
344   output->reset(value->DeepCopy());
345   std::string error_path;
346   std::string error;
347   bool result =
348       schema_.Normalize(output->get(), strategy_, &error_path, &error);
349
350   if (errors && !error.empty()) {
351     if (error_path.empty())
352       error_path = "(ROOT)";
353     errors->AddError(policy_name_, error_path, error);
354   }
355
356   return result;
357 }
358
359 }  // namespace policy