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(Profile* profile) : profile_(profile) { |
42 : pref_service_(pref_service) { | |
43 TRACE_EVENT0("browser,startup", | 46 TRACE_EVENT0("browser,startup", |
44 "ExtensionManagement::ExtensionManagement::ctor"); | 47 "ExtensionManagement::ExtensionManagement::ctor"); |
45 pref_change_registrar_.Init(pref_service_); | 48 pref_change_registrar_.Init(profile_->GetPrefs()); |
46 base::Closure pref_change_callback = base::Bind( | 49 base::Closure pref_change_callback = base::Bind( |
47 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this)); | 50 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this)); |
48 pref_change_registrar_.Add(pref_names::kInstallAllowList, | 51 pref_change_registrar_.Add(pref_names::kInstallAllowList, |
49 pref_change_callback); | 52 pref_change_callback); |
50 pref_change_registrar_.Add(pref_names::kInstallDenyList, | 53 pref_change_registrar_.Add(pref_names::kInstallDenyList, |
51 pref_change_callback); | 54 pref_change_callback); |
52 pref_change_registrar_.Add(pref_names::kInstallForceList, | 55 pref_change_registrar_.Add(pref_names::kInstallForceList, |
53 pref_change_callback); | 56 pref_change_callback); |
57 pref_change_registrar_.Add(pref_names::kInstallLoginScreenAppList, | |
58 pref_change_callback); | |
54 pref_change_registrar_.Add(pref_names::kAllowedInstallSites, | 59 pref_change_registrar_.Add(pref_names::kAllowedInstallSites, |
55 pref_change_callback); | 60 pref_change_callback); |
56 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); | 61 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); |
57 pref_change_registrar_.Add(pref_names::kExtensionManagement, | 62 pref_change_registrar_.Add(pref_names::kExtensionManagement, |
58 pref_change_callback); | 63 pref_change_callback); |
59 // Note that both |global_settings_| and |default_settings_| will be null | 64 // 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 | 65 // before first call to Refresh(), so in order to resolve this, Refresh() must |
61 // be called in the initialization of ExtensionManagement. | 66 // be called in the initialization of ExtensionManagement. |
62 Refresh(); | 67 Refresh(); |
63 providers_.push_back( | 68 providers_.push_back( |
64 base::MakeUnique<StandardManagementPolicyProvider>(this)); | 69 base::MakeUnique<StandardManagementPolicyProvider>(this)); |
65 providers_.push_back( | 70 providers_.push_back( |
66 base::MakeUnique<PermissionsBasedManagementPolicyProvider>(this)); | 71 base::MakeUnique<PermissionsBasedManagementPolicyProvider>(this)); |
67 } | 72 } |
68 | 73 |
69 ExtensionManagement::~ExtensionManagement() { | 74 ExtensionManagement::~ExtensionManagement() { |
70 } | 75 } |
71 | 76 |
72 void ExtensionManagement::Shutdown() { | 77 void ExtensionManagement::Shutdown() { |
73 pref_change_registrar_.RemoveAll(); | 78 pref_change_registrar_.RemoveAll(); |
74 pref_service_ = nullptr; | 79 profile_ = nullptr; |
75 } | 80 } |
76 | 81 |
77 void ExtensionManagement::AddObserver(Observer* observer) { | 82 void ExtensionManagement::AddObserver(Observer* observer) { |
78 observer_list_.AddObserver(observer); | 83 observer_list_.AddObserver(observer); |
79 } | 84 } |
80 | 85 |
81 void ExtensionManagement::RemoveObserver(Observer* observer) { | 86 void ExtensionManagement::RemoveObserver(Observer* observer) { |
82 observer_list_.RemoveObserver(observer); | 87 observer_list_.RemoveObserver(observer); |
83 } | 88 } |
84 | 89 |
(...skipping 18 matching lines...) Expand all Loading... | |
103 &update_url)) { | 108 &update_url)) { |
104 auto iter_update_url = settings_by_update_url_.find(update_url); | 109 auto iter_update_url = settings_by_update_url_.find(update_url); |
105 if (iter_update_url != settings_by_update_url_.end()) | 110 if (iter_update_url != settings_by_update_url_.end()) |
106 return iter_update_url->second->installation_mode; | 111 return iter_update_url->second->installation_mode; |
107 } | 112 } |
108 // Fall back to default installation mode setting. | 113 // Fall back to default installation mode setting. |
109 return default_settings_->installation_mode; | 114 return default_settings_->installation_mode; |
110 } | 115 } |
111 | 116 |
112 std::unique_ptr<base::DictionaryValue> | 117 std::unique_ptr<base::DictionaryValue> |
118 ExtensionManagement::GetInstallListByMode( | |
Devlin
2017/03/03 17:24:47
implementation order should (try) to match the dec
achuithb
2017/03/06 15:25:31
Done.
| |
119 InstallationMode installation_mode) const { | |
120 auto extension_dict = base::MakeUnique<base::DictionaryValue>(); | |
121 for (const auto& entry : settings_by_id_) { | |
122 if (entry.second->installation_mode == installation_mode) { | |
123 ExternalPolicyLoader::AddExtension(extension_dict.get(), entry.first, | |
124 entry.second->update_url); | |
125 } | |
126 } | |
127 return extension_dict; | |
128 } | |
129 | |
130 std::unique_ptr<base::DictionaryValue> | |
113 ExtensionManagement::GetForceInstallList() const { | 131 ExtensionManagement::GetForceInstallList() const { |
114 std::unique_ptr<base::DictionaryValue> install_list( | 132 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 } | 133 } |
124 | 134 |
125 std::unique_ptr<base::DictionaryValue> | 135 std::unique_ptr<base::DictionaryValue> |
126 ExtensionManagement::GetRecommendedInstallList() const { | 136 ExtensionManagement::GetRecommendedInstallList() const { |
127 std::unique_ptr<base::DictionaryValue> install_list( | 137 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 } | 138 } |
137 | 139 |
138 bool ExtensionManagement::IsInstallationExplicitlyAllowed( | 140 bool ExtensionManagement::IsInstallationExplicitlyAllowed( |
139 const ExtensionId& id) const { | 141 const ExtensionId& id) const { |
140 auto it = settings_by_id_.find(id); | 142 auto it = settings_by_id_.find(id); |
141 // No settings explicitly specified for |id|. | 143 // No settings explicitly specified for |id|. |
142 if (it == settings_by_id_.end()) | 144 if (it == settings_by_id_.end()) |
143 return false; | 145 return false; |
144 // Checks if the extension is on the automatically installed list or | 146 // Checks if the extension is on the automatically installed list or |
145 // install white-list. | 147 // install white-list. |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 static_cast<const base::ListValue*>(LoadPreference( | 250 static_cast<const base::ListValue*>(LoadPreference( |
249 pref_names::kInstallAllowList, true, base::Value::Type::LIST)); | 251 pref_names::kInstallAllowList, true, base::Value::Type::LIST)); |
250 // Allow user to use preference to block certain extensions. Note that policy | 252 // Allow user to use preference to block certain extensions. Note that policy |
251 // managed forcelist or whitelist will always override this. | 253 // managed forcelist or whitelist will always override this. |
252 const base::ListValue* denied_list_pref = | 254 const base::ListValue* denied_list_pref = |
253 static_cast<const base::ListValue*>(LoadPreference( | 255 static_cast<const base::ListValue*>(LoadPreference( |
254 pref_names::kInstallDenyList, false, base::Value::Type::LIST)); | 256 pref_names::kInstallDenyList, false, base::Value::Type::LIST)); |
255 const base::DictionaryValue* forced_list_pref = | 257 const base::DictionaryValue* forced_list_pref = |
256 static_cast<const base::DictionaryValue*>(LoadPreference( | 258 static_cast<const base::DictionaryValue*>(LoadPreference( |
257 pref_names::kInstallForceList, true, base::Value::Type::DICTIONARY)); | 259 pref_names::kInstallForceList, true, base::Value::Type::DICTIONARY)); |
260 #if defined(OS_CHROMEOS) | |
261 const base::DictionaryValue* login_screen_app_list_pref = | |
262 static_cast<const base::DictionaryValue*>( | |
263 LoadPreference(pref_names::kInstallLoginScreenAppList, true, | |
Devlin
2017/03/03 17:24:48
Can we gate loading this on whether or not this is
achuithb
2017/03/06 15:25:31
Done. I've moved up the IsSigninProfile check to h
| |
264 base::Value::Type::DICTIONARY)); | |
265 #endif | |
258 const base::ListValue* install_sources_pref = | 266 const base::ListValue* install_sources_pref = |
259 static_cast<const base::ListValue*>(LoadPreference( | 267 static_cast<const base::ListValue*>(LoadPreference( |
260 pref_names::kAllowedInstallSites, true, base::Value::Type::LIST)); | 268 pref_names::kAllowedInstallSites, true, base::Value::Type::LIST)); |
261 const base::ListValue* allowed_types_pref = | 269 const base::ListValue* allowed_types_pref = |
262 static_cast<const base::ListValue*>(LoadPreference( | 270 static_cast<const base::ListValue*>(LoadPreference( |
263 pref_names::kAllowedTypes, true, base::Value::Type::LIST)); | 271 pref_names::kAllowedTypes, true, base::Value::Type::LIST)); |
264 const base::DictionaryValue* dict_pref = | 272 const base::DictionaryValue* dict_pref = |
265 static_cast<const base::DictionaryValue*>( | 273 static_cast<const base::DictionaryValue*>( |
266 LoadPreference(pref_names::kExtensionManagement, | 274 LoadPreference(pref_names::kExtensionManagement, |
267 true, | 275 true, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 } | 316 } |
309 | 317 |
310 if (denied_list_pref) { | 318 if (denied_list_pref) { |
311 for (base::ListValue::const_iterator it = denied_list_pref->begin(); | 319 for (base::ListValue::const_iterator it = denied_list_pref->begin(); |
312 it != denied_list_pref->end(); ++it) { | 320 it != denied_list_pref->end(); ++it) { |
313 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id)) | 321 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id)) |
314 AccessById(id)->installation_mode = INSTALLATION_BLOCKED; | 322 AccessById(id)->installation_mode = INSTALLATION_BLOCKED; |
315 } | 323 } |
316 } | 324 } |
317 | 325 |
318 if (forced_list_pref) { | 326 UpdateForcedExtensions(forced_list_pref); |
319 std::string update_url; | 327 #if defined(OS_CHROMEOS) |
320 for (base::DictionaryValue::Iterator it(*forced_list_pref); !it.IsAtEnd(); | 328 if (chromeos::ProfileHelper::IsSigninProfile(profile_)) |
321 it.Advance()) { | 329 UpdateForcedExtensions(login_screen_app_list_pref); |
322 if (!crx_file::id_util::IdIsValid(it.key())) | 330 #endif |
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 | 331 |
335 if (install_sources_pref) { | 332 if (install_sources_pref) { |
336 global_settings_->has_restricted_install_sources = true; | 333 global_settings_->has_restricted_install_sources = true; |
337 for (base::ListValue::const_iterator it = install_sources_pref->begin(); | 334 for (base::ListValue::const_iterator it = install_sources_pref->begin(); |
338 it != install_sources_pref->end(); ++it) { | 335 it != install_sources_pref->end(); ++it) { |
339 std::string url_pattern; | 336 std::string url_pattern; |
340 if ((*it)->GetAsString(&url_pattern)) { | 337 if ((*it)->GetAsString(&url_pattern)) { |
341 URLPattern entry(URLPattern::SCHEME_ALL); | 338 URLPattern entry(URLPattern::SCHEME_ALL); |
342 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { | 339 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { |
343 global_settings_->install_sources.AddPattern(entry); | 340 global_settings_->install_sources.AddPattern(entry); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 } | 405 } |
409 } | 406 } |
410 } | 407 } |
411 } | 408 } |
412 } | 409 } |
413 | 410 |
414 const base::Value* ExtensionManagement::LoadPreference( | 411 const base::Value* ExtensionManagement::LoadPreference( |
415 const char* pref_name, | 412 const char* pref_name, |
416 bool force_managed, | 413 bool force_managed, |
417 base::Value::Type expected_type) { | 414 base::Value::Type expected_type) { |
418 if (!pref_service_) | 415 if (!profile_) |
419 return nullptr; | 416 return nullptr; |
420 const PrefService::Preference* pref = | 417 const PrefService::Preference* pref = |
421 pref_service_->FindPreference(pref_name); | 418 profile_->GetPrefs()->FindPreference(pref_name); |
422 if (pref && !pref->IsDefaultValue() && | 419 if (pref && !pref->IsDefaultValue() && |
423 (!force_managed || pref->IsManaged())) { | 420 (!force_managed || pref->IsManaged())) { |
424 const base::Value* value = pref->GetValue(); | 421 const base::Value* value = pref->GetValue(); |
425 if (value && value->IsType(expected_type)) | 422 if (value && value->IsType(expected_type)) |
426 return value; | 423 return value; |
427 } | 424 } |
428 return nullptr; | 425 return nullptr; |
429 } | 426 } |
430 | 427 |
431 void ExtensionManagement::OnExtensionPrefChanged() { | 428 void ExtensionManagement::OnExtensionPrefChanged() { |
432 Refresh(); | 429 Refresh(); |
433 NotifyExtensionManagementPrefChanged(); | 430 NotifyExtensionManagementPrefChanged(); |
434 } | 431 } |
435 | 432 |
436 void ExtensionManagement::NotifyExtensionManagementPrefChanged() { | 433 void ExtensionManagement::NotifyExtensionManagementPrefChanged() { |
437 for (auto& observer : observer_list_) | 434 for (auto& observer : observer_list_) |
438 observer.OnExtensionManagementSettingsChanged(); | 435 observer.OnExtensionManagementSettingsChanged(); |
439 } | 436 } |
440 | 437 |
438 void ExtensionManagement::UpdateForcedExtensions( | |
439 const base::DictionaryValue* extension_dict) { | |
440 if (!extension_dict) | |
441 return; | |
442 | |
443 std::string update_url; | |
444 for (base::DictionaryValue::Iterator it(*extension_dict); !it.IsAtEnd(); | |
445 it.Advance()) { | |
446 if (!crx_file::id_util::IdIsValid(it.key())) | |
447 continue; | |
448 const base::DictionaryValue* dict_value = nullptr; | |
449 if (it.value().GetAsDictionary(&dict_value) && | |
450 dict_value->GetStringWithoutPathExpansion( | |
451 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) { | |
452 internal::IndividualSettings* by_id = AccessById(it.key()); | |
453 by_id->installation_mode = INSTALLATION_FORCED; | |
454 by_id->update_url = update_url; | |
455 } | |
456 } | |
457 } | |
458 | |
441 internal::IndividualSettings* ExtensionManagement::AccessById( | 459 internal::IndividualSettings* ExtensionManagement::AccessById( |
442 const ExtensionId& id) { | 460 const ExtensionId& id) { |
443 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id; | 461 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id; |
444 std::unique_ptr<internal::IndividualSettings>& settings = settings_by_id_[id]; | 462 std::unique_ptr<internal::IndividualSettings>& settings = settings_by_id_[id]; |
445 if (!settings) { | 463 if (!settings) { |
446 settings = | 464 settings = |
447 base::MakeUnique<internal::IndividualSettings>(default_settings_.get()); | 465 base::MakeUnique<internal::IndividualSettings>(default_settings_.get()); |
448 } | 466 } |
449 return settings.get(); | 467 return settings.get(); |
450 } | 468 } |
(...skipping 26 matching lines...) Expand all Loading... | |
477 BrowserContextDependencyManager::GetInstance()) { | 495 BrowserContextDependencyManager::GetInstance()) { |
478 } | 496 } |
479 | 497 |
480 ExtensionManagementFactory::~ExtensionManagementFactory() { | 498 ExtensionManagementFactory::~ExtensionManagementFactory() { |
481 } | 499 } |
482 | 500 |
483 KeyedService* ExtensionManagementFactory::BuildServiceInstanceFor( | 501 KeyedService* ExtensionManagementFactory::BuildServiceInstanceFor( |
484 content::BrowserContext* context) const { | 502 content::BrowserContext* context) const { |
485 TRACE_EVENT0("browser,startup", | 503 TRACE_EVENT0("browser,startup", |
486 "ExtensionManagementFactory::BuildServiceInstanceFor"); | 504 "ExtensionManagementFactory::BuildServiceInstanceFor"); |
487 return new ExtensionManagement( | 505 return new ExtensionManagement(Profile::FromBrowserContext(context)); |
488 Profile::FromBrowserContext(context)->GetPrefs()); | |
489 } | 506 } |
490 | 507 |
491 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( | 508 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( |
492 content::BrowserContext* context) const { | 509 content::BrowserContext* context) const { |
493 return chrome::GetBrowserContextRedirectedInIncognito(context); | 510 return chrome::GetBrowserContextRedirectedInIncognito(context); |
494 } | 511 } |
495 | 512 |
496 void ExtensionManagementFactory::RegisterProfilePrefs( | 513 void ExtensionManagementFactory::RegisterProfilePrefs( |
497 user_prefs::PrefRegistrySyncable* user_prefs) { | 514 user_prefs::PrefRegistrySyncable* user_prefs) { |
498 user_prefs->RegisterDictionaryPref(pref_names::kExtensionManagement); | 515 user_prefs->RegisterDictionaryPref(pref_names::kExtensionManagement); |
499 } | 516 } |
500 | 517 |
501 } // namespace extensions | 518 } // namespace extensions |
OLD | NEW |