| 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_constants.h" |
| 28 #include "extensions/common/permissions/api_permission_set.h" | 28 #include "extensions/common/permissions/api_permission_set.h" |
| 29 #include "extensions/common/permissions/permission_set.h" | 29 #include "extensions/common/permissions/permission_set.h" |
| 30 #include "extensions/common/url_pattern.h" | 30 #include "extensions/common/url_pattern.h" |
| 31 #include "url/gurl.h" | 31 #include "url/gurl.h" |
| 32 | 32 |
| 33 namespace extensions { | 33 namespace extensions { |
| 34 | 34 |
| 35 ExtensionManagement::ExtensionManagement(PrefService* pref_service) | 35 ExtensionManagement::ExtensionManagement(PrefService* pref_service) |
| 36 : pref_service_(pref_service) { | 36 : pref_service_(pref_service) { |
| 37 pref_change_registrar_.Init(pref_service_); | 37 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() | 75 std::vector<ManagementPolicy::Provider*> ExtensionManagement::GetProviders() |
| 76 const { | 76 const { |
| 77 return providers_.get(); | 77 return providers_.get(); |
| 78 } | 78 } |
| 79 | 79 |
| 80 bool ExtensionManagement::BlacklistedByDefault() const { | 80 bool ExtensionManagement::BlacklistedByDefault() const { |
| 81 return default_settings_->installation_mode == INSTALLATION_BLOCKED; | 81 return default_settings_->installation_mode == INSTALLATION_BLOCKED; |
| 82 } | 82 } |
| 83 | 83 |
| 84 ExtensionManagement::InstallationMode ExtensionManagement::GetInstallationMode( | 84 ExtensionManagement::InstallationMode ExtensionManagement::GetInstallationMode( |
| 85 const ExtensionId& id) const { | 85 const Extension* extension) const { |
| 86 return ReadById(id)->installation_mode; | 86 // Check per-extension installation mode setting first. |
| 87 auto iter_id = settings_by_id_.find(extension->id()); |
| 88 if (iter_id != settings_by_id_.end()) |
| 89 return iter_id->second->installation_mode; |
| 90 std::string update_url; |
| 91 // Check per-update-url installation mode setting. |
| 92 if (extension->manifest()->GetString(manifest_keys::kUpdateURL, |
| 93 &update_url)) { |
| 94 auto iter_update_url = settings_by_update_url_.find(update_url); |
| 95 if (iter_update_url != settings_by_update_url_.end()) |
| 96 return iter_update_url->second->installation_mode; |
| 97 } |
| 98 // Fall back to default installation mode setting. |
| 99 return default_settings_->installation_mode; |
| 87 } | 100 } |
| 88 | 101 |
| 89 scoped_ptr<base::DictionaryValue> ExtensionManagement::GetForceInstallList() | 102 scoped_ptr<base::DictionaryValue> ExtensionManagement::GetForceInstallList() |
| 90 const { | 103 const { |
| 91 scoped_ptr<base::DictionaryValue> install_list(new base::DictionaryValue()); | 104 scoped_ptr<base::DictionaryValue> install_list(new base::DictionaryValue()); |
| 92 for (SettingsIdMap::const_iterator it = settings_by_id_.begin(); | 105 for (SettingsIdMap::const_iterator it = settings_by_id_.begin(); |
| 93 it != settings_by_id_.end(); | 106 it != settings_by_id_.end(); |
| 94 ++it) { | 107 ++it) { |
| 95 if (it->second->installation_mode == INSTALLATION_FORCED) { | 108 if (it->second->installation_mode == INSTALLATION_FORCED) { |
| 96 ExternalPolicyLoader::AddExtension( | 109 ExternalPolicyLoader::AddExtension( |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 bool ExtensionManagement::IsAllowedManifestType( | 160 bool ExtensionManagement::IsAllowedManifestType( |
| 148 Manifest::Type manifest_type) const { | 161 Manifest::Type manifest_type) const { |
| 149 if (!global_settings_->has_restricted_allowed_types) | 162 if (!global_settings_->has_restricted_allowed_types) |
| 150 return true; | 163 return true; |
| 151 const std::vector<Manifest::Type>& allowed_types = | 164 const std::vector<Manifest::Type>& allowed_types = |
| 152 global_settings_->allowed_types; | 165 global_settings_->allowed_types; |
| 153 return std::find(allowed_types.begin(), allowed_types.end(), manifest_type) != | 166 return std::find(allowed_types.begin(), allowed_types.end(), manifest_type) != |
| 154 allowed_types.end(); | 167 allowed_types.end(); |
| 155 } | 168 } |
| 156 | 169 |
| 157 const APIPermissionSet& ExtensionManagement::GetBlockedAPIPermissions( | 170 APIPermissionSet ExtensionManagement::GetBlockedAPIPermissions( |
| 158 const ExtensionId& id) const { | 171 const Extension* extension) const { |
| 159 return ReadById(id)->blocked_permissions; | 172 // Fetch per-extension blocked permissions setting. |
| 173 auto iter_id = settings_by_id_.find(extension->id()); |
| 174 |
| 175 // Fetch per-update-url blocked permissions setting. |
| 176 std::string update_url; |
| 177 auto iter_update_url = settings_by_update_url_.end(); |
| 178 if (extension->manifest()->GetString(manifest_keys::kUpdateURL, |
| 179 &update_url)) { |
| 180 iter_update_url = settings_by_update_url_.find(update_url); |
| 181 } |
| 182 |
| 183 if (iter_id != settings_by_id_.end() && |
| 184 iter_update_url != settings_by_update_url_.end()) { |
| 185 // Blocked permissions setting are specified in both per-extension and |
| 186 // per-update-url settings, try to merge them. |
| 187 APIPermissionSet merged; |
| 188 APIPermissionSet::Union(iter_id->second->blocked_permissions, |
| 189 iter_update_url->second->blocked_permissions, |
| 190 &merged); |
| 191 return merged; |
| 192 } |
| 193 // Check whether if in one of them, setting is specified. |
| 194 if (iter_id != settings_by_id_.end()) |
| 195 return iter_id->second->blocked_permissions; |
| 196 if (iter_update_url != settings_by_update_url_.end()) |
| 197 return iter_update_url->second->blocked_permissions; |
| 198 // Fall back to the default blocked permissions setting. |
| 199 return default_settings_->blocked_permissions; |
| 160 } | 200 } |
| 161 | 201 |
| 162 scoped_refptr<const PermissionSet> ExtensionManagement::GetBlockedPermissions( | 202 scoped_refptr<const PermissionSet> ExtensionManagement::GetBlockedPermissions( |
| 163 const ExtensionId& id) const { | 203 const Extension* extension) const { |
| 164 // Only api permissions are supported currently. | 204 // Only api permissions are supported currently. |
| 165 return scoped_refptr<const PermissionSet>( | 205 return scoped_refptr<const PermissionSet>(new PermissionSet( |
| 166 new PermissionSet(GetBlockedAPIPermissions(id), | 206 GetBlockedAPIPermissions(extension), ManifestPermissionSet(), |
| 167 ManifestPermissionSet(), | 207 URLPatternSet(), URLPatternSet())); |
| 168 URLPatternSet(), | |
| 169 URLPatternSet())); | |
| 170 } | 208 } |
| 171 | 209 |
| 172 bool ExtensionManagement::IsPermissionSetAllowed( | 210 bool ExtensionManagement::IsPermissionSetAllowed( |
| 173 const ExtensionId& id, | 211 const Extension* extension, |
| 174 scoped_refptr<const PermissionSet> perms) const { | 212 scoped_refptr<const PermissionSet> perms) const { |
| 175 for (const auto& blocked_api : GetBlockedAPIPermissions(id)) { | 213 for (const auto& blocked_api : GetBlockedAPIPermissions(extension)) { |
| 176 if (perms->HasAPIPermission(blocked_api->id())) | 214 if (perms->HasAPIPermission(blocked_api->id())) |
| 177 return false; | 215 return false; |
| 178 } | 216 } |
| 179 return true; | 217 return true; |
| 180 } | 218 } |
| 181 | 219 |
| 182 void ExtensionManagement::Refresh() { | 220 void ExtensionManagement::Refresh() { |
| 183 // Load all extension management settings preferences. | 221 // Load all extension management settings preferences. |
| 184 const base::ListValue* allowed_list_pref = | 222 const base::ListValue* allowed_list_pref = |
| 185 static_cast<const base::ListValue*>(LoadPreference( | 223 static_cast<const base::ListValue*>(LoadPreference( |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 } | 345 } |
| 308 | 346 |
| 309 if (dict_pref) { | 347 if (dict_pref) { |
| 310 // Parse new extension management preference. | 348 // Parse new extension management preference. |
| 311 for (base::DictionaryValue::Iterator iter(*dict_pref); !iter.IsAtEnd(); | 349 for (base::DictionaryValue::Iterator iter(*dict_pref); !iter.IsAtEnd(); |
| 312 iter.Advance()) { | 350 iter.Advance()) { |
| 313 if (iter.key() == schema_constants::kWildcard) | 351 if (iter.key() == schema_constants::kWildcard) |
| 314 continue; | 352 continue; |
| 315 if (!iter.value().GetAsDictionary(&subdict)) | 353 if (!iter.value().GetAsDictionary(&subdict)) |
| 316 continue; | 354 continue; |
| 317 if (StartsWithASCII(iter.key(), schema_constants::kUpdateUrlPrefix, true)) | 355 if (StartsWithASCII(iter.key(), schema_constants::kUpdateUrlPrefix, |
| 318 continue; | 356 true)) { |
| 319 const std::string& extension_id = iter.key(); | 357 const std::string& update_url = |
| 320 if (!crx_file::id_util::IdIsValid(extension_id)) { | 358 iter.key().substr(strlen(schema_constants::kUpdateUrlPrefix)); |
| 321 LOG(WARNING) << "Invalid extension ID : " << extension_id << "."; | 359 if (!GURL(update_url).is_valid()) { |
| 322 continue; | 360 LOG(WARNING) << "Invalid update URL: " << update_url << "."; |
| 323 } | 361 continue; |
| 324 internal::IndividualSettings* by_id = AccessById(extension_id); | 362 } |
| 325 if (!by_id->Parse(subdict, | 363 internal::IndividualSettings* by_update_url = |
| 326 internal::IndividualSettings::SCOPE_INDIVIDUAL)) { | 364 AccessByUpdateUrl(update_url); |
| 327 settings_by_id_.erase(extension_id); | 365 if (!by_update_url->Parse( |
| 328 LOG(WARNING) << "Malformed Extension Management settings for " | 366 subdict, internal::IndividualSettings::SCOPE_UPDATE_URL)) { |
| 329 << extension_id << "."; | 367 settings_by_update_url_.erase(update_url); |
| 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 |