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

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

Issue 671943003: Add update url controlled extension management settings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ext-5
Patch Set: add unit tests Created 6 years, 1 month 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 <algorithm> 7 #include <algorithm>
8 #include <string>
9 8
10 #include "base/bind.h" 9 #include "base/bind.h"
11 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
12 #include "base/logging.h" 11 #include "base/logging.h"
13 #include "base/prefs/pref_service.h" 12 #include "base/prefs/pref_service.h"
14 #include "base/strings/string16.h" 13 #include "base/strings/string16.h"
15 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
16 #include "chrome/browser/extensions/extension_management_constants.h" 15 #include "chrome/browser/extensions/extension_management_constants.h"
17 #include "chrome/browser/extensions/extension_management_internal.h" 16 #include "chrome/browser/extensions/extension_management_internal.h"
18 #include "chrome/browser/extensions/external_policy_loader.h" 17 #include "chrome/browser/extensions/external_policy_loader.h"
19 #include "chrome/browser/extensions/external_provider_impl.h" 18 #include "chrome/browser/extensions/external_provider_impl.h"
20 #include "chrome/browser/extensions/permissions_based_management_policy_provider .h" 19 #include "chrome/browser/extensions/permissions_based_management_policy_provider .h"
21 #include "chrome/browser/extensions/standard_management_policy_provider.h" 20 #include "chrome/browser/extensions/standard_management_policy_provider.h"
22 #include "chrome/browser/profiles/incognito_helpers.h" 21 #include "chrome/browser/profiles/incognito_helpers.h"
23 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
24 #include "components/crx_file/id_util.h" 23 #include "components/crx_file/id_util.h"
25 #include "components/keyed_service/content/browser_context_dependency_manager.h" 24 #include "components/keyed_service/content/browser_context_dependency_manager.h"
26 #include "components/pref_registry/pref_registry_syncable.h" 25 #include "components/pref_registry/pref_registry_syncable.h"
27 #include "extensions/browser/pref_names.h" 26 #include "extensions/browser/pref_names.h"
27 #include "extensions/common/manifest.h"
Joao da Silva 2014/11/04 14:06:09 Already in the header
binjin 2014/11/05 12:52:42 Done.
28 #include "extensions/common/manifest_constants.h"
28 #include "extensions/common/permissions/api_permission_set.h" 29 #include "extensions/common/permissions/api_permission_set.h"
29 #include "extensions/common/permissions/permission_set.h" 30 #include "extensions/common/permissions/permission_set.h"
30 #include "extensions/common/url_pattern.h" 31 #include "extensions/common/url_pattern.h"
31 #include "url/gurl.h" 32 #include "url/gurl.h"
32 33
33 namespace extensions { 34 namespace extensions {
34 35
35 ExtensionManagement::ExtensionManagement(PrefService* pref_service) 36 ExtensionManagement::ExtensionManagement(PrefService* pref_service)
36 : pref_service_(pref_service) { 37 : pref_service_(pref_service) {
37 pref_change_registrar_.Init(pref_service_); 38 pref_change_registrar_.Init(pref_service_);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 std::vector<ManagementPolicy::Provider*> ExtensionManagement::GetProviders() 76 std::vector<ManagementPolicy::Provider*> ExtensionManagement::GetProviders()
76 const { 77 const {
77 return providers_.get(); 78 return providers_.get();
78 } 79 }
79 80
80 bool ExtensionManagement::BlacklistedByDefault() const { 81 bool ExtensionManagement::BlacklistedByDefault() const {
81 return default_settings_->installation_mode == INSTALLATION_BLOCKED; 82 return default_settings_->installation_mode == INSTALLATION_BLOCKED;
82 } 83 }
83 84
84 ExtensionManagement::InstallationMode ExtensionManagement::GetInstallationMode( 85 ExtensionManagement::InstallationMode ExtensionManagement::GetInstallationMode(
85 const ExtensionId& id) const { 86 const Extension* extension) const {
86 return ReadById(id)->installation_mode; 87 // Check per-extension installation mode setting first.
88 auto iter_id = settings_by_id_.find(extension->id());
89 if (iter_id != settings_by_id_.end())
90 return iter_id->second->installation_mode;
91 std::string update_url;
92 // Check per-update-url installation mode setting.
93 if (extension->manifest()->GetString(manifest_keys::kUpdateURL,
94 &update_url)) {
95 auto iter_update_url = settings_by_update_url_.find(update_url);
96 if (iter_update_url != settings_by_update_url_.end())
97 return iter_update_url->second->installation_mode;
98 }
99 // Fall back to default installation mode setting.
100 return default_settings_->installation_mode;
87 } 101 }
88 102
89 scoped_ptr<base::DictionaryValue> ExtensionManagement::GetForceInstallList() 103 scoped_ptr<base::DictionaryValue> ExtensionManagement::GetForceInstallList()
90 const { 104 const {
91 scoped_ptr<base::DictionaryValue> install_list(new base::DictionaryValue()); 105 scoped_ptr<base::DictionaryValue> install_list(new base::DictionaryValue());
92 for (SettingsIdMap::const_iterator it = settings_by_id_.begin(); 106 for (SettingsIdMap::const_iterator it = settings_by_id_.begin();
93 it != settings_by_id_.end(); 107 it != settings_by_id_.end();
94 ++it) { 108 ++it) {
95 if (it->second->installation_mode == INSTALLATION_FORCED) { 109 if (it->second->installation_mode == INSTALLATION_FORCED) {
96 ExternalPolicyLoader::AddExtension( 110 ExternalPolicyLoader::AddExtension(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 bool ExtensionManagement::IsAllowedManifestType( 161 bool ExtensionManagement::IsAllowedManifestType(
148 Manifest::Type manifest_type) const { 162 Manifest::Type manifest_type) const {
149 if (!global_settings_->has_restricted_allowed_types) 163 if (!global_settings_->has_restricted_allowed_types)
150 return true; 164 return true;
151 const std::vector<Manifest::Type>& allowed_types = 165 const std::vector<Manifest::Type>& allowed_types =
152 global_settings_->allowed_types; 166 global_settings_->allowed_types;
153 return std::find(allowed_types.begin(), allowed_types.end(), manifest_type) != 167 return std::find(allowed_types.begin(), allowed_types.end(), manifest_type) !=
154 allowed_types.end(); 168 allowed_types.end();
155 } 169 }
156 170
157 const APIPermissionSet& ExtensionManagement::GetBlockedAPIPermissions( 171 APIPermissionSet ExtensionManagement::GetBlockedAPIPermissions(
158 const ExtensionId& id) const { 172 const Extension* extension) const {
159 return ReadById(id)->blocked_permissions; 173 // Fetch per-extension blocked permissions setting.
174 auto iter_id = settings_by_id_.find(extension->id());
175
176 // Fetch per-update-url blocked permissions setting.
177 std::string update_url;
178 auto iter_update_url = settings_by_update_url_.end();
179 if (extension->manifest()->GetString(manifest_keys::kUpdateURL,
180 &update_url)) {
181 iter_update_url = settings_by_update_url_.find(update_url);
182 }
183
184 if (iter_id != settings_by_id_.end() &&
185 iter_update_url != settings_by_update_url_.end()) {
186 // Blocked permissions setting are specified in both per-extension and
187 // per-update-url settings, try to merge them.
188 APIPermissionSet unioned;
Joao da Silva 2014/11/04 14:06:09 Rename this variable to |merged|
binjin 2014/11/05 12:52:42 Done.
189 APIPermissionSet::Union(iter_id->second->blocked_permissions,
190 iter_update_url->second->blocked_permissions,
191 &unioned);
192 return unioned;
193 }
194 // Check whether if in one of them, setting is specified.
195 if (iter_id != settings_by_id_.end())
196 return iter_id->second->blocked_permissions;
197 if (iter_update_url != settings_by_update_url_.end())
198 return iter_update_url->second->blocked_permissions;
199 // Fall back to the default blocked permissions setting.
200 return default_settings_->blocked_permissions;
160 } 201 }
161 202
162 scoped_refptr<const PermissionSet> ExtensionManagement::GetBlockedPermissions( 203 scoped_refptr<const PermissionSet> ExtensionManagement::GetBlockedPermissions(
163 const ExtensionId& id) const { 204 const Extension* extension) const {
164 // Only api permissions are supported currently. 205 // Only api permissions are supported currently.
165 return scoped_refptr<const PermissionSet>( 206 return scoped_refptr<const PermissionSet>(new PermissionSet(
166 new PermissionSet(GetBlockedAPIPermissions(id), 207 GetBlockedAPIPermissions(extension), ManifestPermissionSet(),
167 ManifestPermissionSet(), 208 URLPatternSet(), URLPatternSet()));
168 URLPatternSet(),
169 URLPatternSet()));
170 } 209 }
171 210
172 bool ExtensionManagement::IsPermissionSetAllowed( 211 bool ExtensionManagement::IsPermissionSetAllowed(
173 const ExtensionId& id, 212 const Extension* extension,
174 scoped_refptr<const PermissionSet> perms) const { 213 scoped_refptr<const PermissionSet> perms) const {
175 for (const auto& blocked_api : GetBlockedAPIPermissions(id)) { 214 for (const auto& blocked_api : GetBlockedAPIPermissions(extension)) {
176 if (perms->HasAPIPermission(blocked_api->id())) 215 if (perms->HasAPIPermission(blocked_api->id()))
177 return false; 216 return false;
178 } 217 }
179 return true; 218 return true;
180 } 219 }
181 220
182 void ExtensionManagement::Refresh() { 221 void ExtensionManagement::Refresh() {
183 // Load all extension management settings preferences. 222 // Load all extension management settings preferences.
184 const base::ListValue* allowed_list_pref = 223 const base::ListValue* allowed_list_pref =
185 static_cast<const base::ListValue*>(LoadPreference( 224 static_cast<const base::ListValue*>(LoadPreference(
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 } 346 }
308 347
309 if (dict_pref) { 348 if (dict_pref) {
310 // Parse new extension management preference. 349 // Parse new extension management preference.
311 for (base::DictionaryValue::Iterator iter(*dict_pref); !iter.IsAtEnd(); 350 for (base::DictionaryValue::Iterator iter(*dict_pref); !iter.IsAtEnd();
312 iter.Advance()) { 351 iter.Advance()) {
313 if (iter.key() == schema_constants::kWildcard) 352 if (iter.key() == schema_constants::kWildcard)
314 continue; 353 continue;
315 if (!iter.value().GetAsDictionary(&subdict)) 354 if (!iter.value().GetAsDictionary(&subdict))
316 continue; 355 continue;
317 if (StartsWithASCII(iter.key(), schema_constants::kUpdateUrlPrefix, true)) 356 if (StartsWithASCII(iter.key(), schema_constants::kUpdateUrlPrefix,
318 continue; 357 true)) {
319 const std::string& extension_id = iter.key(); 358 const std::string& update_url =
320 if (!crx_file::id_util::IdIsValid(extension_id)) { 359 iter.key().substr(strlen(schema_constants::kUpdateUrlPrefix));
321 LOG(WARNING) << "Invalid extension ID : " << extension_id << "."; 360 if (!GURL(update_url).is_valid()) {
322 continue; 361 LOG(WARNING) << "Invalid update URL: " << update_url << ".";
323 } 362 continue;
324 internal::IndividualSettings* by_id = AccessById(extension_id); 363 }
325 if (!by_id->Parse(subdict, 364 internal::IndividualSettings* by_id = AccessByUpdateUrl(update_url);
Joao da Silva 2014/11/04 14:06:09 Rename |by_id| here to |by_update_url|
binjin 2014/11/05 12:52:42 Done.
326 internal::IndividualSettings::SCOPE_INDIVIDUAL)) { 365 if (!by_id->Parse(subdict,
327 settings_by_id_.erase(extension_id); 366 internal::IndividualSettings::SCOPE_UPDATE_URL)) {
328 LOG(WARNING) << "Malformed Extension Management settings for " 367 settings_by_id_.erase(update_url);
Joao da Silva 2014/11/04 14:06:09 settings_by_update_url_
binjin 2014/11/05 12:52:42 Done.
329 << extension_id << "."; 368 LOG(WARNING) << "Malformed Extension Management settings for "
369 "extensions with update url: " << update_url << ".";
370 }
371 } else {
372 const std::string& extension_id = iter.key();
373 if (!crx_file::id_util::IdIsValid(extension_id)) {
374 LOG(WARNING) << "Invalid extension ID : " << extension_id << ".";
375 continue;
376 }
377 internal::IndividualSettings* by_id = AccessById(extension_id);
378 if (!by_id->Parse(subdict,
379 internal::IndividualSettings::SCOPE_INDIVIDUAL)) {
380 settings_by_id_.erase(extension_id);
381 LOG(WARNING) << "Malformed Extension Management settings for "
382 << extension_id << ".";
383 }
330 } 384 }
331 } 385 }
332 } 386 }
333 } 387 }
334 388
335 const base::Value* ExtensionManagement::LoadPreference( 389 const base::Value* ExtensionManagement::LoadPreference(
336 const char* pref_name, 390 const char* pref_name,
337 bool force_managed, 391 bool force_managed,
338 base::Value::Type expected_type) { 392 base::Value::Type expected_type) {
339 if (!pref_service_) 393 if (!pref_service_)
(...skipping 12 matching lines...) Expand all
352 void ExtensionManagement::OnExtensionPrefChanged() { 406 void ExtensionManagement::OnExtensionPrefChanged() {
353 Refresh(); 407 Refresh();
354 NotifyExtensionManagementPrefChanged(); 408 NotifyExtensionManagementPrefChanged();
355 } 409 }
356 410
357 void ExtensionManagement::NotifyExtensionManagementPrefChanged() { 411 void ExtensionManagement::NotifyExtensionManagementPrefChanged() {
358 FOR_EACH_OBSERVER( 412 FOR_EACH_OBSERVER(
359 Observer, observer_list_, OnExtensionManagementSettingsChanged()); 413 Observer, observer_list_, OnExtensionManagementSettingsChanged());
360 } 414 }
361 415
362 const internal::IndividualSettings* ExtensionManagement::ReadById(
363 const ExtensionId& id) const {
364 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id;
365 SettingsIdMap::const_iterator it = settings_by_id_.find(id);
366 if (it != settings_by_id_.end())
367 return it->second;
368 return default_settings_.get();
369 }
370
371 const internal::GlobalSettings* ExtensionManagement::ReadGlobalSettings()
372 const {
373 return global_settings_.get();
374 }
375
376 internal::IndividualSettings* ExtensionManagement::AccessById( 416 internal::IndividualSettings* ExtensionManagement::AccessById(
377 const ExtensionId& id) { 417 const ExtensionId& id) {
378 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id; 418 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id;
379 SettingsIdMap::iterator it = settings_by_id_.find(id); 419 SettingsIdMap::iterator it = settings_by_id_.find(id);
380 if (it == settings_by_id_.end()) { 420 if (it == settings_by_id_.end()) {
381 scoped_ptr<internal::IndividualSettings> settings( 421 scoped_ptr<internal::IndividualSettings> settings(
382 new internal::IndividualSettings(*default_settings_)); 422 new internal::IndividualSettings(*default_settings_));
383 it = settings_by_id_.add(id, settings.Pass()).first; 423 it = settings_by_id_.add(id, settings.Pass()).first;
384 } 424 }
385 return it->second; 425 return it->second;
386 } 426 }
387 427
428 internal::IndividualSettings* ExtensionManagement::AccessByUpdateUrl(
429 const std::string& update_url) {
430 DCHECK(GURL(update_url).is_valid()) << "Invalid update URL: " << update_url;
431 SettingsUpdateUrlMap::iterator it = settings_by_update_url_.find(update_url);
432 if (it == settings_by_update_url_.end()) {
433 scoped_ptr<internal::IndividualSettings> settings(
434 new internal::IndividualSettings(*default_settings_));
435 it = settings_by_update_url_.add(update_url, settings.Pass()).first;
436 }
437 return it->second;
438 }
439
388 ExtensionManagement* ExtensionManagementFactory::GetForBrowserContext( 440 ExtensionManagement* ExtensionManagementFactory::GetForBrowserContext(
389 content::BrowserContext* context) { 441 content::BrowserContext* context) {
390 return static_cast<ExtensionManagement*>( 442 return static_cast<ExtensionManagement*>(
391 GetInstance()->GetServiceForBrowserContext(context, true)); 443 GetInstance()->GetServiceForBrowserContext(context, true));
392 } 444 }
393 445
394 ExtensionManagementFactory* ExtensionManagementFactory::GetInstance() { 446 ExtensionManagementFactory* ExtensionManagementFactory::GetInstance() {
395 return Singleton<ExtensionManagementFactory>::get(); 447 return Singleton<ExtensionManagementFactory>::get();
396 } 448 }
397 449
(...skipping 18 matching lines...) Expand all
416 } 468 }
417 469
418 void ExtensionManagementFactory::RegisterProfilePrefs( 470 void ExtensionManagementFactory::RegisterProfilePrefs(
419 user_prefs::PrefRegistrySyncable* user_prefs) { 471 user_prefs::PrefRegistrySyncable* user_prefs) {
420 user_prefs->RegisterDictionaryPref( 472 user_prefs->RegisterDictionaryPref(
421 pref_names::kExtensionManagement, 473 pref_names::kExtensionManagement,
422 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 474 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
423 } 475 }
424 476
425 } // namespace extensions 477 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698