policy_handlers.cc revision f2477e01787aa58f445919b809d89e252beef54f
18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file.
48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/extensions/policy_handlers.h"
68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/logging.h"
88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/prefs/pref_value_map.h"
98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/extensions/external_policy_loader.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/policy/policy_error_map.h"
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/common/pref_names.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "grit/component_strings.h"
158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "policy/policy_constants.h"
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace extensions {
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ExtensionListPolicyHandler implementation -----------------------------------
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ExtensionListPolicyHandler::ExtensionListPolicyHandler(const char* policy_name,
228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                       const char* pref_path,
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                       bool allow_wildcards)
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      pref_path_(pref_path),
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      allow_wildcards_(allow_wildcards) {}
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ExtensionListPolicyHandler::~ExtensionListPolicyHandler() {}
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ExtensionListPolicyHandler::CheckPolicySettings(
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const policy::PolicyMap& policies,
328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    policy::PolicyErrorMap* errors) {
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return CheckAndGetList(policies, errors, NULL);
348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ExtensionListPolicyHandler::ApplyPolicySettings(
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const policy::PolicyMap& policies,
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    PrefValueMap* prefs) {
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<base::ListValue> list;
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  policy::PolicyErrorMap errors;
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (CheckAndGetList(policies, &errors, &list) && list)
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    prefs->SetValue(pref_path(), list.release());
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char* ExtensionListPolicyHandler::pref_path() const {
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return pref_path_;
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ExtensionListPolicyHandler::CheckAndGetList(
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const policy::PolicyMap& policies,
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    policy::PolicyErrorMap* errors,
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_ptr<base::ListValue>* extension_ids) {
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (extension_ids)
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    extension_ids->reset();
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::Value* value = NULL;
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!CheckAndGetValue(policies, errors, &value))
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!value)
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;
628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::ListValue* list_value = NULL;
648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!value->GetAsList(&list_value)) {
658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    NOTREACHED();
668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Filter the list, rejecting any invalid extension IDs.
708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<base::ListValue> filtered_list(new base::ListValue());
718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (base::ListValue::const_iterator entry(list_value->begin());
728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       entry != list_value->end(); ++entry) {
738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string id;
748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!(*entry)->GetAsString(&id)) {
758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      errors->AddError(policy_name(),
768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       entry - list_value->begin(),
778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       IDS_POLICY_TYPE_ERROR,
788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       ValueTypeToString(base::Value::TYPE_STRING));
798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!(allow_wildcards_ && id == "*") &&
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        !extensions::Extension::IdIsValid(id)) {
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      errors->AddError(policy_name(),
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       entry - list_value->begin(),
858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       IDS_POLICY_VALUE_FORMAT_ERROR);
868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    filtered_list->Append(base::Value::CreateStringValue(id));
898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (extension_ids)
928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    *extension_ids = filtered_list.Pass();
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ExtensionInstallForcelistPolicyHandler implementation -----------------------
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ExtensionInstallForcelistPolicyHandler::ExtensionInstallForcelistPolicyHandler()
1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : policy::TypeCheckingPolicyHandler(policy::key::kExtensionInstallForcelist,
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                        base::Value::TYPE_LIST) {}
1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ExtensionInstallForcelistPolicyHandler::
1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ~ExtensionInstallForcelistPolicyHandler() {}
1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ExtensionInstallForcelistPolicyHandler::CheckPolicySettings(
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const policy::PolicyMap& policies,
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    policy::PolicyErrorMap* errors) {
1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::Value* value;
1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return CheckAndGetValue(policies, errors, &value) &&
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ParseList(value, NULL, errors);
1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ExtensionInstallForcelistPolicyHandler::ApplyPolicySettings(
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const policy::PolicyMap& policies,
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    PrefValueMap* prefs) {
1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::Value* value = NULL;
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (CheckAndGetValue(policies, NULL, &value) &&
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      value &&
1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ParseList(value, dict.get(), NULL)) {
1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    prefs->SetValue(prefs::kExtensionInstallForceList, dict.release());
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ExtensionInstallForcelistPolicyHandler::ParseList(
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::Value* policy_value,
1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::DictionaryValue* extension_dict,
1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    policy::PolicyErrorMap* errors) {
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!policy_value)
1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;
1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::ListValue* policy_list_value = NULL;
1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!policy_value->GetAsList(&policy_list_value)) {
1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // This should have been caught in CheckPolicySettings.
1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    NOTREACHED();
1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (base::ListValue::const_iterator entry(policy_list_value->begin());
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       entry != policy_list_value->end(); ++entry) {
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string entry_string;
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!(*entry)->GetAsString(&entry_string)) {
1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (errors) {
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        errors->AddError(policy_name(),
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                         entry - policy_list_value->begin(),
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                         IDS_POLICY_TYPE_ERROR,
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                         ValueTypeToString(base::Value::TYPE_STRING));
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Each string item of the list has the following form:
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // <extension_id>;<update_url>
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Note: The update URL might also contain semicolons.
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    size_t pos = entry_string.find(';');
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (pos == std::string::npos) {
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (errors) {
1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        errors->AddError(policy_name(),
1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                         entry - policy_list_value->begin(),
1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                         IDS_POLICY_VALUE_FORMAT_ERROR);
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string extension_id = entry_string.substr(0, pos);
1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string update_url = entry_string.substr(pos+1);
1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!extensions::Extension::IdIsValid(extension_id) ||
1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        !GURL(update_url).is_valid()) {
1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (errors) {
1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        errors->AddError(policy_name(),
1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                         entry - policy_list_value->begin(),
1738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                         IDS_POLICY_VALUE_FORMAT_ERROR);
1748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
1778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (extension_dict) {
1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      extensions::ExternalPolicyLoader::AddExtension(
1808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          extension_dict, extension_id, update_url);
1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ExtensionURLPatternListPolicyHandler implementation -------------------------
1888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ExtensionURLPatternListPolicyHandler::ExtensionURLPatternListPolicyHandler(
1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const char* policy_name,
1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const char* pref_path)
1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      pref_path_(pref_path) {}
1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ExtensionURLPatternListPolicyHandler::~ExtensionURLPatternListPolicyHandler() {}
1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool ExtensionURLPatternListPolicyHandler::CheckPolicySettings(
1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const policy::PolicyMap& policies,
1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    policy::PolicyErrorMap* errors) {
2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::Value* value = NULL;
2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!CheckAndGetValue(policies, errors, &value))
2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!value)
2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;
2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::ListValue* list_value = NULL;
2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!value->GetAsList(&list_value)) {
2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    NOTREACHED();
2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Check that the list contains valid URLPattern strings only.
2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (base::ListValue::const_iterator entry(list_value->begin());
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       entry != list_value->end(); ++entry) {
2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string url_pattern_string;
2178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!(*entry)->GetAsString(&url_pattern_string)) {
2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      errors->AddError(policy_name(),
2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       entry - list_value->begin(),
2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       IDS_POLICY_TYPE_ERROR,
2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       ValueTypeToString(base::Value::TYPE_STRING));
2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return false;
2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
2248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    URLPattern pattern(URLPattern::SCHEME_ALL);
2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (pattern.Parse(url_pattern_string) != URLPattern::PARSE_SUCCESS) {
2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      errors->AddError(policy_name(),
2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       entry - list_value->begin(),
2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                       IDS_POLICY_VALUE_FORMAT_ERROR);
2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return false;
2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ExtensionURLPatternListPolicyHandler::ApplyPolicySettings(
2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const policy::PolicyMap& policies,
2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    PrefValueMap* prefs) {
2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!pref_path_)
2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const Value* value = policies.GetValue(policy_name());
2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (value)
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    prefs->SetValue(pref_path_, value->DeepCopy());
2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace extensions
248