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

Side by Side Diff: extensions/common/features/simple_feature.cc

Issue 241673002: Support a "policy" extension location in extension features files. At the same (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: different approach (yoz) Created 6 years, 8 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 | Annotate | Revision Log
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 "extensions/common/features/simple_feature.h" 5 #include "extensions/common/features/simple_feature.h"
6 6
7 #include <map> 7 #include <map>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/lazy_instance.h"
12 #include "base/sha1.h" 11 #include "base/sha1.h"
13 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
16 #include "extensions/common/switches.h" 15 #include "extensions/common/switches.h"
17 16
18 namespace extensions { 17 namespace extensions {
19 18
20 namespace { 19 namespace {
21 20
22 struct Mappings {
23 Mappings() {
24 extension_types["extension"] = Manifest::TYPE_EXTENSION;
25 extension_types["theme"] = Manifest::TYPE_THEME;
26 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP;
27 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP;
28 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP;
29 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE;
30
31 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT;
32 contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT;
33 contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT;
34 contexts["web_page"] = Feature::WEB_PAGE_CONTEXT;
35 contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT;
36
37 locations["component"] = Feature::COMPONENT_LOCATION;
38
39 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM;
40 platforms["linux"] = Feature::LINUX_PLATFORM;
41 platforms["mac"] = Feature::MACOSX_PLATFORM;
42 platforms["win"] = Feature::WIN_PLATFORM;
43 }
44
45 std::map<std::string, Manifest::Type> extension_types;
46 std::map<std::string, Feature::Context> contexts;
47 std::map<std::string, Feature::Location> locations;
48 std::map<std::string, Feature::Platform> platforms;
49 };
50
51 base::LazyInstance<Mappings> g_mappings = LAZY_INSTANCE_INITIALIZER;
52
53 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? 21 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff?
54 22
55 void ParseSet(const base::DictionaryValue* value, 23 void ParseSet(const base::DictionaryValue* value,
56 const std::string& property, 24 const std::string& property,
57 std::set<std::string>* set) { 25 std::set<std::string>* set) {
58 const base::ListValue* list_value = NULL; 26 const base::ListValue* list_value = NULL;
59 if (!value->GetList(property, &list_value)) 27 if (!value->GetList(property, &list_value))
60 return; 28 return;
61 29
62 set->clear(); 30 set->clear();
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 } 175 }
208 176
209 std::string HashExtensionId(const std::string& extension_id) { 177 std::string HashExtensionId(const std::string& extension_id) {
210 const std::string id_hash = base::SHA1HashString(extension_id); 178 const std::string id_hash = base::SHA1HashString(extension_id);
211 DCHECK(id_hash.length() == base::kSHA1Length); 179 DCHECK(id_hash.length() == base::kSHA1Length);
212 return base::HexEncode(id_hash.c_str(), id_hash.length()); 180 return base::HexEncode(id_hash.c_str(), id_hash.length());
213 } 181 }
214 182
215 } // namespace 183 } // namespace
216 184
185 struct SimpleFeature::Mappings {
186 Mappings() {
187 extension_types["extension"] = Manifest::TYPE_EXTENSION;
188 extension_types["theme"] = Manifest::TYPE_THEME;
189 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP;
190 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP;
191 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP;
192 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE;
193
194 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT;
195 contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT;
196 contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT;
197 contexts["web_page"] = Feature::WEB_PAGE_CONTEXT;
198 contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT;
199
200 locations["component"] = SimpleFeature::COMPONENT_LOCATION;
201 locations["policy"] = SimpleFeature::POLICY_LOCATION;
202
203 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM;
204 platforms["linux"] = Feature::LINUX_PLATFORM;
205 platforms["mac"] = Feature::MACOSX_PLATFORM;
206 platforms["win"] = Feature::WIN_PLATFORM;
207 }
208
209 std::map<std::string, Manifest::Type> extension_types;
210 std::map<std::string, Feature::Context> contexts;
211 std::map<std::string, SimpleFeature::Location> locations;
212 std::map<std::string, Feature::Platform> platforms;
213 };
214
215 // static
216 base::LazyInstance<SimpleFeature::Mappings> SimpleFeature::g_mappings =
217 LAZY_INSTANCE_INITIALIZER;
218
217 SimpleFeature::SimpleFeature() 219 SimpleFeature::SimpleFeature()
218 : location_(UNSPECIFIED_LOCATION), 220 : location_(UNSPECIFIED_LOCATION),
219 min_manifest_version_(0), 221 min_manifest_version_(0),
220 max_manifest_version_(0), 222 max_manifest_version_(0),
221 has_parent_(false) {} 223 has_parent_(false) {}
222 224
223 SimpleFeature::~SimpleFeature() {} 225 SimpleFeature::~SimpleFeature() {}
224 226
225 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) { 227 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) {
226 filters_.push_back(make_linked_ptr(filter.release())); 228 filters_.push_back(make_linked_ptr(filter.release()));
(...skipping 30 matching lines...) Expand all
257 return result; 259 return result;
258 } 260 }
259 } 261 }
260 262
261 return std::string(); 263 return std::string();
262 } 264 }
263 265
264 Feature::Availability SimpleFeature::IsAvailableToManifest( 266 Feature::Availability SimpleFeature::IsAvailableToManifest(
265 const std::string& extension_id, 267 const std::string& extension_id,
266 Manifest::Type type, 268 Manifest::Type type,
267 Location location, 269 Manifest::Location location,
268 int manifest_version, 270 int manifest_version,
269 Platform platform) const { 271 Platform platform) const {
270 // Check extension type first to avoid granting platform app permissions 272 // Check extension type first to avoid granting platform app permissions
271 // to component extensions. 273 // to component extensions.
272 // HACK(kalman): user script -> extension. Solve this in a more generic way 274 // HACK(kalman): user script -> extension. Solve this in a more generic way
273 // when we compile feature files. 275 // when we compile feature files.
274 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? 276 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ?
275 Manifest::TYPE_EXTENSION : type; 277 Manifest::TYPE_EXTENSION : type;
276 if (!extension_types_.empty() && 278 if (!extension_types_.empty() &&
277 extension_types_.find(type_to_check) == extension_types_.end()) { 279 extension_types_.find(type_to_check) == extension_types_.end()) {
278 return CreateAvailability(INVALID_TYPE, type); 280 return CreateAvailability(INVALID_TYPE, type);
279 } 281 }
280 282
281 // Component extensions can access any feature. 283 // Component extensions can access any feature.
282 if (location == COMPONENT_LOCATION) 284 // TODO(kalman/asargent): Should this match EXTERNAL_COMPONENT too?
285 if (location == Manifest::COMPONENT)
283 return CreateAvailability(IS_AVAILABLE, type); 286 return CreateAvailability(IS_AVAILABLE, type);
284 287
285 if (!whitelist_.empty()) { 288 if (!whitelist_.empty()) {
286 if (!IsIdInWhitelist(extension_id)) { 289 if (!IsIdInWhitelist(extension_id)) {
287 // TODO(aa): This is gross. There should be a better way to test the 290 // TODO(aa): This is gross. There should be a better way to test the
288 // whitelist. 291 // whitelist.
289 CommandLine* command_line = CommandLine::ForCurrentProcess(); 292 CommandLine* command_line = CommandLine::ForCurrentProcess();
290 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) 293 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID))
291 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); 294 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type);
292 295
293 std::string whitelist_switch_value = 296 std::string whitelist_switch_value =
294 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 297 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
295 switches::kWhitelistedExtensionID); 298 switches::kWhitelistedExtensionID);
296 if (extension_id != whitelist_switch_value) 299 if (extension_id != whitelist_switch_value)
297 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); 300 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type);
298 } 301 }
299 } 302 }
300 303
301 if (location_ != UNSPECIFIED_LOCATION && location_ != location) 304 if (!MatchesManifestLocation(location))
302 return CreateAvailability(INVALID_LOCATION, type); 305 return CreateAvailability(INVALID_LOCATION, type);
303 306
304 if (!platforms_.empty() && 307 if (!platforms_.empty() &&
305 platforms_.find(platform) == platforms_.end()) 308 platforms_.find(platform) == platforms_.end())
306 return CreateAvailability(INVALID_PLATFORM, type); 309 return CreateAvailability(INVALID_PLATFORM, type);
307 310
308 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) 311 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_)
309 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); 312 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type);
310 313
311 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) 314 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_)
(...skipping 10 matching lines...) Expand all
322 325
323 return CreateAvailability(IS_AVAILABLE, type); 326 return CreateAvailability(IS_AVAILABLE, type);
324 } 327 }
325 328
326 Feature::Availability SimpleFeature::IsAvailableToContext( 329 Feature::Availability SimpleFeature::IsAvailableToContext(
327 const Extension* extension, 330 const Extension* extension,
328 SimpleFeature::Context context, 331 SimpleFeature::Context context,
329 const GURL& url, 332 const GURL& url,
330 SimpleFeature::Platform platform) const { 333 SimpleFeature::Platform platform) const {
331 if (extension) { 334 if (extension) {
332 Availability result = IsAvailableToManifest( 335 Availability result = IsAvailableToManifest(extension->id(),
333 extension->id(), 336 extension->GetType(),
334 extension->GetType(), 337 extension->location(),
335 ConvertLocation(extension->location()), 338 extension->manifest_version(),
336 extension->manifest_version(), 339 platform);
337 platform);
338 if (!result.is_available()) 340 if (!result.is_available())
339 return result; 341 return result;
340 } 342 }
341 343
342 if (!contexts_.empty() && contexts_.find(context) == contexts_.end()) 344 if (!contexts_.empty() && contexts_.find(context) == contexts_.end())
343 return CreateAvailability(INVALID_CONTEXT, context); 345 return CreateAvailability(INVALID_CONTEXT, context);
344 346
345 if (!matches_.is_empty() && !matches_.MatchesURL(url)) 347 if (!matches_.is_empty() && !matches_.MatchesURL(url))
346 return CreateAvailability(INVALID_URL, url); 348 return CreateAvailability(INVALID_URL, url);
347 349
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 return false; 474 return false;
473 475
474 if (whitelist.find(extension_id) != whitelist.end() || 476 if (whitelist.find(extension_id) != whitelist.end() ||
475 whitelist.find(HashExtensionId(extension_id)) != whitelist.end()) { 477 whitelist.find(HashExtensionId(extension_id)) != whitelist.end()) {
476 return true; 478 return true;
477 } 479 }
478 480
479 return false; 481 return false;
480 } 482 }
481 483
484 bool SimpleFeature::MatchesManifestLocation(
485 Manifest::Location manifest_location) const {
486 switch (location_) {
487 case SimpleFeature::UNSPECIFIED_LOCATION:
488 return true;
489 case SimpleFeature::COMPONENT_LOCATION:
490 return manifest_location == Manifest::COMPONENT ||
491 manifest_location == Manifest::EXTERNAL_COMPONENT;
492 case SimpleFeature::POLICY_LOCATION:
493 return manifest_location == Manifest::EXTERNAL_POLICY ||
494 manifest_location == Manifest::EXTERNAL_POLICY_DOWNLOAD;
495 }
496 NOTREACHED();
497 return false;
498 }
499
482 } // namespace extensions 500 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698