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 <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "components/pref_registry/pref_registry_syncable.h" | 29 #include "components/pref_registry/pref_registry_syncable.h" |
30 #include "components/prefs/pref_service.h" | 30 #include "components/prefs/pref_service.h" |
31 #include "extensions/browser/pref_names.h" | 31 #include "extensions/browser/pref_names.h" |
32 #include "extensions/common/extension.h" | 32 #include "extensions/common/extension.h" |
33 #include "extensions/common/manifest_constants.h" | 33 #include "extensions/common/manifest_constants.h" |
34 #include "extensions/common/permissions/api_permission_set.h" | 34 #include "extensions/common/permissions/api_permission_set.h" |
35 #include "extensions/common/permissions/permission_set.h" | 35 #include "extensions/common/permissions/permission_set.h" |
36 #include "extensions/common/url_pattern.h" | 36 #include "extensions/common/url_pattern.h" |
37 #include "url/gurl.h" | 37 #include "url/gurl.h" |
38 | 38 |
| 39 #if defined(OS_CHROMEOS) |
| 40 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 41 #endif |
| 42 |
39 namespace extensions { | 43 namespace extensions { |
40 | 44 |
41 ExtensionManagement::ExtensionManagement(PrefService* pref_service) | 45 ExtensionManagement::ExtensionManagement(PrefService* pref_service, |
42 : pref_service_(pref_service) { | 46 bool is_signin_profile) |
| 47 : pref_service_(pref_service), is_signin_profile_(is_signin_profile) { |
43 TRACE_EVENT0("browser,startup", | 48 TRACE_EVENT0("browser,startup", |
44 "ExtensionManagement::ExtensionManagement::ctor"); | 49 "ExtensionManagement::ExtensionManagement::ctor"); |
45 pref_change_registrar_.Init(pref_service_); | 50 pref_change_registrar_.Init(pref_service_); |
46 base::Closure pref_change_callback = base::Bind( | 51 base::Closure pref_change_callback = base::Bind( |
47 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this)); | 52 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this)); |
48 pref_change_registrar_.Add(pref_names::kInstallAllowList, | 53 pref_change_registrar_.Add(pref_names::kInstallAllowList, |
49 pref_change_callback); | 54 pref_change_callback); |
50 pref_change_registrar_.Add(pref_names::kInstallDenyList, | 55 pref_change_registrar_.Add(pref_names::kInstallDenyList, |
51 pref_change_callback); | 56 pref_change_callback); |
52 pref_change_registrar_.Add(pref_names::kInstallForceList, | 57 pref_change_registrar_.Add(pref_names::kInstallForceList, |
53 pref_change_callback); | 58 pref_change_callback); |
| 59 pref_change_registrar_.Add(pref_names::kInstallLoginScreenAppList, |
| 60 pref_change_callback); |
54 pref_change_registrar_.Add(pref_names::kAllowedInstallSites, | 61 pref_change_registrar_.Add(pref_names::kAllowedInstallSites, |
55 pref_change_callback); | 62 pref_change_callback); |
56 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); | 63 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); |
57 pref_change_registrar_.Add(pref_names::kExtensionManagement, | 64 pref_change_registrar_.Add(pref_names::kExtensionManagement, |
58 pref_change_callback); | 65 pref_change_callback); |
59 // Note that both |global_settings_| and |default_settings_| will be null | 66 // Note that both |global_settings_| and |default_settings_| will be null |
60 // before first call to Refresh(), so in order to resolve this, Refresh() must | 67 // before first call to Refresh(), so in order to resolve this, Refresh() must |
61 // be called in the initialization of ExtensionManagement. | 68 // be called in the initialization of ExtensionManagement. |
62 Refresh(); | 69 Refresh(); |
63 providers_.push_back( | 70 providers_.push_back( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 auto iter_update_url = settings_by_update_url_.find(update_url); | 111 auto iter_update_url = settings_by_update_url_.find(update_url); |
105 if (iter_update_url != settings_by_update_url_.end()) | 112 if (iter_update_url != settings_by_update_url_.end()) |
106 return iter_update_url->second->installation_mode; | 113 return iter_update_url->second->installation_mode; |
107 } | 114 } |
108 // Fall back to default installation mode setting. | 115 // Fall back to default installation mode setting. |
109 return default_settings_->installation_mode; | 116 return default_settings_->installation_mode; |
110 } | 117 } |
111 | 118 |
112 std::unique_ptr<base::DictionaryValue> | 119 std::unique_ptr<base::DictionaryValue> |
113 ExtensionManagement::GetForceInstallList() const { | 120 ExtensionManagement::GetForceInstallList() const { |
114 std::unique_ptr<base::DictionaryValue> install_list( | 121 return GetInstallListByMode(INSTALLATION_FORCED); |
115 new base::DictionaryValue()); | |
116 for (const auto& entry : settings_by_id_) { | |
117 if (entry.second->installation_mode == INSTALLATION_FORCED) { | |
118 ExternalPolicyLoader::AddExtension(install_list.get(), entry.first, | |
119 entry.second->update_url); | |
120 } | |
121 } | |
122 return install_list; | |
123 } | 122 } |
124 | 123 |
125 std::unique_ptr<base::DictionaryValue> | 124 std::unique_ptr<base::DictionaryValue> |
126 ExtensionManagement::GetRecommendedInstallList() const { | 125 ExtensionManagement::GetRecommendedInstallList() const { |
127 std::unique_ptr<base::DictionaryValue> install_list( | 126 return GetInstallListByMode(INSTALLATION_RECOMMENDED); |
128 new base::DictionaryValue()); | |
129 for (const auto& entry : settings_by_id_) { | |
130 if (entry.second->installation_mode == INSTALLATION_RECOMMENDED) { | |
131 ExternalPolicyLoader::AddExtension(install_list.get(), entry.first, | |
132 entry.second->update_url); | |
133 } | |
134 } | |
135 return install_list; | |
136 } | 127 } |
137 | 128 |
138 bool ExtensionManagement::IsInstallationExplicitlyAllowed( | 129 bool ExtensionManagement::IsInstallationExplicitlyAllowed( |
139 const ExtensionId& id) const { | 130 const ExtensionId& id) const { |
140 auto it = settings_by_id_.find(id); | 131 auto it = settings_by_id_.find(id); |
141 // No settings explicitly specified for |id|. | 132 // No settings explicitly specified for |id|. |
142 if (it == settings_by_id_.end()) | 133 if (it == settings_by_id_.end()) |
143 return false; | 134 return false; |
144 // Checks if the extension is on the automatically installed list or | 135 // Checks if the extension is on the automatically installed list or |
145 // install white-list. | 136 // install white-list. |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 static_cast<const base::ListValue*>(LoadPreference( | 239 static_cast<const base::ListValue*>(LoadPreference( |
249 pref_names::kInstallAllowList, true, base::Value::Type::LIST)); | 240 pref_names::kInstallAllowList, true, base::Value::Type::LIST)); |
250 // Allow user to use preference to block certain extensions. Note that policy | 241 // Allow user to use preference to block certain extensions. Note that policy |
251 // managed forcelist or whitelist will always override this. | 242 // managed forcelist or whitelist will always override this. |
252 const base::ListValue* denied_list_pref = | 243 const base::ListValue* denied_list_pref = |
253 static_cast<const base::ListValue*>(LoadPreference( | 244 static_cast<const base::ListValue*>(LoadPreference( |
254 pref_names::kInstallDenyList, false, base::Value::Type::LIST)); | 245 pref_names::kInstallDenyList, false, base::Value::Type::LIST)); |
255 const base::DictionaryValue* forced_list_pref = | 246 const base::DictionaryValue* forced_list_pref = |
256 static_cast<const base::DictionaryValue*>(LoadPreference( | 247 static_cast<const base::DictionaryValue*>(LoadPreference( |
257 pref_names::kInstallForceList, true, base::Value::Type::DICTIONARY)); | 248 pref_names::kInstallForceList, true, base::Value::Type::DICTIONARY)); |
| 249 const base::DictionaryValue* login_screen_app_list_pref = nullptr; |
| 250 if (is_signin_profile_) { |
| 251 login_screen_app_list_pref = static_cast<const base::DictionaryValue*>( |
| 252 LoadPreference(pref_names::kInstallLoginScreenAppList, true, |
| 253 base::Value::Type::DICTIONARY)); |
| 254 } |
258 const base::ListValue* install_sources_pref = | 255 const base::ListValue* install_sources_pref = |
259 static_cast<const base::ListValue*>(LoadPreference( | 256 static_cast<const base::ListValue*>(LoadPreference( |
260 pref_names::kAllowedInstallSites, true, base::Value::Type::LIST)); | 257 pref_names::kAllowedInstallSites, true, base::Value::Type::LIST)); |
261 const base::ListValue* allowed_types_pref = | 258 const base::ListValue* allowed_types_pref = |
262 static_cast<const base::ListValue*>(LoadPreference( | 259 static_cast<const base::ListValue*>(LoadPreference( |
263 pref_names::kAllowedTypes, true, base::Value::Type::LIST)); | 260 pref_names::kAllowedTypes, true, base::Value::Type::LIST)); |
264 const base::DictionaryValue* dict_pref = | 261 const base::DictionaryValue* dict_pref = |
265 static_cast<const base::DictionaryValue*>( | 262 static_cast<const base::DictionaryValue*>( |
266 LoadPreference(pref_names::kExtensionManagement, | 263 LoadPreference(pref_names::kExtensionManagement, |
267 true, | 264 true, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 } | 305 } |
309 | 306 |
310 if (denied_list_pref) { | 307 if (denied_list_pref) { |
311 for (base::ListValue::const_iterator it = denied_list_pref->begin(); | 308 for (base::ListValue::const_iterator it = denied_list_pref->begin(); |
312 it != denied_list_pref->end(); ++it) { | 309 it != denied_list_pref->end(); ++it) { |
313 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id)) | 310 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id)) |
314 AccessById(id)->installation_mode = INSTALLATION_BLOCKED; | 311 AccessById(id)->installation_mode = INSTALLATION_BLOCKED; |
315 } | 312 } |
316 } | 313 } |
317 | 314 |
318 if (forced_list_pref) { | 315 UpdateForcedExtensions(forced_list_pref); |
319 std::string update_url; | 316 UpdateForcedExtensions(login_screen_app_list_pref); |
320 for (base::DictionaryValue::Iterator it(*forced_list_pref); !it.IsAtEnd(); | |
321 it.Advance()) { | |
322 if (!crx_file::id_util::IdIsValid(it.key())) | |
323 continue; | |
324 const base::DictionaryValue* dict_value = NULL; | |
325 if (it.value().GetAsDictionary(&dict_value) && | |
326 dict_value->GetStringWithoutPathExpansion( | |
327 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) { | |
328 internal::IndividualSettings* by_id = AccessById(it.key()); | |
329 by_id->installation_mode = INSTALLATION_FORCED; | |
330 by_id->update_url = update_url; | |
331 } | |
332 } | |
333 } | |
334 | 317 |
335 if (install_sources_pref) { | 318 if (install_sources_pref) { |
336 global_settings_->has_restricted_install_sources = true; | 319 global_settings_->has_restricted_install_sources = true; |
337 for (base::ListValue::const_iterator it = install_sources_pref->begin(); | 320 for (base::ListValue::const_iterator it = install_sources_pref->begin(); |
338 it != install_sources_pref->end(); ++it) { | 321 it != install_sources_pref->end(); ++it) { |
339 std::string url_pattern; | 322 std::string url_pattern; |
340 if ((*it)->GetAsString(&url_pattern)) { | 323 if ((*it)->GetAsString(&url_pattern)) { |
341 URLPattern entry(URLPattern::SCHEME_ALL); | 324 URLPattern entry(URLPattern::SCHEME_ALL); |
342 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { | 325 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { |
343 global_settings_->install_sources.AddPattern(entry); | 326 global_settings_->install_sources.AddPattern(entry); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 void ExtensionManagement::OnExtensionPrefChanged() { | 414 void ExtensionManagement::OnExtensionPrefChanged() { |
432 Refresh(); | 415 Refresh(); |
433 NotifyExtensionManagementPrefChanged(); | 416 NotifyExtensionManagementPrefChanged(); |
434 } | 417 } |
435 | 418 |
436 void ExtensionManagement::NotifyExtensionManagementPrefChanged() { | 419 void ExtensionManagement::NotifyExtensionManagementPrefChanged() { |
437 for (auto& observer : observer_list_) | 420 for (auto& observer : observer_list_) |
438 observer.OnExtensionManagementSettingsChanged(); | 421 observer.OnExtensionManagementSettingsChanged(); |
439 } | 422 } |
440 | 423 |
| 424 std::unique_ptr<base::DictionaryValue> |
| 425 ExtensionManagement::GetInstallListByMode( |
| 426 InstallationMode installation_mode) const { |
| 427 auto extension_dict = base::MakeUnique<base::DictionaryValue>(); |
| 428 for (const auto& entry : settings_by_id_) { |
| 429 if (entry.second->installation_mode == installation_mode) { |
| 430 ExternalPolicyLoader::AddExtension(extension_dict.get(), entry.first, |
| 431 entry.second->update_url); |
| 432 } |
| 433 } |
| 434 return extension_dict; |
| 435 } |
| 436 |
| 437 void ExtensionManagement::UpdateForcedExtensions( |
| 438 const base::DictionaryValue* extension_dict) { |
| 439 if (!extension_dict) |
| 440 return; |
| 441 |
| 442 std::string update_url; |
| 443 for (base::DictionaryValue::Iterator it(*extension_dict); !it.IsAtEnd(); |
| 444 it.Advance()) { |
| 445 if (!crx_file::id_util::IdIsValid(it.key())) |
| 446 continue; |
| 447 const base::DictionaryValue* dict_value = nullptr; |
| 448 if (it.value().GetAsDictionary(&dict_value) && |
| 449 dict_value->GetStringWithoutPathExpansion( |
| 450 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) { |
| 451 internal::IndividualSettings* by_id = AccessById(it.key()); |
| 452 by_id->installation_mode = INSTALLATION_FORCED; |
| 453 by_id->update_url = update_url; |
| 454 } |
| 455 } |
| 456 } |
| 457 |
441 internal::IndividualSettings* ExtensionManagement::AccessById( | 458 internal::IndividualSettings* ExtensionManagement::AccessById( |
442 const ExtensionId& id) { | 459 const ExtensionId& id) { |
443 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id; | 460 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id; |
444 std::unique_ptr<internal::IndividualSettings>& settings = settings_by_id_[id]; | 461 std::unique_ptr<internal::IndividualSettings>& settings = settings_by_id_[id]; |
445 if (!settings) { | 462 if (!settings) { |
446 settings = | 463 settings = |
447 base::MakeUnique<internal::IndividualSettings>(default_settings_.get()); | 464 base::MakeUnique<internal::IndividualSettings>(default_settings_.get()); |
448 } | 465 } |
449 return settings.get(); | 466 return settings.get(); |
450 } | 467 } |
(...skipping 26 matching lines...) Expand all Loading... |
477 BrowserContextDependencyManager::GetInstance()) { | 494 BrowserContextDependencyManager::GetInstance()) { |
478 } | 495 } |
479 | 496 |
480 ExtensionManagementFactory::~ExtensionManagementFactory() { | 497 ExtensionManagementFactory::~ExtensionManagementFactory() { |
481 } | 498 } |
482 | 499 |
483 KeyedService* ExtensionManagementFactory::BuildServiceInstanceFor( | 500 KeyedService* ExtensionManagementFactory::BuildServiceInstanceFor( |
484 content::BrowserContext* context) const { | 501 content::BrowserContext* context) const { |
485 TRACE_EVENT0("browser,startup", | 502 TRACE_EVENT0("browser,startup", |
486 "ExtensionManagementFactory::BuildServiceInstanceFor"); | 503 "ExtensionManagementFactory::BuildServiceInstanceFor"); |
487 return new ExtensionManagement( | 504 Profile* profile = Profile::FromBrowserContext(context); |
488 Profile::FromBrowserContext(context)->GetPrefs()); | 505 bool is_signin_profile = false; |
| 506 #if defined(OS_CHROMEOS) |
| 507 is_signin_profile = chromeos::ProfileHelper::IsSigninProfile(profile); |
| 508 #endif |
| 509 return new ExtensionManagement(profile->GetPrefs(), is_signin_profile); |
489 } | 510 } |
490 | 511 |
491 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( | 512 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( |
492 content::BrowserContext* context) const { | 513 content::BrowserContext* context) const { |
493 return chrome::GetBrowserContextRedirectedInIncognito(context); | 514 return chrome::GetBrowserContextRedirectedInIncognito(context); |
494 } | 515 } |
495 | 516 |
496 void ExtensionManagementFactory::RegisterProfilePrefs( | 517 void ExtensionManagementFactory::RegisterProfilePrefs( |
497 user_prefs::PrefRegistrySyncable* user_prefs) { | 518 user_prefs::PrefRegistrySyncable* user_prefs) { |
498 user_prefs->RegisterDictionaryPref(pref_names::kExtensionManagement); | 519 user_prefs->RegisterDictionaryPref(pref_names::kExtensionManagement); |
499 } | 520 } |
500 | 521 |
501 } // namespace extensions | 522 } // namespace extensions |
OLD | NEW |