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

Side by Side Diff: chrome/common/extensions/extension.cc

Issue 14651017: Move RuntimeData and related permissions out of Extension class (Closed) Base URL: http://git.chromium.org/chromium/src.git@dc_unref_permissions
Patch Set: Latest master Created 7 years, 7 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
« no previous file with comments | « chrome/common/extensions/extension.h ('k') | chrome/common/extensions/extension_messages.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/common/extensions/extension.h" 5 #include "chrome/common/extensions/extension.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 current_whitelist->push_back(*it); 398 current_whitelist->push_back(*it);
399 } 399 }
400 } 400 }
401 401
402 // static 402 // static
403 const Extension::ScriptingWhitelist* Extension::GetScriptingWhitelist() { 403 const Extension::ScriptingWhitelist* Extension::GetScriptingWhitelist() {
404 return ExtensionConfig::GetInstance()->whitelist(); 404 return ExtensionConfig::GetInstance()->whitelist();
405 } 405 }
406 406
407 bool Extension::HasAPIPermission(APIPermission::ID permission) const { 407 bool Extension::HasAPIPermission(APIPermission::ID permission) const {
408 base::AutoLock auto_lock(runtime_data_lock_); 408 return PermissionsData::HasAPIPermission(this, permission);
409 return runtime_data_.GetActivePermissions()->HasAPIPermission(permission);
410 } 409 }
411 410
412 bool Extension::HasAPIPermission(const std::string& function_name) const { 411 bool Extension::HasAPIPermission(const std::string& function_name) const {
413 base::AutoLock auto_lock(runtime_data_lock_); 412 return PermissionsData::HasAPIPermission(this, function_name);
414 return runtime_data_.GetActivePermissions()->
415 HasAccessToFunction(function_name, true);
416 }
417
418 bool Extension::HasAPIPermissionForTab(int tab_id,
419 APIPermission::ID permission) const {
420 base::AutoLock auto_lock(runtime_data_lock_);
421 if (runtime_data_.GetActivePermissions()->HasAPIPermission(permission))
422 return true;
423 scoped_refptr<const PermissionSet> tab_specific_permissions =
424 runtime_data_.GetTabSpecificPermissions(tab_id);
425 return tab_specific_permissions.get() &&
426 tab_specific_permissions->HasAPIPermission(permission);
427 }
428
429 bool Extension::CheckAPIPermissionWithParam(APIPermission::ID permission,
430 const APIPermission::CheckParam* param) const {
431 base::AutoLock auto_lock(runtime_data_lock_);
432 return runtime_data_.GetActivePermissions()->
433 CheckAPIPermissionWithParam(permission, param);
434 }
435
436 const URLPatternSet& Extension::GetEffectiveHostPermissions() const {
437 base::AutoLock auto_lock(runtime_data_lock_);
438 return runtime_data_.GetActivePermissions()->effective_hosts();
439 }
440
441 bool Extension::CanSilentlyIncreasePermissions() const {
442 return location() != Manifest::INTERNAL;
443 }
444
445 bool Extension::HasHostPermission(const GURL& url) const {
446 base::AutoLock auto_lock(runtime_data_lock_);
447 return runtime_data_.GetActivePermissions()->
448 HasExplicitAccessToOrigin(url);
449 }
450
451 bool Extension::HasEffectiveAccessToAllHosts() const {
452 base::AutoLock auto_lock(runtime_data_lock_);
453 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts();
454 }
455
456 bool Extension::HasFullPermissions() const {
457 base::AutoLock auto_lock(runtime_data_lock_);
458 return runtime_data_.GetActivePermissions()->HasEffectiveFullAccess();
459 }
460
461 PermissionMessages Extension::GetPermissionMessages() const {
462 base::AutoLock auto_lock(runtime_data_lock_);
463 if (IsTrustedId(id())) {
464 return PermissionMessages();
465 } else {
466 return runtime_data_.GetActivePermissions()->GetPermissionMessages(
467 GetType());
468 }
469 }
470
471 std::vector<string16> Extension::GetPermissionMessageStrings() const {
472 base::AutoLock auto_lock(runtime_data_lock_);
473 if (IsTrustedId(id()))
474 return std::vector<string16>();
475 else
476 return runtime_data_.GetActivePermissions()->GetWarningMessages(GetType());
477 }
478
479 bool Extension::ShouldSkipPermissionWarnings() const {
480 return IsTrustedId(id());
481 }
482
483 void Extension::SetActivePermissions(const PermissionSet* permissions) const {
484 base::AutoLock auto_lock(runtime_data_lock_);
485 runtime_data_.SetActivePermissions(permissions);
486 } 413 }
487 414
488 scoped_refptr<const PermissionSet> Extension::GetActivePermissions() const { 415 scoped_refptr<const PermissionSet> Extension::GetActivePermissions() const {
489 base::AutoLock auto_lock(runtime_data_lock_); 416 return PermissionsData::GetActivePermissions(this);
490 return runtime_data_.GetActivePermissions();
491 } 417 }
492 418
493 bool Extension::ShowConfigureContextMenus() const { 419 bool Extension::ShowConfigureContextMenus() const {
494 // Don't show context menu for component extensions. We might want to show 420 // Don't show context menu for component extensions. We might want to show
495 // options for component extension button but now there is no component 421 // options for component extension button but now there is no component
496 // extension with options. All other menu items like uninstall have 422 // extension with options. All other menu items like uninstall have
497 // no sense for component extensions. 423 // no sense for component extensions.
498 return location() != Manifest::COMPONENT; 424 return location() != Manifest::COMPONENT;
499 } 425 }
500 426
501 GURL Extension::GetFullLaunchURL() const { 427 GURL Extension::GetFullLaunchURL() const {
502 return launch_local_path().empty() ? GURL(launch_web_url()) : 428 return launch_local_path().empty() ? GURL(launch_web_url()) :
503 url().Resolve(launch_local_path()); 429 url().Resolve(launch_local_path());
504 } 430 }
505 431
506 bool Extension::CanExecuteScriptOnPage(const GURL& document_url,
507 const GURL& top_frame_url,
508 int tab_id,
509 const UserScript* script,
510 std::string* error) const {
511 base::AutoLock auto_lock(runtime_data_lock_);
512 // The gallery is special-cased as a restricted URL for scripting to prevent
513 // access to special JS bindings we expose to the gallery (and avoid things
514 // like extensions removing the "report abuse" link).
515 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing
516 // against the store app extent?
517 GURL store_url(extension_urls::GetWebstoreLaunchURL());
518 if ((document_url.host() == store_url.host()) &&
519 !CanExecuteScriptEverywhere() &&
520 !CommandLine::ForCurrentProcess()->HasSwitch(
521 switches::kAllowScriptingGallery)) {
522 if (error)
523 *error = errors::kCannotScriptGallery;
524 return false;
525 }
526
527 if (!CommandLine::ForCurrentProcess()->HasSwitch(
528 switches::kExtensionsOnChromeURLs)) {
529 if (document_url.SchemeIs(chrome::kChromeUIScheme) &&
530 !CanExecuteScriptEverywhere()) {
531 if (error)
532 *error = errors::kCannotAccessChromeUrl;
533 return false;
534 }
535 }
536
537 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) &&
538 top_frame_url.GetOrigin() !=
539 GetBaseURLFromExtensionId(id()).GetOrigin() &&
540 !CanExecuteScriptEverywhere()) {
541 if (error)
542 *error = errors::kCannotAccessExtensionUrl;
543 return false;
544 }
545
546 // If a tab ID is specified, try the tab-specific permissions.
547 if (tab_id >= 0) {
548 scoped_refptr<const PermissionSet> tab_permissions =
549 runtime_data_.GetTabSpecificPermissions(tab_id);
550 if (tab_permissions.get() &&
551 tab_permissions->explicit_hosts().MatchesSecurityOrigin(document_url)) {
552 return true;
553 }
554 }
555
556 bool can_access = false;
557
558 if (script) {
559 // If a script is specified, use its matches.
560 can_access = script->MatchesURL(document_url);
561 } else {
562 // Otherwise, see if this extension has permission to execute script
563 // programmatically on pages.
564 can_access = runtime_data_.GetActivePermissions()->
565 HasExplicitAccessToOrigin(document_url);
566 }
567
568 if (!can_access && error) {
569 *error = ErrorUtils::FormatErrorMessage(errors::kCannotAccessPage,
570 document_url.spec());
571 }
572
573 return can_access;
574 }
575
576 bool Extension::CanExecuteScriptEverywhere() const {
577 if (location() == Manifest::COMPONENT)
578 return true;
579
580 ScriptingWhitelist* whitelist = ExtensionConfig::GetInstance()->whitelist();
581
582 for (ScriptingWhitelist::const_iterator it = whitelist->begin();
583 it != whitelist->end(); ++it) {
584 if (id() == *it) {
585 return true;
586 }
587 }
588
589 return false;
590 }
591
592 bool Extension::CanCaptureVisiblePage(const GURL& page_url,
593 int tab_id,
594 std::string* error) const {
595 if (tab_id >= 0) {
596 scoped_refptr<const PermissionSet> tab_permissions =
597 GetTabSpecificPermissions(tab_id);
598 if (tab_permissions.get() &&
599 tab_permissions->explicit_hosts().MatchesSecurityOrigin(page_url)) {
600 return true;
601 }
602 }
603
604 if (HasHostPermission(page_url) || page_url.GetOrigin() == url())
605 return true;
606
607 if (error) {
608 *error = ErrorUtils::FormatErrorMessage(errors::kCannotAccessPage,
609 page_url.spec());
610 }
611 return false;
612 }
613
614 bool Extension::UpdatesFromGallery() const { 432 bool Extension::UpdatesFromGallery() const {
615 return extension_urls::IsWebstoreUpdateUrl(ManifestURL::GetUpdateURL(this)); 433 return extension_urls::IsWebstoreUpdateUrl(ManifestURL::GetUpdateURL(this));
616 } 434 }
617 435
618 bool Extension::OverlapsWithOrigin(const GURL& origin) const { 436 bool Extension::OverlapsWithOrigin(const GURL& origin) const {
619 if (url() == origin) 437 if (url() == origin)
620 return true; 438 return true;
621 439
622 if (web_extent().is_empty()) 440 if (web_extent().is_empty())
623 return false; 441 return false;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 // show packaged apps and platform apps because there are some pieces of 543 // show packaged apps and platform apps because there are some pieces of
726 // functionality that are only available in chrome://extensions/ but which 544 // functionality that are only available in chrome://extensions/ but which
727 // are needed for packaged and platform apps. For example, inspecting 545 // are needed for packaged and platform apps. For example, inspecting
728 // background pages. See http://crbug.com/116134. 546 // background pages. See http://crbug.com/116134.
729 if (is_hosted_app()) 547 if (is_hosted_app())
730 return false; 548 return false;
731 549
732 return true; 550 return true;
733 } 551 }
734 552
735 scoped_refptr<const PermissionSet> Extension::GetTabSpecificPermissions(
736 int tab_id) const {
737 base::AutoLock auto_lock(runtime_data_lock_);
738 return runtime_data_.GetTabSpecificPermissions(tab_id);
739 }
740
741 void Extension::UpdateTabSpecificPermissions(
742 int tab_id,
743 scoped_refptr<const PermissionSet> permissions) const {
744 base::AutoLock auto_lock(runtime_data_lock_);
745 runtime_data_.UpdateTabSpecificPermissions(tab_id, permissions);
746 }
747
748 void Extension::ClearTabSpecificPermissions(int tab_id) const {
749 base::AutoLock auto_lock(runtime_data_lock_);
750 runtime_data_.ClearTabSpecificPermissions(tab_id);
751 }
752
753 Extension::ManifestData* Extension::GetManifestData(const std::string& key) 553 Extension::ManifestData* Extension::GetManifestData(const std::string& key)
754 const { 554 const {
755 DCHECK(finished_parsing_manifest_ || thread_checker_.CalledOnValidThread()); 555 DCHECK(finished_parsing_manifest_ || thread_checker_.CalledOnValidThread());
756 ManifestDataMap::const_iterator iter = manifest_data_.find(key); 556 ManifestDataMap::const_iterator iter = manifest_data_.find(key);
757 if (iter != manifest_data_.end()) 557 if (iter != manifest_data_.end())
758 return iter->second.get(); 558 return iter->second.get();
759 return NULL; 559 return NULL;
760 } 560 }
761 561
762 void Extension::SetManifestData(const std::string& key, 562 void Extension::SetManifestData(const std::string& key,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 } 613 }
814 614
815 void Extension::AddWebExtentPattern(const URLPattern& pattern) { 615 void Extension::AddWebExtentPattern(const URLPattern& pattern) {
816 extent_.AddPattern(pattern); 616 extent_.AddPattern(pattern);
817 } 617 }
818 618
819 bool Extension::is_theme() const { 619 bool Extension::is_theme() const {
820 return manifest()->is_theme(); 620 return manifest()->is_theme();
821 } 621 }
822 622
823 Extension::RuntimeData::RuntimeData() {}
824 Extension::RuntimeData::RuntimeData(const PermissionSet* active)
825 : active_permissions_(active) {}
826 Extension::RuntimeData::~RuntimeData() {}
827
828 void Extension::RuntimeData::SetActivePermissions(
829 const PermissionSet* active) {
830 active_permissions_ = active;
831 }
832
833 scoped_refptr<const PermissionSet>
834 Extension::RuntimeData::GetActivePermissions() const {
835 return active_permissions_;
836 }
837
838 scoped_refptr<const PermissionSet>
839 Extension::RuntimeData::GetTabSpecificPermissions(int tab_id) const {
840 CHECK_GE(tab_id, 0);
841 TabPermissionsMap::const_iterator it = tab_specific_permissions_.find(tab_id);
842 return (it != tab_specific_permissions_.end()) ? it->second : NULL;
843 }
844
845 void Extension::RuntimeData::UpdateTabSpecificPermissions(
846 int tab_id,
847 scoped_refptr<const PermissionSet> permissions) {
848 CHECK_GE(tab_id, 0);
849 if (tab_specific_permissions_.count(tab_id)) {
850 tab_specific_permissions_[tab_id] = PermissionSet::CreateUnion(
851 tab_specific_permissions_[tab_id],
852 permissions.get());
853 } else {
854 tab_specific_permissions_[tab_id] = permissions;
855 }
856 }
857
858 void Extension::RuntimeData::ClearTabSpecificPermissions(int tab_id) {
859 CHECK_GE(tab_id, 0);
860 tab_specific_permissions_.erase(tab_id);
861 }
862
863 // static 623 // static
864 bool Extension::InitExtensionID(extensions::Manifest* manifest, 624 bool Extension::InitExtensionID(extensions::Manifest* manifest,
865 const base::FilePath& path, 625 const base::FilePath& path,
866 const std::string& explicit_id, 626 const std::string& explicit_id,
867 int creation_flags, 627 int creation_flags,
868 string16* error) { 628 string16* error) {
869 if (!explicit_id.empty()) { 629 if (!explicit_id.empty()) {
870 manifest->set_extension_id(explicit_id); 630 manifest->set_extension_id(explicit_id);
871 return true; 631 return true;
872 } 632 }
(...skipping 21 matching lines...) Expand all
894 std::string extension_id = id_util::GenerateIdForPath(path); 654 std::string extension_id = id_util::GenerateIdForPath(path);
895 if (extension_id.empty()) { 655 if (extension_id.empty()) {
896 NOTREACHED() << "Could not create ID from path."; 656 NOTREACHED() << "Could not create ID from path.";
897 return false; 657 return false;
898 } 658 }
899 manifest->set_extension_id(extension_id); 659 manifest->set_extension_id(extension_id);
900 return true; 660 return true;
901 } 661 }
902 } 662 }
903 663
904 // static
905 bool Extension::IsTrustedId(const std::string& id) {
906 // See http://b/4946060 for more details.
907 return id == std::string("nckgahadagoaajjgafhacjanaoiihapd");
908 }
909
910 Extension::Extension(const base::FilePath& path, 664 Extension::Extension(const base::FilePath& path,
911 scoped_ptr<extensions::Manifest> manifest) 665 scoped_ptr<extensions::Manifest> manifest)
912 : manifest_version_(0), 666 : manifest_version_(0),
913 converted_from_user_script_(false), 667 converted_from_user_script_(false),
914 manifest_(manifest.release()), 668 manifest_(manifest.release()),
915 finished_parsing_manifest_(false), 669 finished_parsing_manifest_(false),
916 launch_container_(extension_misc::LAUNCH_TAB), 670 launch_container_(extension_misc::LAUNCH_TAB),
917 launch_width_(0), 671 launch_width_(0),
918 launch_height_(0), 672 launch_height_(0),
919 display_in_launcher_(true), 673 display_in_launcher_(true),
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 if (is_app() && !LoadAppFeatures(error)) 710 if (is_app() && !LoadAppFeatures(error))
957 return false; 711 return false;
958 712
959 permissions_data_.reset(new PermissionsData); 713 permissions_data_.reset(new PermissionsData);
960 if (!permissions_data_->ParsePermissions(this, error)) 714 if (!permissions_data_->ParsePermissions(this, error))
961 return false; 715 return false;
962 716
963 if (!LoadSharedFeatures(error)) 717 if (!LoadSharedFeatures(error))
964 return false; 718 return false;
965 719
966 if (manifest_->HasKey(keys::kConvertedFromUserScript)) 720 if (manifest_->HasKey(keys::kConvertedFromUserScript)) {
967 manifest_->GetBoolean(keys::kConvertedFromUserScript, 721 manifest_->GetBoolean(keys::kConvertedFromUserScript,
968 &converted_from_user_script_); 722 &converted_from_user_script_);
723 }
969 724
970 if (HasMultipleUISurfaces()) { 725 if (HasMultipleUISurfaces()) {
971 *error = ASCIIToUTF16(errors::kOneUISurfaceOnly); 726 *error = ASCIIToUTF16(errors::kOneUISurfaceOnly);
972 return false; 727 return false;
973 } 728 }
974 729
975 finished_parsing_manifest_ = true; 730 finished_parsing_manifest_ = true;
976 731
977 permissions_data_->FinalizePermissions(this); 732 permissions_data_->FinalizePermissions(this);
978 733
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 1239
1485 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( 1240 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
1486 const Extension* extension, 1241 const Extension* extension,
1487 const PermissionSet* permissions, 1242 const PermissionSet* permissions,
1488 Reason reason) 1243 Reason reason)
1489 : reason(reason), 1244 : reason(reason),
1490 extension(extension), 1245 extension(extension),
1491 permissions(permissions) {} 1246 permissions(permissions) {}
1492 1247
1493 } // namespace extensions 1248 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/extension.h ('k') | chrome/common/extensions/extension_messages.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698