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"
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"
23 // ConfigurationPolicyHandler implementation -----------------------------------
26 std::string ConfigurationPolicyHandler::ValueTypeToString(
27 base::Value::Type type) {
28 static const char* strings[] = {
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 {}
52 // TypeCheckingPolicyHandler implementation ------------------------------------
54 TypeCheckingPolicyHandler::TypeCheckingPolicyHandler(
55 const char* policy_name,
56 base::Value::Type value_type)
57 : policy_name_(policy_name),
58 value_type_(value_type) {
61 TypeCheckingPolicyHandler::~TypeCheckingPolicyHandler() {
64 const char* TypeCheckingPolicyHandler::policy_name() const {
68 bool TypeCheckingPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
69 PolicyErrorMap* errors) {
70 const base::Value* value = NULL;
71 return CheckAndGetValue(policies, errors, &value);
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_));
88 // IntRangePolicyHandlerBase implementation ------------------------------------
90 IntRangePolicyHandlerBase::IntRangePolicyHandlerBase(
91 const char* policy_name,
95 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_INTEGER),
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);
108 IntRangePolicyHandlerBase::~IntRangePolicyHandlerBase() {
111 bool IntRangePolicyHandlerBase::EnsureInRange(const base::Value* input,
113 PolicyErrorMap* errors) {
118 if (!input->GetAsInteger(&value)) {
123 if (value < min_ || value > max_) {
125 errors->AddError(policy_name(),
126 IDS_POLICY_OUT_OF_RANGE_ERROR,
127 base::IntToString(value));
133 value = std::min(std::max(value, min_), max_);
142 // StringToIntEnumListPolicyHandler implementation -----------------------------
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) {}
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);
162 void StringToIntEnumListPolicyHandler::ApplyPolicySettings(
163 const PolicyMap& policies,
164 PrefValueMap* prefs) {
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());
173 bool StringToIntEnumListPolicyHandler::Convert(const base::Value* input,
174 base::ListValue* output,
175 PolicyErrorMap* errors) {
179 const base::ListValue* list_value = NULL;
180 if (!input->GetAsList(&list_value)) {
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)) {
190 errors->AddError(policy_name(),
191 entry - list_value->begin(),
192 IDS_POLICY_TYPE_ERROR,
193 ValueTypeToString(base::Value::TYPE_STRING));
198 for (const MappingEntry* mapping_entry(mapping_begin_);
199 mapping_entry != mapping_end_; ++mapping_entry) {
200 if (mapping_entry->enum_value == entry_value) {
203 output->AppendInteger(mapping_entry->int_value);
209 errors->AddError(policy_name(),
210 entry - list_value->begin(),
211 IDS_POLICY_OUT_OF_RANGE_ERROR);
220 // IntRangePolicyHandler implementation ----------------------------------------
222 IntRangePolicyHandler::IntRangePolicyHandler(const char* policy_name,
223 const char* pref_path,
227 : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
228 pref_path_(pref_path) {
231 IntRangePolicyHandler::~IntRangePolicyHandler() {
234 void IntRangePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
235 PrefValueMap* prefs) {
238 const base::Value* value = policies.GetValue(policy_name());
240 if (value && EnsureInRange(value, &value_in_range, NULL)) {
241 prefs->SetValue(pref_path_,
242 base::Value::CreateIntegerValue(value_in_range));
247 // IntPercentageToDoublePolicyHandler implementation ---------------------------
249 IntPercentageToDoublePolicyHandler::IntPercentageToDoublePolicyHandler(
250 const char* policy_name,
251 const char* pref_path,
255 : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
256 pref_path_(pref_path) {
259 IntPercentageToDoublePolicyHandler::~IntPercentageToDoublePolicyHandler() {
262 void IntPercentageToDoublePolicyHandler::ApplyPolicySettings(
263 const PolicyMap& policies,
264 PrefValueMap* prefs) {
267 const base::Value* value = policies.GetValue(policy_name());
269 if (value && EnsureInRange(value, &percentage, NULL)) {
270 prefs->SetValue(pref_path_, base::Value::CreateDoubleValue(
271 static_cast<double>(percentage) / 100.));
276 // SimplePolicyHandler implementation ------------------------------------------
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) {
286 SimplePolicyHandler::~SimplePolicyHandler() {
289 void SimplePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
290 PrefValueMap* prefs) {
293 const base::Value* value = policies.GetValue(policy_name());
295 prefs->SetValue(pref_path_, value->DeepCopy());
299 // SchemaValidatingPolicyHandler implementation --------------------------------
301 SchemaValidatingPolicyHandler::SchemaValidatingPolicyHandler(
302 const char* policy_name,
304 SchemaOnErrorStrategy strategy)
305 : policy_name_(policy_name), schema_(schema), strategy_(strategy) {
306 DCHECK(schema_.valid());
309 SchemaValidatingPolicyHandler::~SchemaValidatingPolicyHandler() {
312 const char* SchemaValidatingPolicyHandler::policy_name() const {
316 bool SchemaValidatingPolicyHandler::CheckPolicySettings(
317 const PolicyMap& policies,
318 PolicyErrorMap* errors) {
319 const base::Value* value = policies.GetValue(policy_name());
323 std::string error_path;
325 bool result = schema_.Validate(*value, strategy_, &error_path, &error);
327 if (errors && !error.empty()) {
328 if (error_path.empty())
329 error_path = "(ROOT)";
330 errors->AddError(policy_name_, error_path, error);
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());
344 output->reset(value->DeepCopy());
345 std::string error_path;
348 schema_.Normalize(output->get(), strategy_, &error_path, &error);
350 if (errors && !error.empty()) {
351 if (error_path.empty())
352 error_path = "(ROOT)";
353 errors->AddError(policy_name_, error_path, error);
359 } // namespace policy