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

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

Issue 559603002: Add new ExtensionManagement preference (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase; fixes Created 6 years, 3 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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
11 #include "base/strings/string_util.h"
11 #include "chrome/browser/extensions/external_policy_loader.h" 12 #include "chrome/browser/extensions/external_policy_loader.h"
12 #include "chrome/browser/extensions/external_provider_impl.h" 13 #include "chrome/browser/extensions/external_provider_impl.h"
13 #include "chrome/browser/extensions/standard_management_policy_provider.h" 14 #include "chrome/browser/extensions/standard_management_policy_provider.h"
14 #include "chrome/browser/profiles/incognito_helpers.h" 15 #include "chrome/browser/profiles/incognito_helpers.h"
15 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/profiles/profile.h"
16 #include "components/crx_file/id_util.h" 17 #include "components/crx_file/id_util.h"
17 #include "components/keyed_service/content/browser_context_dependency_manager.h" 18 #include "components/keyed_service/content/browser_context_dependency_manager.h"
18 #include "extensions/browser/pref_names.h" 19 #include "extensions/browser/pref_names.h"
19 #include "extensions/common/url_pattern.h" 20 #include "extensions/common/url_pattern.h"
20 #include "url/gurl.h" 21 #include "url/gurl.h"
21 22
22 namespace extensions { 23 namespace extensions {
23 24
25 namespace schema_constants {
26
27 const char kAllOtherExtension[] = "*";
Joao da Silva 2014/09/18 12:08:21 Rename this to kWildcard
binjin 2014/09/18 14:37:27 Done.
28
29 const char kInstallationMode[] = "installation_mode";
30 const char kAllowed[] = "allowed";
31 const char kBlocked[] = "blocked";
32 const char kForceInstalled[] = "force_installed";
33 const char kNormalInstalled[] = "normal_installed";
34
35 const char kUpdateUrl[] = "update_url";
36 const char kInstallSources[] = "install_sources";
37 const char kAllowedTypes[] = "allowed_types";
38
39 const char kUpdateUrlPrefix[] = "update_url:";
40
41 const AllowedTypesMapType kAllowedTypesMap[] = {
42 { "extension", Manifest::TYPE_EXTENSION },
43 { "theme", Manifest::TYPE_THEME },
44 { "user_script", Manifest::TYPE_USER_SCRIPT },
45 { "hosted_app", Manifest::TYPE_HOSTED_APP },
46 { "legacy_packaged_app", Manifest::TYPE_LEGACY_PACKAGED_APP },
47 { "platform_app", Manifest::TYPE_PLATFORM_APP },
Joao da Silva 2014/09/18 12:08:21 Align the types in the same column
binjin 2014/09/18 14:37:27 Done.
48 // TODO(binjin): Add shared_module type here and update ExtensionAllowedTypes
49 // policy.
50 { NULL, Manifest::TYPE_UNKNOWN }
Joao da Silva 2014/09/18 12:08:21 Remove the NULL entry
binjin 2014/09/18 14:37:26 Done.
51 };
Joao da Silva 2014/09/18 12:08:21 Add the size constant: const size_t kAllowedTypes
binjin 2014/09/18 14:37:27 Done.
52
53 } // namespace schema_constants
54
55 bool ExtensionManagement::IndividualSettings::Parse(
56 const base::DictionaryValue* dict,
57 Scope scope) {
58 Reset();
59
60 std::string installation_mode;
61 if (dict->GetStringWithoutPathExpansion(schema_constants::kInstallationMode,
62 &installation_mode)) {
63 if (installation_mode == schema_constants::kAllowed) {
64 this->installation_mode = INSTALLATION_ALLOWED;
65 } else if (installation_mode == schema_constants::kBlocked) {
66 this->installation_mode = INSTALLATION_BLOCKED;
67 } else if (installation_mode == schema_constants::kForceInstalled) {
68 this->installation_mode = INSTALLATION_FORCED;
69 } else if (installation_mode == schema_constants::kNormalInstalled) {
70 this->installation_mode = INSTALLATION_RECOMMENDED;
71 } else {
72 LOG(WARNING) << "Invalid value for 'installation_modes'.";
Joao da Silva 2014/09/18 12:08:21 installation_mode
binjin 2014/09/18 14:37:27 Done.
73 return false;
74 }
75 }
76
77 std::string update_url;
78 if (dict->GetStringWithoutPathExpansion(schema_constants::kUpdateUrl,
79 &update_url)) {
Joao da Silva 2014/09/18 12:08:21 The update_url only matters for FORCED and RECOMME
binjin 2014/09/18 14:37:26 Done with further simplification.
80 if (scope != SCOPE_INDIVIDUAL) {
81 LOG(WARNING)
82 << "Only individual extensions are allowed to have an update URL.";
83 return false;
84 }
85 if (!GURL(update_url).is_valid()) {
86 LOG(WARNING) << "No valid update URL for this extension.";
87 return false;
88 }
89 this->update_url = update_url;
90 }
91
92 if (this->installation_mode == INSTALLATION_FORCED ||
93 this->installation_mode == INSTALLATION_RECOMMENDED) {
94 if (scope != SCOPE_INDIVIDUAL) {
95 LOG(WARNING) << "Only individual extensions are allowed to be "
96 "automatically installed.";
97 return false;
98 }
99 if (this->update_url.empty()) {
100 LOG(WARNING) << "No valid update URL for this extension.";
101 return false;
102 }
103 }
104
105 return true;
106 }
107
24 void ExtensionManagement::IndividualSettings::Reset() { 108 void ExtensionManagement::IndividualSettings::Reset() {
25 installation_mode = ExtensionManagement::INSTALLATION_ALLOWED; 109 installation_mode = ExtensionManagement::INSTALLATION_ALLOWED;
26 update_url.clear(); 110 update_url.clear();
27 } 111 }
28 112
29 ExtensionManagement::GlobalSettings::GlobalSettings() { 113 ExtensionManagement::GlobalSettings::GlobalSettings() {
30 Reset(); 114 Reset();
31 } 115 }
32 116
33 ExtensionManagement::GlobalSettings::~GlobalSettings() { 117 ExtensionManagement::GlobalSettings::~GlobalSettings() {
(...skipping 13 matching lines...) Expand all
47 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this)); 131 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this));
48 pref_change_registrar_.Add(pref_names::kInstallAllowList, 132 pref_change_registrar_.Add(pref_names::kInstallAllowList,
49 pref_change_callback); 133 pref_change_callback);
50 pref_change_registrar_.Add(pref_names::kInstallDenyList, 134 pref_change_registrar_.Add(pref_names::kInstallDenyList,
51 pref_change_callback); 135 pref_change_callback);
52 pref_change_registrar_.Add(pref_names::kInstallForceList, 136 pref_change_registrar_.Add(pref_names::kInstallForceList,
53 pref_change_callback); 137 pref_change_callback);
54 pref_change_registrar_.Add(pref_names::kAllowedInstallSites, 138 pref_change_registrar_.Add(pref_names::kAllowedInstallSites,
55 pref_change_callback); 139 pref_change_callback);
56 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); 140 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback);
141 pref_change_registrar_.Add(pref_names::kExtensionManagement,
142 pref_change_callback);
57 Refresh(); 143 Refresh();
58 provider_.reset(new StandardManagementPolicyProvider(this)); 144 provider_.reset(new StandardManagementPolicyProvider(this));
59 } 145 }
60 146
61 ExtensionManagement::~ExtensionManagement() { 147 ExtensionManagement::~ExtensionManagement() {
62 } 148 }
63 149
64 void ExtensionManagement::AddObserver(Observer* observer) { 150 void ExtensionManagement::AddObserver(Observer* observer) {
65 observer_list_.AddObserver(observer); 151 observer_list_.AddObserver(observer);
66 } 152 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 pref_names::kInstallDenyList, false, base::Value::TYPE_LIST)); 224 pref_names::kInstallDenyList, false, base::Value::TYPE_LIST));
139 const base::DictionaryValue* forced_list_pref = 225 const base::DictionaryValue* forced_list_pref =
140 static_cast<const base::DictionaryValue*>(LoadPreference( 226 static_cast<const base::DictionaryValue*>(LoadPreference(
141 pref_names::kInstallForceList, true, base::Value::TYPE_DICTIONARY)); 227 pref_names::kInstallForceList, true, base::Value::TYPE_DICTIONARY));
142 const base::ListValue* install_sources_pref = 228 const base::ListValue* install_sources_pref =
143 static_cast<const base::ListValue*>(LoadPreference( 229 static_cast<const base::ListValue*>(LoadPreference(
144 pref_names::kAllowedInstallSites, true, base::Value::TYPE_LIST)); 230 pref_names::kAllowedInstallSites, true, base::Value::TYPE_LIST));
145 const base::ListValue* allowed_types_pref = 231 const base::ListValue* allowed_types_pref =
146 static_cast<const base::ListValue*>(LoadPreference( 232 static_cast<const base::ListValue*>(LoadPreference(
147 pref_names::kAllowedTypes, true, base::Value::TYPE_LIST)); 233 pref_names::kAllowedTypes, true, base::Value::TYPE_LIST));
234 const base::DictionaryValue* dict_pref =
235 static_cast<const base::DictionaryValue*>(
236 LoadPreference(pref_names::kExtensionManagement,
237 true,
238 base::Value::TYPE_DICTIONARY));
148 239
149 // Reset all settings. 240 // Reset all settings.
150 global_settings_.Reset(); 241 global_settings_.Reset();
151 settings_by_id_.clear(); 242 settings_by_id_.clear();
152 default_settings_.Reset(); 243 default_settings_.Reset();
153 244
154 // Parse default settings. 245 // Parse default settings.
155 const base::StringValue wildcard("*"); 246 const base::StringValue wildcard("*");
156 if (denied_list_pref && 247 if (denied_list_pref &&
157 denied_list_pref->Find(wildcard) != denied_list_pref->end()) { 248 denied_list_pref->Find(wildcard) != denied_list_pref->end()) {
158 default_settings_.installation_mode = INSTALLATION_BLOCKED; 249 default_settings_.installation_mode = INSTALLATION_BLOCKED;
159 } 250 }
160 251
252 const base::DictionaryValue* subdict = NULL;
253 if (dict_pref &&
254 dict_pref->GetDictionary(schema_constants::kAllOtherExtension,
255 &subdict)) {
256 if (!default_settings_.Parse(subdict, IndividualSettings::SCOPE_DEFAULT))
257 LOG(WARNING) << "Default extension management settings parsing error.";
Joao da Silva 2014/09/18 12:08:21 Reset() default_settings_ in this case?
binjin 2014/09/18 14:37:26 Done.
258
259 // Settings from new preference have higher priority over legacy ones.
260 const base::ListValue* list_value;
Joao da Silva 2014/09/18 12:08:21 = NULL
binjin 2014/09/18 14:37:26 Done.
261 if (subdict->GetList(schema_constants::kInstallSources, &list_value))
262 install_sources_pref = list_value;
263 if (subdict->GetList(schema_constants::kAllowedTypes, &list_value))
264 allowed_types_pref = list_value;
265 }
266
161 // Parse legacy preferences. 267 // Parse legacy preferences.
162 ExtensionId id; 268 ExtensionId id;
163 269
164 if (allowed_list_pref) { 270 if (allowed_list_pref) {
165 for (base::ListValue::const_iterator it = allowed_list_pref->begin(); 271 for (base::ListValue::const_iterator it = allowed_list_pref->begin();
166 it != allowed_list_pref->end(); ++it) { 272 it != allowed_list_pref->end(); ++it) {
167 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id)) 273 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id))
168 AccessById(id)->installation_mode = INSTALLATION_ALLOWED; 274 AccessById(id)->installation_mode = INSTALLATION_ALLOWED;
169 } 275 }
170 } 276 }
(...skipping 18 matching lines...) Expand all
189 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) { 295 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) {
190 IndividualSettings* by_id = AccessById(it.key()); 296 IndividualSettings* by_id = AccessById(it.key());
191 by_id->installation_mode = INSTALLATION_FORCED; 297 by_id->installation_mode = INSTALLATION_FORCED;
192 by_id->update_url = update_url; 298 by_id->update_url = update_url;
193 } 299 }
194 } 300 }
195 } 301 }
196 302
197 if (install_sources_pref) { 303 if (install_sources_pref) {
198 global_settings_.has_restricted_install_sources = true; 304 global_settings_.has_restricted_install_sources = true;
199 std::string url_pattern;
200 for (base::ListValue::const_iterator it = install_sources_pref->begin(); 305 for (base::ListValue::const_iterator it = install_sources_pref->begin();
201 it != install_sources_pref->end(); ++it) { 306 it != install_sources_pref->end(); ++it) {
202 URLPattern entry(URLPattern::SCHEME_ALL); 307 std::string url_pattern;
203 if ((*it)->GetAsString(&url_pattern)) { 308 if ((*it)->GetAsString(&url_pattern)) {
309 URLPattern entry(URLPattern::SCHEME_ALL);
204 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { 310 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) {
205 global_settings_.install_sources.AddPattern(entry); 311 global_settings_.install_sources.AddPattern(entry);
206 } else { 312 } else {
207 LOG(WARNING) << "Invalid URL pattern in for preference " 313 LOG(WARNING) << "Invalid URL pattern in for preference "
208 << pref_names::kAllowedInstallSites << ": " 314 << pref_names::kAllowedInstallSites << ": "
209 << url_pattern << "."; 315 << url_pattern << ".";
210 } 316 }
211 } 317 }
212 } 318 }
213 } 319 }
214 320
215 if (allowed_types_pref) { 321 if (allowed_types_pref) {
216 global_settings_.has_restricted_allowed_types = true; 322 global_settings_.has_restricted_allowed_types = true;
217 for (base::ListValue::const_iterator it = allowed_types_pref->begin(); 323 for (base::ListValue::const_iterator it = allowed_types_pref->begin();
218 it != allowed_types_pref->end(); ++it) { 324 it != allowed_types_pref->end(); ++it) {
219 int int_value; 325 int int_value;
326 std::string string_value;
220 if ((*it)->GetAsInteger(&int_value) && int_value >= 0 && 327 if ((*it)->GetAsInteger(&int_value) && int_value >= 0 &&
221 int_value < Manifest::Type::NUM_LOAD_TYPES) { 328 int_value < Manifest::Type::NUM_LOAD_TYPES) {
222 global_settings_.allowed_types.push_back( 329 global_settings_.allowed_types.push_back(
223 static_cast<Manifest::Type>(int_value)); 330 static_cast<Manifest::Type>(int_value));
331 } else if ((*it)->GetAsString(&string_value)) {
332 for (const schema_constants::AllowedTypesMapType* iter =
333 schema_constants::kAllowedTypesMap;
334 iter->name;
335 ++iter) {
336 if (iter->name == string_value) {
337 global_settings_.allowed_types.push_back(iter->manifest_type);
338 break;
Joao da Silva 2014/09/18 12:08:21 Make a helper for this: bool GetManifestType(cons
binjin 2014/09/18 14:37:27 Done. I tried to avoid passing pointer here, and r
339 }
340 }
224 } 341 }
225 } 342 }
226 } 343 }
227 344
228 // TODO(binjin): Add parsing of new ExtensionManagement preference after the 345 if (dict_pref) {
229 // new ExtensionManagement policy is added. 346 // Parse new extension management preference.
347 for (base::DictionaryValue::Iterator iter(*dict_pref); !iter.IsAtEnd();
348 iter.Advance()) {
349 if (iter.key() == schema_constants::kAllOtherExtension)
350 continue;
351 if (!iter.value().GetAsDictionary(&subdict)) {
352 LOG(WARNING) << "Malformed extension management preference.";
353 continue;
354 }
355 if (!StartsWithASCII(
356 iter.key(), schema_constants::kUpdateUrlPrefix, true)) {
Joao da Silva 2014/09/18 12:08:21 if (StartsWithASCII(...)) continue;
binjin 2014/09/18 14:37:27 Done.
357 const std::string& extension_id = iter.key();
358 if (!crx_file::id_util::IdIsValid(extension_id)) {
359 LOG(WARNING) << "Malformed extension management preference.";
360 continue;
361 }
362 IndividualSettings by_id;
363 if (!by_id.Parse(subdict, IndividualSettings::SCOPE_INDIVIDUAL)) {
364 LOG(WARNING) << "Malformed extension management preference.";
365 continue;
366 } else {
367 *AccessById(extension_id) = by_id;
368 }
369 }
370 }
371 }
230 } 372 }
231 373
232 const base::Value* ExtensionManagement::LoadPreference( 374 const base::Value* ExtensionManagement::LoadPreference(
233 const char* pref_name, 375 const char* pref_name,
234 bool force_managed, 376 bool force_managed,
235 base::Value::Type expected_type) { 377 base::Value::Type expected_type) {
236 const PrefService::Preference* pref = 378 const PrefService::Preference* pref =
237 pref_service_->FindPreference(pref_name); 379 pref_service_->FindPreference(pref_name);
238 if (pref && !pref->IsDefaultValue() && 380 if (pref && !pref->IsDefaultValue() &&
239 (!force_managed || pref->IsManaged())) { 381 (!force_managed || pref->IsManaged())) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 return new ExtensionManagement( 429 return new ExtensionManagement(
288 Profile::FromBrowserContext(context)->GetPrefs()); 430 Profile::FromBrowserContext(context)->GetPrefs());
289 } 431 }
290 432
291 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( 433 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse(
292 content::BrowserContext* context) const { 434 content::BrowserContext* context) const {
293 return chrome::GetBrowserContextRedirectedInIncognito(context); 435 return chrome::GetBrowserContextRedirectedInIncognito(context);
294 } 436 }
295 437
296 } // namespace extensions 438 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698