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

Unified Diff: chrome/common/extensions/permissions/permissions_data.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: 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 side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/permissions/permissions_data.cc
diff --git a/chrome/common/extensions/permissions/permissions_data.cc b/chrome/common/extensions/permissions/permissions_data.cc
index 445da122835b283f2d971861443365939063457e..57e4fb0a48fe66c025dc016400103b24a7c9ec80 100644
--- a/chrome/common/extensions/permissions/permissions_data.cc
+++ b/chrome/common/extensions/permissions/permissions_data.cc
@@ -16,12 +16,17 @@
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/features/base_feature_provider.h"
#include "chrome/common/extensions/features/feature.h"
+#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/permissions/api_permission_set.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/common/extensions/permissions/permissions_info.h"
+#include "chrome/common/extensions/user_script.h"
#include "chrome/common/url_constants.h"
+#include "extensions/common/constants.h"
#include "extensions/common/error_utils.h"
+#include "extensions/common/url_pattern_set.h"
+#include "googleurl/src/gurl.h"
namespace keys = extension_manifest_keys;
namespace errors = extension_manifest_errors;
@@ -92,7 +97,7 @@ bool CanSpecifyHostPermission(const Extension* extension,
}
// Component extensions can have access to all of chrome://*.
- if (extension->CanExecuteScriptEverywhere())
+ if (PermissionsData::CanExecuteScriptEverywhere(extension))
return true;
if (CommandLine::ForCurrentProcess()->HasSwitch(
@@ -184,7 +189,8 @@ bool ParseHelper(Extension* extension,
}
// Parse host pattern permissions.
- const int kAllowedSchemes = extension->CanExecuteScriptEverywhere() ?
+ const int kAllowedSchemes =
+ PermissionsData::CanExecuteScriptEverywhere(extension) ?
URLPattern::SCHEME_ALL : Extension::kValidHostPermissionSchemes;
for (std::vector<std::string>::const_iterator iter = host_data.begin();
@@ -200,14 +206,14 @@ bool ParseHelper(Extension* extension,
pattern.SetPath("/*");
int valid_schemes = pattern.valid_schemes();
if (pattern.MatchesScheme(chrome::kFileScheme) &&
- !extension->CanExecuteScriptEverywhere()) {
+ !PermissionsData::CanExecuteScriptEverywhere(extension)) {
extension->set_wants_file_access(true);
if (!(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS))
valid_schemes &= ~URLPattern::SCHEME_FILE;
}
if (pattern.scheme() != chrome::kChromeUIScheme &&
- !extension->CanExecuteScriptEverywhere()) {
+ !PermissionsData::CanExecuteScriptEverywhere(extension)) {
// Keep chrome:// in allowed schemes only if it's explicitly requested
// or CanExecuteScriptEverywhere is true. If the
// extensions_on_chrome_urls flag is not set, CanSpecifyHostPermission
@@ -293,6 +299,270 @@ APIPermissionSet* PermissionsData::GetInitialAPIPermissions(
initial_required_permissions_->api_permissions;
}
+// static
+void PermissionsData::SetActivePermissions(const Extension* extension,
+ const PermissionSet* permissions) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ extension->permissions_data()->active_permissions_ = permissions;
+}
+
+// static
+scoped_refptr<const PermissionSet> PermissionsData::GetActivePermissions(
+ const Extension* extension) {
+ return extension->permissions_data()->active_permissions_;
+}
+
+// static
+scoped_refptr<const PermissionSet> PermissionsData::GetTabSpecificPermissions(
+ const Extension* extension,
+ int tab_id) {
+ CHECK_GE(tab_id, 0);
+ TabPermissionsMap::const_iterator iter =
+ extension->permissions_data()->tab_specific_permissions_.find(tab_id);
+ return
+ (iter != extension->permissions_data()->tab_specific_permissions_.end())
+ ? iter->second
+ : NULL;
+}
+
+// static
+void PermissionsData::UpdateTabSpecificPermissions(
+ const Extension* extension,
+ int tab_id,
+ scoped_refptr<const PermissionSet> permissions) {
+ CHECK_GE(tab_id, 0);
+ TabPermissionsMap* tab_permissions =
+ &extension->permissions_data()->tab_specific_permissions_;
+ if (tab_permissions->count(tab_id)) {
+ (*tab_permissions)[tab_id] = PermissionSet::CreateUnion(
+ (*tab_permissions)[tab_id],
+ permissions.get());
+ } else {
+ (*tab_permissions)[tab_id] = permissions;
+ }
+}
+
+// static
+void PermissionsData::ClearTabSpecificPermissions(
+ const Extension* extension,
+ int tab_id) {
+ CHECK_GE(tab_id, 0);
+ extension->permissions_data()->tab_specific_permissions_.erase(tab_id);
+}
+
+// static
+bool PermissionsData::HasAPIPermission(const Extension* extension,
+ APIPermission::ID permission) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ return extension->permissions_data()->
Yoyo Zhou 2013/05/11 00:57:04 These should probably be GetActivePermissions. The
Devlin 2013/05/13 22:44:23 Done.
+ active_permissions_->HasAPIPermission(permission);
+}
+
+// static
+bool PermissionsData::HasAPIPermission(const Extension* extension,
+ const std::string& function_name) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ return extension->permissions_data()->
+ active_permissions_->HasAccessToFunction(function_name,
+ true); // include implicit
+}
+
+// static
+bool PermissionsData::HasAPIPermissionForTab(
+ const Extension* extension,
+ int tab_id,
+ APIPermission::ID permission) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ if (HasAPIPermission(extension, permission))
+ return true;
+ scoped_refptr<const PermissionSet> tab_permissions =
+ GetTabSpecificPermissions(extension, tab_id);
+ return tab_permissions.get() && tab_permissions->HasAPIPermission(permission);
+}
+
+// static
+bool PermissionsData::CheckAPIPermissionWithParam(
+ const Extension* extension,
+ APIPermission::ID permission,
+ const APIPermission::CheckParam* param) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ return extension->permissions_data()->active_permissions_->
+ CheckAPIPermissionWithParam(permission, param);
+}
+
+// static
+const URLPatternSet& PermissionsData::GetEffectiveHostPermissions(
+ const Extension* extension) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ return extension->permissions_data()->active_permissions_->effective_hosts();
+}
+
+// static
+bool PermissionsData::CanSilentlyIncreasePermissions(
+ const Extension* extension) {
+ return extension->location() != Manifest::INTERNAL;
+}
+
+// static
+bool PermissionsData::ShouldSkipPermissionWarnings(const Extension* extension) {
+ return Extension::IsTrustedId(extension->id());
Yoyo Zhou 2013/05/11 00:57:04 Why not move IsTrustedId to here?
Devlin 2013/05/13 22:44:23 Done.
+}
+
+// static
+bool PermissionsData::HasHostPermission(const Extension* extension,
+ const GURL& url) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ return extension->permissions_data()->active_permissions_->
+ HasExplicitAccessToOrigin(url);
+}
+
+// static
+bool PermissionsData::HasEffectiveAccessToAllHosts(const Extension* extension) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ return extension->permissions_data()->active_permissions_->
+ HasEffectiveAccessToAllHosts();
+}
+
+// static
+PermissionMessages PermissionsData::GetPermissionMessages(
+ const Extension* extension) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ if (Extension::IsTrustedId(extension->id())) {
Yoyo Zhou 2013/05/11 00:57:04 I think these should use ShouldSkipPermissionWarni
Devlin 2013/05/13 22:44:23 Done.
+ return PermissionMessages();
+ } else {
+ return extension->permissions_data()->active_permissions_->
+ GetPermissionMessages(extension->GetType());
+ }
+}
+
+// static
+std::vector<string16> PermissionsData::GetPermissionMessageStrings(
+ const Extension* extension) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ if (Extension::IsTrustedId(extension->id())) {
+ return std::vector<string16>();
+ } else {
+ return extension->permissions_data()->active_permissions_->
+ GetWarningMessages(extension->GetType());
+ }
+}
+
+// static
+bool PermissionsData::CanExecuteScriptOnPage(const Extension* extension,
+ const GURL& document_url,
+ const GURL& top_frame_url,
+ int tab_id,
+ const UserScript* script,
+ std::string* error) {
+ base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
+ // The gallery is special-cased as a restricted URL for scripting to prevent
+ // access to special JS bindings we expose to the gallery (and avoid things
+ // like extensions removing the "report abuse" link).
+ // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing
+ // against the store app extent?
+ GURL store_url(extension_urls::GetWebstoreLaunchURL());
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ bool can_execute_everywhere = CanExecuteScriptEverywhere(extension);
+
+ if ((document_url.host() == store_url.host()) &&
+ !can_execute_everywhere &&
+ !command_line->HasSwitch(switches::kAllowScriptingGallery)) {
+ if (error)
+ *error = errors::kCannotScriptGallery;
+ return false;
+ }
+
+ if (!command_line->HasSwitch(switches::kExtensionsOnChromeURLs)) {
+ if (document_url.SchemeIs(chrome::kChromeUIScheme) &&
+ !can_execute_everywhere) {
+ if (error)
+ *error = errors::kCannotAccessChromeUrl;
+ return false;
+ }
+ }
+
+ if (top_frame_url.SchemeIs(extensions::kExtensionScheme) &&
+ top_frame_url.GetOrigin() !=
+ Extension::GetBaseURLFromExtensionId(extension->id()).GetOrigin() &&
+ !can_execute_everywhere) {
+ if (error)
+ *error = errors::kCannotAccessExtensionUrl;
+ return false;
+ }
+
+ // If a tab ID is specified, try the tab-specific permissions.
+ if (tab_id >= 0) {
+ scoped_refptr<const PermissionSet> tab_permissions =
+ GetTabSpecificPermissions(extension, tab_id);
+ if (tab_permissions.get() &&
+ tab_permissions->explicit_hosts().MatchesSecurityOrigin(document_url)) {
+ return true;
+ }
+ }
+
+ bool can_access = false;
+
+ if (script) {
+ // If a script is specified, use its matches.
+ can_access = script->MatchesURL(document_url);
+ } else {
+ // Otherwise, see if this extension has permission to execute script
+ // programmatically on pages.
+ can_access = GetActivePermissions(extension)->
+ HasExplicitAccessToOrigin(document_url);
+ }
+
+ if (!can_access && error) {
+ *error = ErrorUtils::FormatErrorMessage(errors::kCannotAccessPage,
+ document_url.spec());
+ }
+
+ return can_access;
+}
+
+// static
+bool PermissionsData::CanExecuteScriptEverywhere(const Extension* extension) {
+ if (extension->location() == Manifest::COMPONENT)
+ return true;
+
+ const Extension::ScriptingWhitelist* whitelist =
+ Extension::GetScriptingWhitelist();
+
+ for (Extension::ScriptingWhitelist::const_iterator iter = whitelist->begin();
+ iter != whitelist->end(); ++iter) {
+ if (extension->id() == *iter)
+ return true;
+ }
+
+ return false;
+}
+
+// static
+bool PermissionsData::CanCaptureVisiblePage(const Extension* extension,
+ const GURL& page_url,
+ int tab_id,
+ std::string* error) {
+ if (tab_id >= 0) {
+ scoped_refptr<const PermissionSet> tab_permissions =
+ GetTabSpecificPermissions(extension, tab_id);
+ if (tab_permissions.get() &&
+ tab_permissions->explicit_hosts().MatchesSecurityOrigin(page_url)) {
+ return true;
+ }
+ }
+
+ if (HasHostPermission(extension, page_url) ||
+ page_url.GetOrigin() == extension->url()) {
+ return true;
+ }
+
+ if (error) {
+ *error = ErrorUtils::FormatErrorMessage(errors::kCannotAccessPage,
+ page_url.spec());
+ }
+ return false;
+}
+
bool PermissionsData::ParsePermissions(Extension* extension, string16* error) {
initial_required_permissions_.reset(new InitialPermissions);
if (!ParseHelper(extension,
@@ -349,10 +619,10 @@ void PermissionsData::FinalizePermissions(Extension* extension) {
URLPatternSet scriptable_hosts =
ContentScriptsInfo::GetScriptableHosts(extension);
- extension->SetActivePermissions(new PermissionSet(
+ active_permissions_ = new PermissionSet(
initial_required_permissions_->api_permissions,
initial_required_permissions_->host_permissions,
- scriptable_hosts));
+ scriptable_hosts);
required_permission_set_ = new PermissionSet(
initial_required_permissions_->api_permissions,

Powered by Google App Engine
This is Rietveld 408576698