Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: chrome/browser/extensions/extension_management.cc

Issue 559603002: Add new ExtensionManagement preference (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixes addressing #2 Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_management.h" 5 #include "chrome/browser/extensions/extension_management.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
11 #include "base/strings/string_util.h"
12 #include "chrome/browser/extensions/extension_management_constants.h"
11 #include "chrome/browser/extensions/external_policy_loader.h" 13 #include "chrome/browser/extensions/external_policy_loader.h"
12 #include "chrome/browser/extensions/external_provider_impl.h" 14 #include "chrome/browser/extensions/external_provider_impl.h"
13 #include "chrome/browser/extensions/standard_management_policy_provider.h" 15 #include "chrome/browser/extensions/standard_management_policy_provider.h"
14 #include "chrome/browser/profiles/incognito_helpers.h" 16 #include "chrome/browser/profiles/incognito_helpers.h"
15 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
16 #include "components/crx_file/id_util.h" 18 #include "components/crx_file/id_util.h"
17 #include "components/keyed_service/content/browser_context_dependency_manager.h" 19 #include "components/keyed_service/content/browser_context_dependency_manager.h"
20 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "extensions/browser/pref_names.h" 21 #include "extensions/browser/pref_names.h"
19 #include "extensions/common/url_pattern.h" 22 #include "extensions/common/url_pattern.h"
20 #include "url/gurl.h" 23 #include "url/gurl.h"
21 24
22 namespace extensions { 25 namespace extensions {
23 26
27 namespace {
28
29 enum Scope {
30 // Parses the default settings
Joao da Silva 2014/09/18 15:23:52 Terminate sentence with .
binjin 2014/09/18 15:49:03 Done.
31 SCOPE_DEFAULT = 0,
32 // Parses the settings for an extension with specified extension ID.
33 SCOPE_INDIVIDUAL,
34 };
35
36 // Parse the individual settings for |settings|. |dict| is the a
37 // sub-dictionary in extension management preference and |scope| represents
38 // the applicable range of the settings, a single extension, a group of
39 // extensions or default settings.
40 // Note that in case of parsing errors, |settings| will NOT be left untouched.
41 bool ParseIndividualSettings(
42 const base::DictionaryValue* dict,
43 Scope scope,
44 ExtensionManagement::IndividualSettings* settings) {
45 settings->Reset();
46
47 std::string installation_mode;
48 if (dict->GetStringWithoutPathExpansion(schema_constants::kInstallationMode,
49 &installation_mode)) {
50 if (installation_mode == schema_constants::kAllowed) {
51 settings->installation_mode = ExtensionManagement::INSTALLATION_ALLOWED;
52 } else if (installation_mode == schema_constants::kBlocked) {
53 settings->installation_mode = ExtensionManagement::INSTALLATION_BLOCKED;
54 } else if (installation_mode == schema_constants::kForceInstalled) {
55 settings->installation_mode = ExtensionManagement::INSTALLATION_FORCED;
56 } else if (installation_mode == schema_constants::kNormalInstalled) {
57 settings->installation_mode =
58 ExtensionManagement::INSTALLATION_RECOMMENDED;
59 } else {
60 LOG(WARNING) << "Invalid value for 'installation_mode'.";
61 return false;
62 }
63 }
64
65 if (settings->installation_mode == ExtensionManagement::INSTALLATION_FORCED ||
66 settings->installation_mode ==
67 ExtensionManagement::INSTALLATION_RECOMMENDED) {
68 if (scope != SCOPE_INDIVIDUAL) {
69 LOG(WARNING) << "Only individual extensions are allowed to be "
70 "automatically installed.";
71 return false;
72 }
73 std::string update_url;
74 if (dict->GetStringWithoutPathExpansion(schema_constants::kUpdateUrl,
75 &update_url) &&
76 GURL(update_url).is_valid()) {
77 settings->update_url = update_url;
78 } else {
79 LOG(WARNING) << "No valid update URL for extension.";
80 return false;
81 }
82 }
83
84 return true;
85 }
86
87 } // namespace
88
24 void ExtensionManagement::IndividualSettings::Reset() { 89 void ExtensionManagement::IndividualSettings::Reset() {
25 installation_mode = ExtensionManagement::INSTALLATION_ALLOWED; 90 installation_mode = ExtensionManagement::INSTALLATION_ALLOWED;
26 update_url.clear(); 91 update_url.clear();
27 } 92 }
28 93
29 ExtensionManagement::GlobalSettings::GlobalSettings() { 94 ExtensionManagement::GlobalSettings::GlobalSettings() {
30 Reset(); 95 Reset();
31 } 96 }
32 97
33 ExtensionManagement::GlobalSettings::~GlobalSettings() { 98 ExtensionManagement::GlobalSettings::~GlobalSettings() {
(...skipping 13 matching lines...) Expand all
47 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this)); 112 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this));
48 pref_change_registrar_.Add(pref_names::kInstallAllowList, 113 pref_change_registrar_.Add(pref_names::kInstallAllowList,
49 pref_change_callback); 114 pref_change_callback);
50 pref_change_registrar_.Add(pref_names::kInstallDenyList, 115 pref_change_registrar_.Add(pref_names::kInstallDenyList,
51 pref_change_callback); 116 pref_change_callback);
52 pref_change_registrar_.Add(pref_names::kInstallForceList, 117 pref_change_registrar_.Add(pref_names::kInstallForceList,
53 pref_change_callback); 118 pref_change_callback);
54 pref_change_registrar_.Add(pref_names::kAllowedInstallSites, 119 pref_change_registrar_.Add(pref_names::kAllowedInstallSites,
55 pref_change_callback); 120 pref_change_callback);
56 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); 121 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback);
122 pref_change_registrar_.Add(pref_names::kExtensionManagement,
123 pref_change_callback);
57 Refresh(); 124 Refresh();
58 provider_.reset(new StandardManagementPolicyProvider(this)); 125 provider_.reset(new StandardManagementPolicyProvider(this));
59 } 126 }
60 127
61 ExtensionManagement::~ExtensionManagement() { 128 ExtensionManagement::~ExtensionManagement() {
62 } 129 }
63 130
64 void ExtensionManagement::AddObserver(Observer* observer) { 131 void ExtensionManagement::AddObserver(Observer* observer) {
65 observer_list_.AddObserver(observer); 132 observer_list_.AddObserver(observer);
66 } 133 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 pref_names::kInstallDenyList, false, base::Value::TYPE_LIST)); 205 pref_names::kInstallDenyList, false, base::Value::TYPE_LIST));
139 const base::DictionaryValue* forced_list_pref = 206 const base::DictionaryValue* forced_list_pref =
140 static_cast<const base::DictionaryValue*>(LoadPreference( 207 static_cast<const base::DictionaryValue*>(LoadPreference(
141 pref_names::kInstallForceList, true, base::Value::TYPE_DICTIONARY)); 208 pref_names::kInstallForceList, true, base::Value::TYPE_DICTIONARY));
142 const base::ListValue* install_sources_pref = 209 const base::ListValue* install_sources_pref =
143 static_cast<const base::ListValue*>(LoadPreference( 210 static_cast<const base::ListValue*>(LoadPreference(
144 pref_names::kAllowedInstallSites, true, base::Value::TYPE_LIST)); 211 pref_names::kAllowedInstallSites, true, base::Value::TYPE_LIST));
145 const base::ListValue* allowed_types_pref = 212 const base::ListValue* allowed_types_pref =
146 static_cast<const base::ListValue*>(LoadPreference( 213 static_cast<const base::ListValue*>(LoadPreference(
147 pref_names::kAllowedTypes, true, base::Value::TYPE_LIST)); 214 pref_names::kAllowedTypes, true, base::Value::TYPE_LIST));
215 const base::DictionaryValue* dict_pref =
216 static_cast<const base::DictionaryValue*>(
217 LoadPreference(pref_names::kExtensionManagement,
218 true,
219 base::Value::TYPE_DICTIONARY));
148 220
149 // Reset all settings. 221 // Reset all settings.
150 global_settings_.Reset(); 222 global_settings_.Reset();
151 settings_by_id_.clear(); 223 settings_by_id_.clear();
152 default_settings_.Reset(); 224 default_settings_.Reset();
153 225
154 // Parse default settings. 226 // Parse default settings.
155 const base::StringValue wildcard("*"); 227 const base::StringValue wildcard("*");
156 if (denied_list_pref && 228 if (denied_list_pref &&
157 denied_list_pref->Find(wildcard) != denied_list_pref->end()) { 229 denied_list_pref->Find(wildcard) != denied_list_pref->end()) {
158 default_settings_.installation_mode = INSTALLATION_BLOCKED; 230 default_settings_.installation_mode = INSTALLATION_BLOCKED;
159 } 231 }
160 232
233 const base::DictionaryValue* subdict = NULL;
234 if (dict_pref &&
235 dict_pref->GetDictionary(schema_constants::kWildcard, &subdict)) {
236 if (!ParseIndividualSettings(subdict, SCOPE_DEFAULT, &default_settings_)) {
237 LOG(WARNING) << "Default extension management settings parsing error.";
238 default_settings_.Reset();
239 }
240
241 // Settings from new preference have higher priority over legacy ones.
242 const base::ListValue* list_value = NULL;
243 if (subdict->GetList(schema_constants::kInstallSources, &list_value))
244 install_sources_pref = list_value;
245 if (subdict->GetList(schema_constants::kAllowedTypes, &list_value))
246 allowed_types_pref = list_value;
247 }
248
161 // Parse legacy preferences. 249 // Parse legacy preferences.
162 ExtensionId id; 250 ExtensionId id;
163 251
164 if (allowed_list_pref) { 252 if (allowed_list_pref) {
165 for (base::ListValue::const_iterator it = allowed_list_pref->begin(); 253 for (base::ListValue::const_iterator it = allowed_list_pref->begin();
166 it != allowed_list_pref->end(); ++it) { 254 it != allowed_list_pref->end(); ++it) {
167 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id)) 255 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id))
168 AccessById(id)->installation_mode = INSTALLATION_ALLOWED; 256 AccessById(id)->installation_mode = INSTALLATION_ALLOWED;
169 } 257 }
170 } 258 }
(...skipping 18 matching lines...) Expand all
189 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) { 277 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) {
190 IndividualSettings* by_id = AccessById(it.key()); 278 IndividualSettings* by_id = AccessById(it.key());
191 by_id->installation_mode = INSTALLATION_FORCED; 279 by_id->installation_mode = INSTALLATION_FORCED;
192 by_id->update_url = update_url; 280 by_id->update_url = update_url;
193 } 281 }
194 } 282 }
195 } 283 }
196 284
197 if (install_sources_pref) { 285 if (install_sources_pref) {
198 global_settings_.has_restricted_install_sources = true; 286 global_settings_.has_restricted_install_sources = true;
199 std::string url_pattern;
200 for (base::ListValue::const_iterator it = install_sources_pref->begin(); 287 for (base::ListValue::const_iterator it = install_sources_pref->begin();
201 it != install_sources_pref->end(); ++it) { 288 it != install_sources_pref->end(); ++it) {
202 URLPattern entry(URLPattern::SCHEME_ALL); 289 std::string url_pattern;
203 if ((*it)->GetAsString(&url_pattern)) { 290 if ((*it)->GetAsString(&url_pattern)) {
291 URLPattern entry(URLPattern::SCHEME_ALL);
204 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { 292 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) {
205 global_settings_.install_sources.AddPattern(entry); 293 global_settings_.install_sources.AddPattern(entry);
206 } else { 294 } else {
207 LOG(WARNING) << "Invalid URL pattern in for preference " 295 LOG(WARNING) << "Invalid URL pattern in for preference "
208 << pref_names::kAllowedInstallSites << ": " 296 << pref_names::kAllowedInstallSites << ": "
209 << url_pattern << "."; 297 << url_pattern << ".";
210 } 298 }
211 } 299 }
212 } 300 }
213 } 301 }
214 302
215 if (allowed_types_pref) { 303 if (allowed_types_pref) {
216 global_settings_.has_restricted_allowed_types = true; 304 global_settings_.has_restricted_allowed_types = true;
217 for (base::ListValue::const_iterator it = allowed_types_pref->begin(); 305 for (base::ListValue::const_iterator it = allowed_types_pref->begin();
218 it != allowed_types_pref->end(); ++it) { 306 it != allowed_types_pref->end(); ++it) {
219 int int_value; 307 int int_value;
308 std::string string_value;
220 if ((*it)->GetAsInteger(&int_value) && int_value >= 0 && 309 if ((*it)->GetAsInteger(&int_value) && int_value >= 0 &&
221 int_value < Manifest::Type::NUM_LOAD_TYPES) { 310 int_value < Manifest::Type::NUM_LOAD_TYPES) {
222 global_settings_.allowed_types.push_back( 311 global_settings_.allowed_types.push_back(
223 static_cast<Manifest::Type>(int_value)); 312 static_cast<Manifest::Type>(int_value));
313 } else if ((*it)->GetAsString(&string_value)) {
314 Manifest::Type manifest_type =
315 schema_constants::GetManifestType(string_value);
316 if (manifest_type != Manifest::TYPE_UNKNOWN)
317 global_settings_.allowed_types.push_back(manifest_type);
224 } 318 }
225 } 319 }
226 } 320 }
227 321
228 // TODO(binjin): Add parsing of new ExtensionManagement preference after the 322 if (dict_pref) {
229 // new ExtensionManagement policy is added. 323 // Parse new extension management preference.
324 for (base::DictionaryValue::Iterator iter(*dict_pref); !iter.IsAtEnd();
325 iter.Advance()) {
326 if (iter.key() == schema_constants::kWildcard)
327 continue;
328 if (!iter.value().GetAsDictionary(&subdict)) {
329 LOG(WARNING) << "Malformed extension management preference.";
330 continue;
331 }
332 if (StartsWithASCII(
333 iter.key(), schema_constants::kUpdateUrlPrefix, true)) {
334 continue;
335 }
336 const std::string& extension_id = iter.key();
337 if (!crx_file::id_util::IdIsValid(extension_id)) {
338 LOG(WARNING) << "Malformed extension management preference.";
339 continue;
340 }
341 IndividualSettings by_id;
342 if (!ParseIndividualSettings(subdict, SCOPE_INDIVIDUAL, &by_id)) {
343 LOG(WARNING) << "Malformed extension management preference.";
344 continue;
345 } else {
346 *AccessById(extension_id) = by_id;
347 }
348 }
349 }
230 } 350 }
231 351
232 const base::Value* ExtensionManagement::LoadPreference( 352 const base::Value* ExtensionManagement::LoadPreference(
233 const char* pref_name, 353 const char* pref_name,
234 bool force_managed, 354 bool force_managed,
235 base::Value::Type expected_type) { 355 base::Value::Type expected_type) {
236 const PrefService::Preference* pref = 356 const PrefService::Preference* pref =
237 pref_service_->FindPreference(pref_name); 357 pref_service_->FindPreference(pref_name);
238 if (pref && !pref->IsDefaultValue() && 358 if (pref && !pref->IsDefaultValue() &&
239 (!force_managed || pref->IsManaged())) { 359 (!force_managed || pref->IsManaged())) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 content::BrowserContext* context) const { 406 content::BrowserContext* context) const {
287 return new ExtensionManagement( 407 return new ExtensionManagement(
288 Profile::FromBrowserContext(context)->GetPrefs()); 408 Profile::FromBrowserContext(context)->GetPrefs());
289 } 409 }
290 410
291 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( 411 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse(
292 content::BrowserContext* context) const { 412 content::BrowserContext* context) const {
293 return chrome::GetBrowserContextRedirectedInIncognito(context); 413 return chrome::GetBrowserContextRedirectedInIncognito(context);
294 } 414 }
295 415
416 void ExtensionManagementFactory::RegisterProfilePrefs(
417 user_prefs::PrefRegistrySyncable* user_prefs) {
418 user_prefs->RegisterDictionaryPref(
419 pref_names::kExtensionManagement,
420 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
421 }
422
296 } // namespace extensions 423 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698