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