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

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 #16 Created 6 years, 2 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 const char kMalformedPreferenceWarning[] =
30 "Malformed extension management preference.";
31
32 enum Scope {
33 // Parses the default settings.
34 SCOPE_DEFAULT = 0,
35 // Parses the settings for an extension with specified extension ID.
36 SCOPE_INDIVIDUAL,
37 };
38
39 // Parse the individual settings for |settings|. |dict| is the a
40 // sub-dictionary in extension management preference and |scope| represents
41 // the applicable range of the settings, a single extension, a group of
42 // extensions or default settings.
43 // Note that in case of parsing errors, |settings| will NOT be left untouched.
44 bool ParseIndividualSettings(
45 const base::DictionaryValue* dict,
46 Scope scope,
47 ExtensionManagement::IndividualSettings* settings) {
48 settings->Reset();
49
50 std::string installation_mode;
51 if (dict->GetStringWithoutPathExpansion(schema_constants::kInstallationMode,
52 &installation_mode)) {
53 if (installation_mode == schema_constants::kAllowed) {
54 settings->installation_mode = ExtensionManagement::INSTALLATION_ALLOWED;
55 } else if (installation_mode == schema_constants::kBlocked) {
56 settings->installation_mode = ExtensionManagement::INSTALLATION_BLOCKED;
57 } else if (installation_mode == schema_constants::kForceInstalled) {
58 settings->installation_mode = ExtensionManagement::INSTALLATION_FORCED;
59 } else if (installation_mode == schema_constants::kNormalInstalled) {
60 settings->installation_mode =
61 ExtensionManagement::INSTALLATION_RECOMMENDED;
62 } else {
63 // Invalid value for 'installation_mode'.
64 LOG(WARNING) << kMalformedPreferenceWarning;
65 return false;
66 }
67 }
68
69 if (settings->installation_mode == ExtensionManagement::INSTALLATION_FORCED ||
70 settings->installation_mode ==
71 ExtensionManagement::INSTALLATION_RECOMMENDED) {
72 if (scope != SCOPE_INDIVIDUAL) {
73 // Only individual extensions are allowed to be automatically installed.
74 LOG(WARNING) << kMalformedPreferenceWarning;
75 return false;
76 }
77 std::string update_url;
78 if (dict->GetStringWithoutPathExpansion(schema_constants::kUpdateUrl,
79 &update_url) &&
80 GURL(update_url).is_valid()) {
81 settings->update_url = update_url;
82 } else {
83 // No valid update URL for extension.
84 LOG(WARNING) << kMalformedPreferenceWarning;
85 return false;
86 }
87 }
88
89 return true;
90 }
91
92 } // namespace
93
24 void ExtensionManagement::IndividualSettings::Reset() { 94 void ExtensionManagement::IndividualSettings::Reset() {
25 installation_mode = ExtensionManagement::INSTALLATION_ALLOWED; 95 installation_mode = ExtensionManagement::INSTALLATION_ALLOWED;
26 update_url.clear(); 96 update_url.clear();
27 } 97 }
28 98
29 ExtensionManagement::GlobalSettings::GlobalSettings() { 99 ExtensionManagement::GlobalSettings::GlobalSettings() {
30 Reset(); 100 Reset();
31 } 101 }
32 102
33 ExtensionManagement::GlobalSettings::~GlobalSettings() { 103 ExtensionManagement::GlobalSettings::~GlobalSettings() {
(...skipping 13 matching lines...) Expand all
47 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this)); 117 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this));
48 pref_change_registrar_.Add(pref_names::kInstallAllowList, 118 pref_change_registrar_.Add(pref_names::kInstallAllowList,
49 pref_change_callback); 119 pref_change_callback);
50 pref_change_registrar_.Add(pref_names::kInstallDenyList, 120 pref_change_registrar_.Add(pref_names::kInstallDenyList,
51 pref_change_callback); 121 pref_change_callback);
52 pref_change_registrar_.Add(pref_names::kInstallForceList, 122 pref_change_registrar_.Add(pref_names::kInstallForceList,
53 pref_change_callback); 123 pref_change_callback);
54 pref_change_registrar_.Add(pref_names::kAllowedInstallSites, 124 pref_change_registrar_.Add(pref_names::kAllowedInstallSites,
55 pref_change_callback); 125 pref_change_callback);
56 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); 126 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback);
127 pref_change_registrar_.Add(pref_names::kExtensionManagement,
128 pref_change_callback);
57 Refresh(); 129 Refresh();
58 provider_.reset(new StandardManagementPolicyProvider(this)); 130 provider_.reset(new StandardManagementPolicyProvider(this));
59 } 131 }
60 132
61 ExtensionManagement::~ExtensionManagement() { 133 ExtensionManagement::~ExtensionManagement() {
62 } 134 }
63 135
64 void ExtensionManagement::AddObserver(Observer* observer) { 136 void ExtensionManagement::AddObserver(Observer* observer) {
65 observer_list_.AddObserver(observer); 137 observer_list_.AddObserver(observer);
66 } 138 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 pref_names::kInstallDenyList, false, base::Value::TYPE_LIST)); 210 pref_names::kInstallDenyList, false, base::Value::TYPE_LIST));
139 const base::DictionaryValue* forced_list_pref = 211 const base::DictionaryValue* forced_list_pref =
140 static_cast<const base::DictionaryValue*>(LoadPreference( 212 static_cast<const base::DictionaryValue*>(LoadPreference(
141 pref_names::kInstallForceList, true, base::Value::TYPE_DICTIONARY)); 213 pref_names::kInstallForceList, true, base::Value::TYPE_DICTIONARY));
142 const base::ListValue* install_sources_pref = 214 const base::ListValue* install_sources_pref =
143 static_cast<const base::ListValue*>(LoadPreference( 215 static_cast<const base::ListValue*>(LoadPreference(
144 pref_names::kAllowedInstallSites, true, base::Value::TYPE_LIST)); 216 pref_names::kAllowedInstallSites, true, base::Value::TYPE_LIST));
145 const base::ListValue* allowed_types_pref = 217 const base::ListValue* allowed_types_pref =
146 static_cast<const base::ListValue*>(LoadPreference( 218 static_cast<const base::ListValue*>(LoadPreference(
147 pref_names::kAllowedTypes, true, base::Value::TYPE_LIST)); 219 pref_names::kAllowedTypes, true, base::Value::TYPE_LIST));
220 const base::DictionaryValue* dict_pref =
221 static_cast<const base::DictionaryValue*>(
222 LoadPreference(pref_names::kExtensionManagement,
223 true,
224 base::Value::TYPE_DICTIONARY));
148 225
149 // Reset all settings. 226 // Reset all settings.
150 global_settings_.Reset(); 227 global_settings_.Reset();
151 settings_by_id_.clear(); 228 settings_by_id_.clear();
152 default_settings_.Reset(); 229 default_settings_.Reset();
153 230
154 // Parse default settings. 231 // Parse default settings.
155 const base::StringValue wildcard("*"); 232 const base::StringValue wildcard("*");
156 if (denied_list_pref && 233 if (denied_list_pref &&
157 denied_list_pref->Find(wildcard) != denied_list_pref->end()) { 234 denied_list_pref->Find(wildcard) != denied_list_pref->end()) {
158 default_settings_.installation_mode = INSTALLATION_BLOCKED; 235 default_settings_.installation_mode = INSTALLATION_BLOCKED;
159 } 236 }
160 237
238 const base::DictionaryValue* subdict = NULL;
239 if (dict_pref &&
240 dict_pref->GetDictionary(schema_constants::kWildcard, &subdict)) {
241 if (!ParseIndividualSettings(subdict, SCOPE_DEFAULT, &default_settings_)) {
242 LOG(WARNING) << "Default extension management settings parsing error.";
243 default_settings_.Reset();
244 }
245
246 // Settings from new preference have higher priority over legacy ones.
247 const base::ListValue* list_value = NULL;
248 if (subdict->GetList(schema_constants::kInstallSources, &list_value))
249 install_sources_pref = list_value;
250 if (subdict->GetList(schema_constants::kAllowedTypes, &list_value))
251 allowed_types_pref = list_value;
252 }
253
161 // Parse legacy preferences. 254 // Parse legacy preferences.
162 ExtensionId id; 255 ExtensionId id;
163 256
164 if (allowed_list_pref) { 257 if (allowed_list_pref) {
165 for (base::ListValue::const_iterator it = allowed_list_pref->begin(); 258 for (base::ListValue::const_iterator it = allowed_list_pref->begin();
166 it != allowed_list_pref->end(); ++it) { 259 it != allowed_list_pref->end(); ++it) {
167 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id)) 260 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id))
168 AccessById(id)->installation_mode = INSTALLATION_ALLOWED; 261 AccessById(id)->installation_mode = INSTALLATION_ALLOWED;
169 } 262 }
170 } 263 }
(...skipping 18 matching lines...) Expand all
189 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) { 282 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) {
190 IndividualSettings* by_id = AccessById(it.key()); 283 IndividualSettings* by_id = AccessById(it.key());
191 by_id->installation_mode = INSTALLATION_FORCED; 284 by_id->installation_mode = INSTALLATION_FORCED;
192 by_id->update_url = update_url; 285 by_id->update_url = update_url;
193 } 286 }
194 } 287 }
195 } 288 }
196 289
197 if (install_sources_pref) { 290 if (install_sources_pref) {
198 global_settings_.has_restricted_install_sources = true; 291 global_settings_.has_restricted_install_sources = true;
199 std::string url_pattern;
200 for (base::ListValue::const_iterator it = install_sources_pref->begin(); 292 for (base::ListValue::const_iterator it = install_sources_pref->begin();
201 it != install_sources_pref->end(); ++it) { 293 it != install_sources_pref->end(); ++it) {
202 URLPattern entry(URLPattern::SCHEME_ALL); 294 std::string url_pattern;
203 if ((*it)->GetAsString(&url_pattern)) { 295 if ((*it)->GetAsString(&url_pattern)) {
296 URLPattern entry(URLPattern::SCHEME_ALL);
204 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { 297 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) {
205 global_settings_.install_sources.AddPattern(entry); 298 global_settings_.install_sources.AddPattern(entry);
206 } else { 299 } else {
207 LOG(WARNING) << "Invalid URL pattern in for preference " 300 LOG(WARNING) << "Invalid URL pattern in for preference "
208 << pref_names::kAllowedInstallSites << ": " 301 << pref_names::kAllowedInstallSites << ": "
209 << url_pattern << "."; 302 << url_pattern << ".";
210 } 303 }
211 } 304 }
212 } 305 }
213 } 306 }
214 307
215 if (allowed_types_pref) { 308 if (allowed_types_pref) {
216 global_settings_.has_restricted_allowed_types = true; 309 global_settings_.has_restricted_allowed_types = true;
217 for (base::ListValue::const_iterator it = allowed_types_pref->begin(); 310 for (base::ListValue::const_iterator it = allowed_types_pref->begin();
218 it != allowed_types_pref->end(); ++it) { 311 it != allowed_types_pref->end(); ++it) {
219 int int_value; 312 int int_value;
313 std::string string_value;
220 if ((*it)->GetAsInteger(&int_value) && int_value >= 0 && 314 if ((*it)->GetAsInteger(&int_value) && int_value >= 0 &&
221 int_value < Manifest::Type::NUM_LOAD_TYPES) { 315 int_value < Manifest::Type::NUM_LOAD_TYPES) {
222 global_settings_.allowed_types.push_back( 316 global_settings_.allowed_types.push_back(
223 static_cast<Manifest::Type>(int_value)); 317 static_cast<Manifest::Type>(int_value));
318 } else if ((*it)->GetAsString(&string_value)) {
319 Manifest::Type manifest_type =
320 schema_constants::GetManifestType(string_value);
321 if (manifest_type != Manifest::TYPE_UNKNOWN)
322 global_settings_.allowed_types.push_back(manifest_type);
224 } 323 }
225 } 324 }
226 } 325 }
227 326
228 // TODO(binjin): Add parsing of new ExtensionManagement preference after the 327 if (dict_pref) {
229 // new ExtensionManagement policy is added. 328 // Parse new extension management preference.
329 for (base::DictionaryValue::Iterator iter(*dict_pref); !iter.IsAtEnd();
330 iter.Advance()) {
331 if (iter.key() == schema_constants::kWildcard)
332 continue;
333 if (!iter.value().GetAsDictionary(&subdict)) {
334 LOG(WARNING) << kMalformedPreferenceWarning;
335 continue;
336 }
337 if (StartsWithASCII(
338 iter.key(), schema_constants::kUpdateUrlPrefix, true))
339 continue;
340 const std::string& extension_id = iter.key();
341 if (!crx_file::id_util::IdIsValid(extension_id)) {
342 LOG(WARNING) << kMalformedPreferenceWarning;
343 continue;
344 }
345 IndividualSettings by_id;
346 if (ParseIndividualSettings(subdict, SCOPE_INDIVIDUAL, &by_id)) {
347 *AccessById(extension_id) = by_id;
348 } else {
349 LOG(WARNING) << "Malformed Extension Management settings for "
350 << iter.key() << ".";
351 }
352 }
353 }
230 } 354 }
231 355
232 const base::Value* ExtensionManagement::LoadPreference( 356 const base::Value* ExtensionManagement::LoadPreference(
233 const char* pref_name, 357 const char* pref_name,
234 bool force_managed, 358 bool force_managed,
235 base::Value::Type expected_type) { 359 base::Value::Type expected_type) {
236 const PrefService::Preference* pref = 360 const PrefService::Preference* pref =
237 pref_service_->FindPreference(pref_name); 361 pref_service_->FindPreference(pref_name);
238 if (pref && !pref->IsDefaultValue() && 362 if (pref && !pref->IsDefaultValue() &&
239 (!force_managed || pref->IsManaged())) { 363 (!force_managed || pref->IsManaged())) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 content::BrowserContext* context) const { 410 content::BrowserContext* context) const {
287 return new ExtensionManagement( 411 return new ExtensionManagement(
288 Profile::FromBrowserContext(context)->GetPrefs()); 412 Profile::FromBrowserContext(context)->GetPrefs());
289 } 413 }
290 414
291 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( 415 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse(
292 content::BrowserContext* context) const { 416 content::BrowserContext* context) const {
293 return chrome::GetBrowserContextRedirectedInIncognito(context); 417 return chrome::GetBrowserContextRedirectedInIncognito(context);
294 } 418 }
295 419
420 void ExtensionManagementFactory::RegisterProfilePrefs(
421 user_prefs::PrefRegistrySyncable* user_prefs) {
422 user_prefs->RegisterDictionaryPref(
423 pref_names::kExtensionManagement,
424 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
425 }
426
296 } // namespace extensions 427 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_management.h ('k') | chrome/browser/extensions/extension_management_constants.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698