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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 has_parent_(false) {} | 230 has_parent_(false) {} |
231 | 231 |
232 SimpleFeature::~SimpleFeature() {} | 232 SimpleFeature::~SimpleFeature() {} |
233 | 233 |
234 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) { | 234 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) { |
235 filters_.push_back(make_linked_ptr(filter.release())); | 235 filters_.push_back(make_linked_ptr(filter.release())); |
236 } | 236 } |
237 | 237 |
238 std::string SimpleFeature::Parse(const base::DictionaryValue* value) { | 238 std::string SimpleFeature::Parse(const base::DictionaryValue* value) { |
239 ParseURLPatterns(value, "matches", &matches_); | 239 ParseURLPatterns(value, "matches", &matches_); |
240 ParseSet(value, "blacklist", &blacklist_); | |
240 ParseSet(value, "whitelist", &whitelist_); | 241 ParseSet(value, "whitelist", &whitelist_); |
241 ParseSet(value, "dependencies", &dependencies_); | 242 ParseSet(value, "dependencies", &dependencies_); |
242 ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_, | 243 ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_, |
243 g_mappings.Get().extension_types); | 244 g_mappings.Get().extension_types); |
244 ParseEnumSet<Context>(value, "contexts", &contexts_, | 245 ParseEnumSet<Context>(value, "contexts", &contexts_, |
245 g_mappings.Get().contexts); | 246 g_mappings.Get().contexts); |
246 ParseEnum<Location>(value, "location", &location_, | 247 ParseEnum<Location>(value, "location", &location_, |
247 g_mappings.Get().locations); | 248 g_mappings.Get().locations); |
248 ParseEnumSet<Platform>(value, "platforms", &platforms_, | 249 ParseEnumSet<Platform>(value, "platforms", &platforms_, |
249 g_mappings.Get().platforms); | 250 g_mappings.Get().platforms); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 if (!extension_types_.empty() && | 286 if (!extension_types_.empty() && |
286 extension_types_.find(type_to_check) == extension_types_.end()) { | 287 extension_types_.find(type_to_check) == extension_types_.end()) { |
287 return CreateAvailability(INVALID_TYPE, type); | 288 return CreateAvailability(INVALID_TYPE, type); |
288 } | 289 } |
289 | 290 |
290 // Component extensions can access any feature. | 291 // Component extensions can access any feature. |
291 // TODO(kalman/asargent): Should this match EXTERNAL_COMPONENT too? | 292 // TODO(kalman/asargent): Should this match EXTERNAL_COMPONENT too? |
292 if (location == Manifest::COMPONENT) | 293 if (location == Manifest::COMPONENT) |
293 return CreateAvailability(IS_AVAILABLE, type); | 294 return CreateAvailability(IS_AVAILABLE, type); |
294 | 295 |
296 if (!blacklist_.empty()) { | |
not at google - send to devlin
2014/05/01 20:55:06
the !blacklist_.empty() check isn't really necessa
benwells
2014/05/02 00:58:52
Done.
| |
297 if (IsIdInBlacklist(extension_id)) | |
298 return CreateAvailability(FOUND_IN_BLACKLIST, type); | |
299 } | |
300 | |
295 if (!whitelist_.empty()) { | 301 if (!whitelist_.empty()) { |
296 if (!IsIdInWhitelist(extension_id)) { | 302 if (!IsIdInWhitelist(extension_id)) { |
297 // TODO(aa): This is gross. There should be a better way to test the | 303 // TODO(aa): This is gross. There should be a better way to test the |
298 // whitelist. | 304 // whitelist. |
299 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 305 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
300 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) | 306 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) |
301 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); | 307 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); |
302 | 308 |
303 std::string whitelist_switch_value = | 309 std::string whitelist_switch_value = |
304 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 310 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
368 | 374 |
369 std::string SimpleFeature::GetAvailabilityMessage( | 375 std::string SimpleFeature::GetAvailabilityMessage( |
370 AvailabilityResult result, | 376 AvailabilityResult result, |
371 Manifest::Type type, | 377 Manifest::Type type, |
372 const GURL& url, | 378 const GURL& url, |
373 Context context) const { | 379 Context context) const { |
374 switch (result) { | 380 switch (result) { |
375 case IS_AVAILABLE: | 381 case IS_AVAILABLE: |
376 return std::string(); | 382 return std::string(); |
377 case NOT_FOUND_IN_WHITELIST: | 383 case NOT_FOUND_IN_WHITELIST: |
384 case FOUND_IN_BLACKLIST: | |
378 return base::StringPrintf( | 385 return base::StringPrintf( |
379 "'%s' is not allowed for specified extension ID.", | 386 "'%s' is not allowed for specified extension ID.", |
380 name().c_str()); | 387 name().c_str()); |
381 case INVALID_URL: | 388 case INVALID_URL: |
382 return base::StringPrintf("'%s' is not allowed on %s.", | 389 return base::StringPrintf("'%s' is not allowed on %s.", |
383 name().c_str(), url.spec().c_str()); | 390 name().c_str(), url.spec().c_str()); |
384 case INVALID_TYPE: | 391 case INVALID_TYPE: |
385 return base::StringPrintf( | 392 return base::StringPrintf( |
386 "'%s' is only allowed for %s, but this is a %s.", | 393 "'%s' is only allowed for %s, but this is a %s.", |
387 name().c_str(), | 394 name().c_str(), |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 std::set<Feature::Context>* SimpleFeature::GetContexts() { | 466 std::set<Feature::Context>* SimpleFeature::GetContexts() { |
460 return &contexts_; | 467 return &contexts_; |
461 } | 468 } |
462 | 469 |
463 bool SimpleFeature::IsInternal() const { | 470 bool SimpleFeature::IsInternal() const { |
464 return false; | 471 return false; |
465 } | 472 } |
466 | 473 |
467 bool SimpleFeature::IsBlockedInServiceWorker() const { return false; } | 474 bool SimpleFeature::IsBlockedInServiceWorker() const { return false; } |
468 | 475 |
476 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { | |
477 return IsIdInList(extension_id, blacklist_); | |
478 } | |
479 | |
469 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { | 480 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { |
470 return IsIdInWhitelist(extension_id, whitelist_); | 481 return IsIdInList(extension_id, whitelist_); |
471 } | 482 } |
472 | 483 |
473 // static | 484 // static |
474 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id, | 485 bool SimpleFeature::IsIdInList(const std::string& extension_id, |
475 const std::set<std::string>& whitelist) { | 486 const std::set<std::string>& list) { |
476 // Belt-and-suspenders philosophy here. We should be pretty confident by this | 487 // Belt-and-suspenders philosophy here. We should be pretty confident by this |
477 // point that we've validated the extension ID format, but in case something | 488 // point that we've validated the extension ID format, but in case something |
478 // slips through, we avoid a class of attack where creative ID manipulation | 489 // slips through, we avoid a class of attack where creative ID manipulation |
479 // leads to hash collisions. | 490 // leads to hash collisions. |
480 if (extension_id.length() != 32) // 128 bits / 4 = 32 mpdecimal characters | 491 if (extension_id.length() != 32) // 128 bits / 4 = 32 mpdecimal characters |
481 return false; | 492 return false; |
482 | 493 |
483 if (whitelist.find(extension_id) != whitelist.end() || | 494 if (list.find(extension_id) != list.end() || |
484 whitelist.find(HashExtensionId(extension_id)) != whitelist.end()) { | 495 list.find(HashExtensionId(extension_id)) != list.end()) { |
485 return true; | 496 return true; |
486 } | 497 } |
487 | 498 |
488 return false; | 499 return false; |
489 } | 500 } |
490 | 501 |
491 bool SimpleFeature::MatchesManifestLocation( | 502 bool SimpleFeature::MatchesManifestLocation( |
492 Manifest::Location manifest_location) const { | 503 Manifest::Location manifest_location) const { |
493 switch (location_) { | 504 switch (location_) { |
494 case SimpleFeature::UNSPECIFIED_LOCATION: | 505 case SimpleFeature::UNSPECIFIED_LOCATION: |
495 return true; | 506 return true; |
496 case SimpleFeature::COMPONENT_LOCATION: | 507 case SimpleFeature::COMPONENT_LOCATION: |
497 // TODO(kalman/asargent): Should this include EXTERNAL_COMPONENT too? | 508 // TODO(kalman/asargent): Should this include EXTERNAL_COMPONENT too? |
498 return manifest_location == Manifest::COMPONENT; | 509 return manifest_location == Manifest::COMPONENT; |
499 case SimpleFeature::POLICY_LOCATION: | 510 case SimpleFeature::POLICY_LOCATION: |
500 return manifest_location == Manifest::EXTERNAL_POLICY || | 511 return manifest_location == Manifest::EXTERNAL_POLICY || |
501 manifest_location == Manifest::EXTERNAL_POLICY_DOWNLOAD; | 512 manifest_location == Manifest::EXTERNAL_POLICY_DOWNLOAD; |
502 } | 513 } |
503 NOTREACHED(); | 514 NOTREACHED(); |
504 return false; | 515 return false; |
505 } | 516 } |
506 | 517 |
507 } // namespace extensions | 518 } // namespace extensions |
OLD | NEW |