policy_handlers.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/extensions/policy_handlers.h" 6 7#include "base/logging.h" 8#include "base/prefs/pref_value_map.h" 9#include "chrome/browser/extensions/external_policy_loader.h" 10#include "chrome/common/pref_names.h" 11#include "components/policy/core/browser/policy_error_map.h" 12#include "components/policy/core/common/policy_map.h" 13#include "extensions/common/extension.h" 14#include "grit/component_strings.h" 15#include "policy/policy_constants.h" 16 17namespace extensions { 18 19// ExtensionListPolicyHandler implementation ----------------------------------- 20 21ExtensionListPolicyHandler::ExtensionListPolicyHandler(const char* policy_name, 22 const char* pref_path, 23 bool allow_wildcards) 24 : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST), 25 pref_path_(pref_path), 26 allow_wildcards_(allow_wildcards) {} 27 28ExtensionListPolicyHandler::~ExtensionListPolicyHandler() {} 29 30bool ExtensionListPolicyHandler::CheckPolicySettings( 31 const policy::PolicyMap& policies, 32 policy::PolicyErrorMap* errors) { 33 return CheckAndGetList(policies, errors, NULL); 34} 35 36void ExtensionListPolicyHandler::ApplyPolicySettings( 37 const policy::PolicyMap& policies, 38 PrefValueMap* prefs) { 39 scoped_ptr<base::ListValue> list; 40 policy::PolicyErrorMap errors; 41 if (CheckAndGetList(policies, &errors, &list) && list) 42 prefs->SetValue(pref_path(), list.release()); 43} 44 45const char* ExtensionListPolicyHandler::pref_path() const { 46 return pref_path_; 47} 48 49bool ExtensionListPolicyHandler::CheckAndGetList( 50 const policy::PolicyMap& policies, 51 policy::PolicyErrorMap* errors, 52 scoped_ptr<base::ListValue>* extension_ids) { 53 if (extension_ids) 54 extension_ids->reset(); 55 56 const base::Value* value = NULL; 57 if (!CheckAndGetValue(policies, errors, &value)) 58 return false; 59 60 if (!value) 61 return true; 62 63 const base::ListValue* list_value = NULL; 64 if (!value->GetAsList(&list_value)) { 65 NOTREACHED(); 66 return false; 67 } 68 69 // Filter the list, rejecting any invalid extension IDs. 70 scoped_ptr<base::ListValue> filtered_list(new base::ListValue()); 71 for (base::ListValue::const_iterator entry(list_value->begin()); 72 entry != list_value->end(); ++entry) { 73 std::string id; 74 if (!(*entry)->GetAsString(&id)) { 75 errors->AddError(policy_name(), 76 entry - list_value->begin(), 77 IDS_POLICY_TYPE_ERROR, 78 ValueTypeToString(base::Value::TYPE_STRING)); 79 continue; 80 } 81 if (!(allow_wildcards_ && id == "*") && 82 !extensions::Extension::IdIsValid(id)) { 83 errors->AddError(policy_name(), 84 entry - list_value->begin(), 85 IDS_POLICY_VALUE_FORMAT_ERROR); 86 continue; 87 } 88 filtered_list->Append(base::Value::CreateStringValue(id)); 89 } 90 91 if (extension_ids) 92 *extension_ids = filtered_list.Pass(); 93 94 return true; 95} 96 97// ExtensionInstallForcelistPolicyHandler implementation ----------------------- 98 99ExtensionInstallForcelistPolicyHandler::ExtensionInstallForcelistPolicyHandler() 100 : policy::TypeCheckingPolicyHandler(policy::key::kExtensionInstallForcelist, 101 base::Value::TYPE_LIST) {} 102 103ExtensionInstallForcelistPolicyHandler:: 104 ~ExtensionInstallForcelistPolicyHandler() {} 105 106bool ExtensionInstallForcelistPolicyHandler::CheckPolicySettings( 107 const policy::PolicyMap& policies, 108 policy::PolicyErrorMap* errors) { 109 const base::Value* value; 110 return CheckAndGetValue(policies, errors, &value) && 111 ParseList(value, NULL, errors); 112} 113 114void ExtensionInstallForcelistPolicyHandler::ApplyPolicySettings( 115 const policy::PolicyMap& policies, 116 PrefValueMap* prefs) { 117 const base::Value* value = NULL; 118 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 119 if (CheckAndGetValue(policies, NULL, &value) && 120 value && 121 ParseList(value, dict.get(), NULL)) { 122 prefs->SetValue(prefs::kExtensionInstallForceList, dict.release()); 123 } 124} 125 126bool ExtensionInstallForcelistPolicyHandler::ParseList( 127 const base::Value* policy_value, 128 base::DictionaryValue* extension_dict, 129 policy::PolicyErrorMap* errors) { 130 if (!policy_value) 131 return true; 132 133 const base::ListValue* policy_list_value = NULL; 134 if (!policy_value->GetAsList(&policy_list_value)) { 135 // This should have been caught in CheckPolicySettings. 136 NOTREACHED(); 137 return false; 138 } 139 140 for (base::ListValue::const_iterator entry(policy_list_value->begin()); 141 entry != policy_list_value->end(); ++entry) { 142 std::string entry_string; 143 if (!(*entry)->GetAsString(&entry_string)) { 144 if (errors) { 145 errors->AddError(policy_name(), 146 entry - policy_list_value->begin(), 147 IDS_POLICY_TYPE_ERROR, 148 ValueTypeToString(base::Value::TYPE_STRING)); 149 } 150 continue; 151 } 152 153 // Each string item of the list has the following form: 154 // <extension_id>;<update_url> 155 // Note: The update URL might also contain semicolons. 156 size_t pos = entry_string.find(';'); 157 if (pos == std::string::npos) { 158 if (errors) { 159 errors->AddError(policy_name(), 160 entry - policy_list_value->begin(), 161 IDS_POLICY_VALUE_FORMAT_ERROR); 162 } 163 continue; 164 } 165 166 std::string extension_id = entry_string.substr(0, pos); 167 std::string update_url = entry_string.substr(pos+1); 168 if (!extensions::Extension::IdIsValid(extension_id) || 169 !GURL(update_url).is_valid()) { 170 if (errors) { 171 errors->AddError(policy_name(), 172 entry - policy_list_value->begin(), 173 IDS_POLICY_VALUE_FORMAT_ERROR); 174 } 175 continue; 176 } 177 178 if (extension_dict) { 179 extensions::ExternalPolicyLoader::AddExtension( 180 extension_dict, extension_id, update_url); 181 } 182 } 183 184 return true; 185} 186 187// ExtensionURLPatternListPolicyHandler implementation ------------------------- 188 189ExtensionURLPatternListPolicyHandler::ExtensionURLPatternListPolicyHandler( 190 const char* policy_name, 191 const char* pref_path) 192 : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST), 193 pref_path_(pref_path) {} 194 195ExtensionURLPatternListPolicyHandler::~ExtensionURLPatternListPolicyHandler() {} 196 197bool ExtensionURLPatternListPolicyHandler::CheckPolicySettings( 198 const policy::PolicyMap& policies, 199 policy::PolicyErrorMap* errors) { 200 const base::Value* value = NULL; 201 if (!CheckAndGetValue(policies, errors, &value)) 202 return false; 203 204 if (!value) 205 return true; 206 207 const base::ListValue* list_value = NULL; 208 if (!value->GetAsList(&list_value)) { 209 NOTREACHED(); 210 return false; 211 } 212 213 // Check that the list contains valid URLPattern strings only. 214 for (base::ListValue::const_iterator entry(list_value->begin()); 215 entry != list_value->end(); ++entry) { 216 std::string url_pattern_string; 217 if (!(*entry)->GetAsString(&url_pattern_string)) { 218 errors->AddError(policy_name(), 219 entry - list_value->begin(), 220 IDS_POLICY_TYPE_ERROR, 221 ValueTypeToString(base::Value::TYPE_STRING)); 222 return false; 223 } 224 225 URLPattern pattern(URLPattern::SCHEME_ALL); 226 if (pattern.Parse(url_pattern_string) != URLPattern::PARSE_SUCCESS) { 227 errors->AddError(policy_name(), 228 entry - list_value->begin(), 229 IDS_POLICY_VALUE_FORMAT_ERROR); 230 return false; 231 } 232 } 233 234 return true; 235} 236 237void ExtensionURLPatternListPolicyHandler::ApplyPolicySettings( 238 const policy::PolicyMap& policies, 239 PrefValueMap* prefs) { 240 if (!pref_path_) 241 return; 242 const Value* value = policies.GetValue(policy_name()); 243 if (value) 244 prefs->SetValue(pref_path_, value->DeepCopy()); 245} 246 247} // namespace extensions 248