Ignore title parameter for navigator.registerProtocolHandler
[chromium-blink-merge.git] / components / policy / core / browser / configuration_policy_handler.cc
blob0a7aea856b6ceda24772dc879fab2da113d37a11
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.
5 #include "components/policy/core/browser/configuration_policy_handler.h"
7 #include <algorithm>
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"
21 namespace policy {
23 // ConfigurationPolicyHandler implementation -----------------------------------
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"
38 CHECK(static_cast<size_t>(type) < arraysize(strings));
39 return std::string(strings[type]);
42 ConfigurationPolicyHandler::ConfigurationPolicyHandler() {
45 ConfigurationPolicyHandler::~ConfigurationPolicyHandler() {
48 void ConfigurationPolicyHandler::PrepareForDisplaying(
49 PolicyMap* policies) const {}
51 void ConfigurationPolicyHandler::ApplyPolicySettings(
52 const policy::PolicyMap& policies,
53 PrefValueMap* prefs) {
54 NOTREACHED();
57 void ConfigurationPolicyHandler::ApplyPolicySettingsWithParameters(
58 const PolicyMap& policies,
59 const PolicyHandlerParameters& parameters,
60 PrefValueMap* prefs) {
61 ApplyPolicySettings(policies, prefs);
64 // TypeCheckingPolicyHandler implementation ------------------------------------
66 TypeCheckingPolicyHandler::TypeCheckingPolicyHandler(
67 const char* policy_name,
68 base::Value::Type value_type)
69 : policy_name_(policy_name),
70 value_type_(value_type) {
73 TypeCheckingPolicyHandler::~TypeCheckingPolicyHandler() {
76 const char* TypeCheckingPolicyHandler::policy_name() const {
77 return policy_name_;
80 bool TypeCheckingPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
81 PolicyErrorMap* errors) {
82 const base::Value* value = NULL;
83 return CheckAndGetValue(policies, errors, &value);
86 bool TypeCheckingPolicyHandler::CheckAndGetValue(const PolicyMap& policies,
87 PolicyErrorMap* errors,
88 const base::Value** value) {
89 *value = policies.GetValue(policy_name_);
90 if (*value && !(*value)->IsType(value_type_)) {
91 errors->AddError(policy_name_,
92 IDS_POLICY_TYPE_ERROR,
93 ValueTypeToString(value_type_));
94 return false;
96 return true;
100 // IntRangePolicyHandlerBase implementation ------------------------------------
102 IntRangePolicyHandlerBase::IntRangePolicyHandlerBase(
103 const char* policy_name,
104 int min,
105 int max,
106 bool clamp)
107 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_INTEGER),
108 min_(min),
109 max_(max),
110 clamp_(clamp) {
113 bool IntRangePolicyHandlerBase::CheckPolicySettings(const PolicyMap& policies,
114 PolicyErrorMap* errors) {
115 const base::Value* value;
116 return CheckAndGetValue(policies, errors, &value) &&
117 EnsureInRange(value, NULL, errors);
120 IntRangePolicyHandlerBase::~IntRangePolicyHandlerBase() {
123 bool IntRangePolicyHandlerBase::EnsureInRange(const base::Value* input,
124 int* output,
125 PolicyErrorMap* errors) {
126 if (!input)
127 return true;
129 int value;
130 if (!input->GetAsInteger(&value)) {
131 NOTREACHED();
132 return false;
135 if (value < min_ || value > max_) {
136 if (errors) {
137 errors->AddError(policy_name(),
138 IDS_POLICY_OUT_OF_RANGE_ERROR,
139 base::IntToString(value));
142 if (!clamp_)
143 return false;
145 value = std::min(std::max(value, min_), max_);
148 if (output)
149 *output = value;
150 return true;
154 // StringToIntEnumListPolicyHandler implementation -----------------------------
156 StringToIntEnumListPolicyHandler::StringToIntEnumListPolicyHandler(
157 const char* policy_name,
158 const char* pref_path,
159 const MappingEntry* mapping_begin,
160 const MappingEntry* mapping_end)
161 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
162 pref_path_(pref_path),
163 mapping_begin_(mapping_begin),
164 mapping_end_(mapping_end) {}
166 bool StringToIntEnumListPolicyHandler::CheckPolicySettings(
167 const PolicyMap& policies,
168 PolicyErrorMap* errors) {
169 const base::Value* value;
170 return CheckAndGetValue(policies, errors, &value) &&
171 Convert(value, NULL, errors);
174 void StringToIntEnumListPolicyHandler::ApplyPolicySettings(
175 const PolicyMap& policies,
176 PrefValueMap* prefs) {
177 if (!pref_path_)
178 return;
179 const base::Value* value = policies.GetValue(policy_name());
180 scoped_ptr<base::ListValue> list(new base::ListValue());
181 if (value && Convert(value, list.get(), NULL))
182 prefs->SetValue(pref_path_, list.release());
185 bool StringToIntEnumListPolicyHandler::Convert(const base::Value* input,
186 base::ListValue* output,
187 PolicyErrorMap* errors) {
188 if (!input)
189 return true;
191 const base::ListValue* list_value = NULL;
192 if (!input->GetAsList(&list_value)) {
193 NOTREACHED();
194 return false;
197 for (base::ListValue::const_iterator entry(list_value->begin());
198 entry != list_value->end(); ++entry) {
199 std::string entry_value;
200 if (!(*entry)->GetAsString(&entry_value)) {
201 if (errors) {
202 errors->AddError(policy_name(),
203 entry - list_value->begin(),
204 IDS_POLICY_TYPE_ERROR,
205 ValueTypeToString(base::Value::TYPE_STRING));
207 continue;
209 bool found = false;
210 for (const MappingEntry* mapping_entry(mapping_begin_);
211 mapping_entry != mapping_end_; ++mapping_entry) {
212 if (mapping_entry->enum_value == entry_value) {
213 found = true;
214 if (output)
215 output->AppendInteger(mapping_entry->int_value);
216 break;
219 if (!found) {
220 if (errors) {
221 errors->AddError(policy_name(),
222 entry - list_value->begin(),
223 IDS_POLICY_OUT_OF_RANGE_ERROR);
228 return true;
232 // IntRangePolicyHandler implementation ----------------------------------------
234 IntRangePolicyHandler::IntRangePolicyHandler(const char* policy_name,
235 const char* pref_path,
236 int min,
237 int max,
238 bool clamp)
239 : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
240 pref_path_(pref_path) {
243 IntRangePolicyHandler::~IntRangePolicyHandler() {
246 void IntRangePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
247 PrefValueMap* prefs) {
248 if (!pref_path_)
249 return;
250 const base::Value* value = policies.GetValue(policy_name());
251 int value_in_range;
252 if (value && EnsureInRange(value, &value_in_range, NULL)) {
253 prefs->SetValue(pref_path_,
254 base::Value::CreateIntegerValue(value_in_range));
259 // IntPercentageToDoublePolicyHandler implementation ---------------------------
261 IntPercentageToDoublePolicyHandler::IntPercentageToDoublePolicyHandler(
262 const char* policy_name,
263 const char* pref_path,
264 int min,
265 int max,
266 bool clamp)
267 : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
268 pref_path_(pref_path) {
271 IntPercentageToDoublePolicyHandler::~IntPercentageToDoublePolicyHandler() {
274 void IntPercentageToDoublePolicyHandler::ApplyPolicySettings(
275 const PolicyMap& policies,
276 PrefValueMap* prefs) {
277 if (!pref_path_)
278 return;
279 const base::Value* value = policies.GetValue(policy_name());
280 int percentage;
281 if (value && EnsureInRange(value, &percentage, NULL)) {
282 prefs->SetValue(pref_path_, base::Value::CreateDoubleValue(
283 static_cast<double>(percentage) / 100.));
288 // SimplePolicyHandler implementation ------------------------------------------
290 SimplePolicyHandler::SimplePolicyHandler(
291 const char* policy_name,
292 const char* pref_path,
293 base::Value::Type value_type)
294 : TypeCheckingPolicyHandler(policy_name, value_type),
295 pref_path_(pref_path) {
298 SimplePolicyHandler::~SimplePolicyHandler() {
301 void SimplePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
302 PrefValueMap* prefs) {
303 if (!pref_path_)
304 return;
305 const base::Value* value = policies.GetValue(policy_name());
306 if (value)
307 prefs->SetValue(pref_path_, value->DeepCopy());
311 // SchemaValidatingPolicyHandler implementation --------------------------------
313 SchemaValidatingPolicyHandler::SchemaValidatingPolicyHandler(
314 const char* policy_name,
315 Schema schema,
316 SchemaOnErrorStrategy strategy)
317 : policy_name_(policy_name), schema_(schema), strategy_(strategy) {
318 DCHECK(schema_.valid());
321 SchemaValidatingPolicyHandler::~SchemaValidatingPolicyHandler() {
324 const char* SchemaValidatingPolicyHandler::policy_name() const {
325 return policy_name_;
328 bool SchemaValidatingPolicyHandler::CheckPolicySettings(
329 const PolicyMap& policies,
330 PolicyErrorMap* errors) {
331 const base::Value* value = policies.GetValue(policy_name());
332 if (!value)
333 return true;
335 std::string error_path;
336 std::string error;
337 bool result = schema_.Validate(*value, strategy_, &error_path, &error);
339 if (errors && !error.empty()) {
340 if (error_path.empty())
341 error_path = "(ROOT)";
342 errors->AddError(policy_name_, error_path, error);
345 return result;
348 bool SchemaValidatingPolicyHandler::CheckAndGetValue(
349 const PolicyMap& policies,
350 PolicyErrorMap* errors,
351 scoped_ptr<base::Value>* output) {
352 const base::Value* value = policies.GetValue(policy_name());
353 if (!value)
354 return true;
356 output->reset(value->DeepCopy());
357 std::string error_path;
358 std::string error;
359 bool result =
360 schema_.Normalize(output->get(), strategy_, &error_path, &error, NULL);
362 if (errors && !error.empty()) {
363 if (error_path.empty())
364 error_path = "(ROOT)";
365 errors->AddError(policy_name_, error_path, error);
368 return result;
371 // LegacyPoliciesDeprecatingPolicyHandler implementation -----------------------
373 // TODO(binjin): Add a new common base class for SchemaValidatingPolicyHandler
374 // and TypeCheckingPolicyHandler representing policy handlers for a single
375 // policy, and use it as the type of |new_policy_handler|.
376 // http://crbug.com/345299
377 LegacyPoliciesDeprecatingPolicyHandler::LegacyPoliciesDeprecatingPolicyHandler(
378 ScopedVector<ConfigurationPolicyHandler> legacy_policy_handlers,
379 scoped_ptr<SchemaValidatingPolicyHandler> new_policy_handler)
380 : legacy_policy_handlers_(legacy_policy_handlers.Pass()),
381 new_policy_handler_(new_policy_handler.Pass()) {
384 LegacyPoliciesDeprecatingPolicyHandler::
385 ~LegacyPoliciesDeprecatingPolicyHandler() {
388 bool LegacyPoliciesDeprecatingPolicyHandler::CheckPolicySettings(
389 const PolicyMap& policies,
390 PolicyErrorMap* errors) {
391 if (policies.Get(new_policy_handler_->policy_name())) {
392 return new_policy_handler_->CheckPolicySettings(policies, errors);
393 } else {
394 // The new policy is not set, fall back to legacy ones.
395 ScopedVector<ConfigurationPolicyHandler>::iterator handler;
396 bool valid_policy_found = false;
397 for (handler = legacy_policy_handlers_.begin();
398 handler != legacy_policy_handlers_.end();
399 ++handler) {
400 if ((*handler)->CheckPolicySettings(policies, errors))
401 valid_policy_found = true;
403 return valid_policy_found;
407 void LegacyPoliciesDeprecatingPolicyHandler::ApplyPolicySettings(
408 const PolicyMap& policies,
409 PrefValueMap* prefs) {
410 if (policies.Get(new_policy_handler_->policy_name())) {
411 new_policy_handler_->ApplyPolicySettings(policies, prefs);
412 } else {
413 // The new policy is not set, fall back to legacy ones.
414 PolicyErrorMap scoped_errors;
415 ScopedVector<ConfigurationPolicyHandler>::iterator handler;
416 for (handler = legacy_policy_handlers_.begin();
417 handler != legacy_policy_handlers_.end();
418 ++handler) {
419 if ((*handler)->CheckPolicySettings(policies, &scoped_errors))
420 (*handler)->ApplyPolicySettings(policies, prefs);
425 } // namespace policy