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 "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" |
(...skipping 16 matching lines...) Expand all Loading... |
27 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; | 27 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; |
28 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; | 28 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; |
29 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; | 29 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; |
30 | 30 |
31 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT; | 31 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT; |
32 contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT; | 32 contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT; |
33 contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT; | 33 contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT; |
34 contexts["web_page"] = Feature::WEB_PAGE_CONTEXT; | 34 contexts["web_page"] = Feature::WEB_PAGE_CONTEXT; |
35 contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT; | 35 contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT; |
36 | 36 |
37 locations["component"] = Feature::COMPONENT_LOCATION; | 37 locations["component"] = SimpleFeature::COMPONENT_LOCATION; |
| 38 locations["policy"] = SimpleFeature::POLICY_LOCATION; |
38 | 39 |
39 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; | 40 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; |
40 platforms["linux"] = Feature::LINUX_PLATFORM; | 41 platforms["linux"] = Feature::LINUX_PLATFORM; |
41 platforms["mac"] = Feature::MACOSX_PLATFORM; | 42 platforms["mac"] = Feature::MACOSX_PLATFORM; |
42 platforms["win"] = Feature::WIN_PLATFORM; | 43 platforms["win"] = Feature::WIN_PLATFORM; |
43 } | 44 } |
44 | 45 |
45 std::map<std::string, Manifest::Type> extension_types; | 46 std::map<std::string, Manifest::Type> extension_types; |
46 std::map<std::string, Feature::Context> contexts; | 47 std::map<std::string, Feature::Context> contexts; |
47 std::map<std::string, Feature::Location> locations; | 48 std::map<std::string, SimpleFeature::Location> locations; |
48 std::map<std::string, Feature::Platform> platforms; | 49 std::map<std::string, Feature::Platform> platforms; |
49 }; | 50 }; |
50 | 51 |
51 base::LazyInstance<Mappings> g_mappings = LAZY_INSTANCE_INITIALIZER; | 52 base::LazyInstance<Mappings> g_mappings = LAZY_INSTANCE_INITIALIZER; |
52 | 53 |
53 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? | 54 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? |
54 | 55 |
55 void ParseSet(const base::DictionaryValue* value, | 56 void ParseSet(const base::DictionaryValue* value, |
56 const std::string& property, | 57 const std::string& property, |
57 std::set<std::string>* set) { | 58 std::set<std::string>* set) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 return result; | 258 return result; |
258 } | 259 } |
259 } | 260 } |
260 | 261 |
261 return std::string(); | 262 return std::string(); |
262 } | 263 } |
263 | 264 |
264 Feature::Availability SimpleFeature::IsAvailableToManifest( | 265 Feature::Availability SimpleFeature::IsAvailableToManifest( |
265 const std::string& extension_id, | 266 const std::string& extension_id, |
266 Manifest::Type type, | 267 Manifest::Type type, |
267 Location location, | 268 Manifest::Location location, |
268 int manifest_version, | 269 int manifest_version, |
269 Platform platform) const { | 270 Platform platform) const { |
270 // Check extension type first to avoid granting platform app permissions | 271 // Check extension type first to avoid granting platform app permissions |
271 // to component extensions. | 272 // to component extensions. |
272 // HACK(kalman): user script -> extension. Solve this in a more generic way | 273 // HACK(kalman): user script -> extension. Solve this in a more generic way |
273 // when we compile feature files. | 274 // when we compile feature files. |
274 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? | 275 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? |
275 Manifest::TYPE_EXTENSION : type; | 276 Manifest::TYPE_EXTENSION : type; |
276 if (!extension_types_.empty() && | 277 if (!extension_types_.empty() && |
277 extension_types_.find(type_to_check) == extension_types_.end()) { | 278 extension_types_.find(type_to_check) == extension_types_.end()) { |
278 return CreateAvailability(INVALID_TYPE, type); | 279 return CreateAvailability(INVALID_TYPE, type); |
279 } | 280 } |
280 | 281 |
281 // Component extensions can access any feature. | 282 // Component extensions can access any feature. |
282 if (location == COMPONENT_LOCATION) | 283 // TODO(kalman/asargent): Should this match EXTERNAL_COMPONENT too? |
| 284 if (location == Manifest::COMPONENT) |
283 return CreateAvailability(IS_AVAILABLE, type); | 285 return CreateAvailability(IS_AVAILABLE, type); |
284 | 286 |
285 if (!whitelist_.empty()) { | 287 if (!whitelist_.empty()) { |
286 if (!IsIdInWhitelist(extension_id)) { | 288 if (!IsIdInWhitelist(extension_id)) { |
287 // TODO(aa): This is gross. There should be a better way to test the | 289 // TODO(aa): This is gross. There should be a better way to test the |
288 // whitelist. | 290 // whitelist. |
289 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 291 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
290 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) | 292 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) |
291 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); | 293 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); |
292 | 294 |
293 std::string whitelist_switch_value = | 295 std::string whitelist_switch_value = |
294 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 296 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
295 switches::kWhitelistedExtensionID); | 297 switches::kWhitelistedExtensionID); |
296 if (extension_id != whitelist_switch_value) | 298 if (extension_id != whitelist_switch_value) |
297 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); | 299 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); |
298 } | 300 } |
299 } | 301 } |
300 | 302 |
301 if (location_ != UNSPECIFIED_LOCATION && location_ != location) | 303 if (!MatchesManifestLocation(location)) |
302 return CreateAvailability(INVALID_LOCATION, type); | 304 return CreateAvailability(INVALID_LOCATION, type); |
303 | 305 |
304 if (!platforms_.empty() && | 306 if (!platforms_.empty() && |
305 platforms_.find(platform) == platforms_.end()) | 307 platforms_.find(platform) == platforms_.end()) |
306 return CreateAvailability(INVALID_PLATFORM, type); | 308 return CreateAvailability(INVALID_PLATFORM, type); |
307 | 309 |
308 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) | 310 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) |
309 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); | 311 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); |
310 | 312 |
311 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) | 313 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) |
(...skipping 10 matching lines...) Expand all Loading... |
322 | 324 |
323 return CreateAvailability(IS_AVAILABLE, type); | 325 return CreateAvailability(IS_AVAILABLE, type); |
324 } | 326 } |
325 | 327 |
326 Feature::Availability SimpleFeature::IsAvailableToContext( | 328 Feature::Availability SimpleFeature::IsAvailableToContext( |
327 const Extension* extension, | 329 const Extension* extension, |
328 SimpleFeature::Context context, | 330 SimpleFeature::Context context, |
329 const GURL& url, | 331 const GURL& url, |
330 SimpleFeature::Platform platform) const { | 332 SimpleFeature::Platform platform) const { |
331 if (extension) { | 333 if (extension) { |
332 Availability result = IsAvailableToManifest( | 334 Availability result = IsAvailableToManifest(extension->id(), |
333 extension->id(), | 335 extension->GetType(), |
334 extension->GetType(), | 336 extension->location(), |
335 ConvertLocation(extension->location()), | 337 extension->manifest_version(), |
336 extension->manifest_version(), | 338 platform); |
337 platform); | |
338 if (!result.is_available()) | 339 if (!result.is_available()) |
339 return result; | 340 return result; |
340 } | 341 } |
341 | 342 |
342 if (!contexts_.empty() && contexts_.find(context) == contexts_.end()) | 343 if (!contexts_.empty() && contexts_.find(context) == contexts_.end()) |
343 return CreateAvailability(INVALID_CONTEXT, context); | 344 return CreateAvailability(INVALID_CONTEXT, context); |
344 | 345 |
345 if (!matches_.is_empty() && !matches_.MatchesURL(url)) | 346 if (!matches_.is_empty() && !matches_.MatchesURL(url)) |
346 return CreateAvailability(INVALID_URL, url); | 347 return CreateAvailability(INVALID_URL, url); |
347 | 348 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 return false; | 473 return false; |
473 | 474 |
474 if (whitelist.find(extension_id) != whitelist.end() || | 475 if (whitelist.find(extension_id) != whitelist.end() || |
475 whitelist.find(HashExtensionId(extension_id)) != whitelist.end()) { | 476 whitelist.find(HashExtensionId(extension_id)) != whitelist.end()) { |
476 return true; | 477 return true; |
477 } | 478 } |
478 | 479 |
479 return false; | 480 return false; |
480 } | 481 } |
481 | 482 |
| 483 bool SimpleFeature::MatchesManifestLocation( |
| 484 Manifest::Location manifest_location) const { |
| 485 switch (location_) { |
| 486 case SimpleFeature::UNSPECIFIED_LOCATION: |
| 487 return true; |
| 488 case SimpleFeature::COMPONENT_LOCATION: |
| 489 // TODO(kalman/asargent): Should this include EXTERNAL_COMPONENT too? |
| 490 return manifest_location == Manifest::COMPONENT; |
| 491 case SimpleFeature::POLICY_LOCATION: |
| 492 return manifest_location == Manifest::EXTERNAL_POLICY || |
| 493 manifest_location == Manifest::EXTERNAL_POLICY_DOWNLOAD; |
| 494 } |
| 495 NOTREACHED(); |
| 496 return false; |
| 497 } |
| 498 |
482 } // namespace extensions | 499 } // namespace extensions |
OLD | NEW |