Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |