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

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

Issue 2144313002: Plumbing for login apps device policy to extensions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix comment Created 3 years, 9 months 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 <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 18 matching lines...) Expand all
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698