15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/browser/configuration_policy_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/callback.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/prefs/pref_value_map.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/browser/policy_error_map.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "grit/components_strings.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ConfigurationPolicyHandler implementation -----------------------------------
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
259ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// static
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ConfigurationPolicyHandler::ValueTypeToString(
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::Value::Type type) {
289ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  static const char* strings[] = {
299ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    "null",
309ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    "boolean",
319ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    "integer",
329ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    "double",
339ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    "string",
349ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    "binary",
359ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    "dictionary",
369ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    "list"
379ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  };
389ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  CHECK(static_cast<size_t>(type) < arraysize(strings));
399ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  return std::string(strings[type]);
409ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConfigurationPolicyHandler::ConfigurationPolicyHandler() {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConfigurationPolicyHandler::~ConfigurationPolicyHandler() {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConfigurationPolicyHandler::PrepareForDisplaying(
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PolicyMap* policies) const {}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ConfigurationPolicyHandler::ApplyPolicySettings(
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const policy::PolicyMap& policies,
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PrefValueMap* prefs) {
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NOTREACHED();
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ConfigurationPolicyHandler::ApplyPolicySettingsWithParameters(
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const PolicyMap& policies,
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const PolicyHandlerParameters& parameters,
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PrefValueMap* prefs) {
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ApplyPolicySettings(policies, prefs);
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TypeCheckingPolicyHandler implementation ------------------------------------
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TypeCheckingPolicyHandler::TypeCheckingPolicyHandler(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* policy_name,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::Value::Type value_type)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : policy_name_(policy_name),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      value_type_(value_type) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TypeCheckingPolicyHandler::~TypeCheckingPolicyHandler() {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* TypeCheckingPolicyHandler::policy_name() const {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return policy_name_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TypeCheckingPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    PolicyErrorMap* errors) {
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Value* value = NULL;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckAndGetValue(policies, errors, &value);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TypeCheckingPolicyHandler::CheckAndGetValue(const PolicyMap& policies,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 PolicyErrorMap* errors,
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                 const base::Value** value) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *value = policies.GetValue(policy_name_);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*value && !(*value)->IsType(value_type_)) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors->AddError(policy_name_,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     IDS_POLICY_TYPE_ERROR,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ValueTypeToString(value_type_));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// IntRangePolicyHandlerBase implementation ------------------------------------
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IntRangePolicyHandlerBase::IntRangePolicyHandlerBase(
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* policy_name,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int min,
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int max,
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool clamp)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_INTEGER),
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      min_(min),
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_(max),
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      clamp_(clamp) {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IntRangePolicyHandlerBase::CheckPolicySettings(const PolicyMap& policies,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                    PolicyErrorMap* errors) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Value* value;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CheckAndGetValue(policies, errors, &value) &&
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EnsureInRange(value, NULL, errors);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IntRangePolicyHandlerBase::~IntRangePolicyHandlerBase() {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IntRangePolicyHandlerBase::EnsureInRange(const base::Value* input,
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              int* output,
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              PolicyErrorMap* errors) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!input)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int value;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!input->GetAsInteger(&value)) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value < min_ || value > max_) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (errors) {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      errors->AddError(policy_name(),
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       IDS_POLICY_OUT_OF_RANGE_ERROR,
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       base::IntToString(value));
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!clamp_)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    value = std::min(std::max(value, min_), max_);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (output)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *output = value;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// StringMappingListPolicyHandler implementation -----------------------------
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)StringMappingListPolicyHandler::MappingEntry::MappingEntry(
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const char* policy_value, scoped_ptr<base::Value> map)
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : enum_value(policy_value), mapped_value(map.Pass()) {}
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)StringMappingListPolicyHandler::MappingEntry::~MappingEntry() {}
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)StringMappingListPolicyHandler::StringMappingListPolicyHandler(
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* policy_name,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* pref_path,
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const GenerateMapCallback& callback)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_path_(pref_path),
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      map_getter_(callback) {}
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)StringMappingListPolicyHandler::~StringMappingListPolicyHandler() {}
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool StringMappingListPolicyHandler::CheckPolicySettings(
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PolicyMap& policies,
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PolicyErrorMap* errors) {
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Value* value;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CheckAndGetValue(policies, errors, &value) &&
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Convert(value, NULL, errors);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void StringMappingListPolicyHandler::ApplyPolicySettings(
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PolicyMap& policies,
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PrefValueMap* prefs) {
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!pref_path_)
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Value* value = policies.GetValue(policy_name());
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::ListValue> list(new base::ListValue());
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value && Convert(value, list.get(), NULL))
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    prefs->SetValue(pref_path_, list.release());
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool StringMappingListPolicyHandler::Convert(const base::Value* input,
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             base::ListValue* output,
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             PolicyErrorMap* errors) {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!input)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::ListValue* list_value = NULL;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!input->GetAsList(&list_value)) {
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::ListValue::const_iterator entry(list_value->begin());
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       entry != list_value->end(); ++entry) {
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string entry_value;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!(*entry)->GetAsString(&entry_value)) {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (errors) {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        errors->AddError(policy_name(),
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         entry - list_value->begin(),
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         IDS_POLICY_TYPE_ERROR,
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ValueTypeToString(base::Value::TYPE_STRING));
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_ptr<base::Value> mapped_value = Map(entry_value);
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (mapped_value) {
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (output)
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        output->Append(mapped_value.release());
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    } else {
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (errors) {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        errors->AddError(policy_name(),
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         entry - list_value->begin(),
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         IDS_POLICY_OUT_OF_RANGE_ERROR);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_ptr<base::Value> StringMappingListPolicyHandler::Map(
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const std::string& entry_value) {
234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Lazily generate the map of policy strings to mapped values.
235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (map_.empty())
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    map_getter_.Run(&map_);
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<base::Value> return_value;
239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (ScopedVector<MappingEntry>::const_iterator it = map_.begin();
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)       it != map_.end(); ++it) {
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const MappingEntry* mapping_entry = *it;
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (mapping_entry->enum_value == entry_value) {
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return_value = make_scoped_ptr(mapping_entry->mapped_value->DeepCopy());
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return return_value.Pass();
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// IntRangePolicyHandler implementation ----------------------------------------
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IntRangePolicyHandler::IntRangePolicyHandler(const char* policy_name,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             const char* pref_path,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             int min,
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             int max,
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             bool clamp)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_path_(pref_path) {
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IntRangePolicyHandler::~IntRangePolicyHandler() {
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IntRangePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                PrefValueMap* prefs) {
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!pref_path_)
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Value* value = policies.GetValue(policy_name());
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int value_in_range;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value && EnsureInRange(value, &value_in_range, NULL)) {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    prefs->SetValue(pref_path_,
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                    new base::FundamentalValue(value_in_range));
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// IntPercentageToDoublePolicyHandler implementation ---------------------------
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IntPercentageToDoublePolicyHandler::IntPercentageToDoublePolicyHandler(
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* policy_name,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* pref_path,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int min,
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int max,
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool clamp)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : IntRangePolicyHandlerBase(policy_name, min, max, clamp),
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_path_(pref_path) {
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IntPercentageToDoublePolicyHandler::~IntPercentageToDoublePolicyHandler() {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IntPercentageToDoublePolicyHandler::ApplyPolicySettings(
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PolicyMap& policies,
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PrefValueMap* prefs) {
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!pref_path_)
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Value* value = policies.GetValue(policy_name());
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int percentage;
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value && EnsureInRange(value, &percentage, NULL)) {
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    prefs->SetValue(pref_path_, base::Value::CreateDoubleValue(
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        static_cast<double>(percentage) / 100.));
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SimplePolicyHandler implementation ------------------------------------------
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SimplePolicyHandler::SimplePolicyHandler(
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* policy_name,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* pref_path,
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::Value::Type value_type)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : TypeCheckingPolicyHandler(policy_name, value_type),
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pref_path_(pref_path) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SimplePolicyHandler::~SimplePolicyHandler() {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SimplePolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              PrefValueMap* prefs) {
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!pref_path_)
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Value* value = policies.GetValue(policy_name());
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs->SetValue(pref_path_, value->DeepCopy());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// SchemaValidatingPolicyHandler implementation --------------------------------
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SchemaValidatingPolicyHandler::SchemaValidatingPolicyHandler(
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* policy_name,
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Schema schema,
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SchemaOnErrorStrategy strategy)
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : policy_name_(policy_name), schema_(schema), strategy_(strategy) {
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(schema_.valid());
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SchemaValidatingPolicyHandler::~SchemaValidatingPolicyHandler() {
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char* SchemaValidatingPolicyHandler::policy_name() const {
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return policy_name_;
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SchemaValidatingPolicyHandler::CheckPolicySettings(
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const PolicyMap& policies,
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PolicyErrorMap* errors) {
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Value* value = policies.GetValue(policy_name());
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!value)
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string error_path;
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string error;
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool result = schema_.Validate(*value, strategy_, &error_path, &error);
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (errors && !error.empty()) {
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (error_path.empty())
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      error_path = "(ROOT)";
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    errors->AddError(policy_name_, error_path, error);
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SchemaValidatingPolicyHandler::CheckAndGetValue(
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const PolicyMap& policies,
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PolicyErrorMap* errors,
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<base::Value>* output) {
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Value* value = policies.GetValue(policy_name());
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!value)
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  output->reset(value->DeepCopy());
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string error_path;
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string error;
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool result =
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      schema_.Normalize(output->get(), strategy_, &error_path, &error, NULL);
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (errors && !error.empty()) {
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (error_path.empty())
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      error_path = "(ROOT)";
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    errors->AddError(policy_name_, error_path, error);
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// SimpleSchemaValidatingPolicyHandler implementation --------------------------
390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SimpleSchemaValidatingPolicyHandler::SimpleSchemaValidatingPolicyHandler(
392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const char* policy_name,
393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const char* pref_path,
394f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    Schema schema,
395f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SchemaOnErrorStrategy strategy,
396f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    RecommendedPermission recommended_permission,
397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    MandatoryPermission mandatory_permission)
398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : SchemaValidatingPolicyHandler(policy_name,
399f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    schema.GetKnownProperty(policy_name),
400f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    strategy),
401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pref_path_(pref_path),
402f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      allow_recommended_(recommended_permission == RECOMMENDED_ALLOWED),
403f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      allow_mandatory_(mandatory_permission == MANDATORY_ALLOWED) {
404f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
406f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SimpleSchemaValidatingPolicyHandler::~SimpleSchemaValidatingPolicyHandler() {
407f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
408f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
409f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SimpleSchemaValidatingPolicyHandler::CheckPolicySettings(
410f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const PolicyMap& policies,
411f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PolicyErrorMap* errors) {
412f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const PolicyMap::Entry* policy_entry = policies.Get(policy_name());
413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!policy_entry)
414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return true;
415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if ((policy_entry->level == policy::POLICY_LEVEL_MANDATORY &&
416f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)       !allow_mandatory_) ||
417f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      (policy_entry->level == policy::POLICY_LEVEL_RECOMMENDED &&
418f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)       !allow_recommended_)) {
419f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (errors)
420f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      errors->AddError(policy_name(), IDS_POLICY_LEVEL_ERROR);
421f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return false;
422f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
423f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
424f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return SchemaValidatingPolicyHandler::CheckPolicySettings(policies, errors);
425f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
426f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
427f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SimpleSchemaValidatingPolicyHandler::ApplyPolicySettings(
428f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const PolicyMap& policies,
429f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PrefValueMap* prefs) {
430f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!pref_path_)
431f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
432f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const base::Value* value = policies.GetValue(policy_name());
433f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (value)
434f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    prefs->SetValue(pref_path_, value->DeepCopy());
435f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
436f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// LegacyPoliciesDeprecatingPolicyHandler implementation -----------------------
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// TODO(binjin): Add a new common base class for SchemaValidatingPolicyHandler
440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// and TypeCheckingPolicyHandler representing policy handlers for a single
441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// policy, and use it as the type of |new_policy_handler|.
442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// http://crbug.com/345299
443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)LegacyPoliciesDeprecatingPolicyHandler::LegacyPoliciesDeprecatingPolicyHandler(
444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScopedVector<ConfigurationPolicyHandler> legacy_policy_handlers,
445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<SchemaValidatingPolicyHandler> new_policy_handler)
446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : legacy_policy_handlers_(legacy_policy_handlers.Pass()),
447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new_policy_handler_(new_policy_handler.Pass()) {
448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)LegacyPoliciesDeprecatingPolicyHandler::
451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ~LegacyPoliciesDeprecatingPolicyHandler() {
452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool LegacyPoliciesDeprecatingPolicyHandler::CheckPolicySettings(
455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const PolicyMap& policies,
456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PolicyErrorMap* errors) {
457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (policies.Get(new_policy_handler_->policy_name())) {
458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return new_policy_handler_->CheckPolicySettings(policies, errors);
459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // The new policy is not set, fall back to legacy ones.
461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScopedVector<ConfigurationPolicyHandler>::iterator handler;
462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool valid_policy_found = false;
463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (handler = legacy_policy_handlers_.begin();
464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         handler != legacy_policy_handlers_.end();
465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         ++handler) {
466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if ((*handler)->CheckPolicySettings(policies, errors))
467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        valid_policy_found = true;
468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return valid_policy_found;
470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void LegacyPoliciesDeprecatingPolicyHandler::ApplyPolicySettings(
474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const PolicyMap& policies,
475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PrefValueMap* prefs) {
476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (policies.Get(new_policy_handler_->policy_name())) {
477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    new_policy_handler_->ApplyPolicySettings(policies, prefs);
478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // The new policy is not set, fall back to legacy ones.
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PolicyErrorMap scoped_errors;
481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScopedVector<ConfigurationPolicyHandler>::iterator handler;
482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (handler = legacy_policy_handlers_.begin();
483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         handler != legacy_policy_handlers_.end();
484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         ++handler) {
485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if ((*handler)->CheckPolicySettings(policies, &scoped_errors))
486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        (*handler)->ApplyPolicySettings(policies, prefs);
487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace policy
492