| Index: extensions/common/permissions/permissions_data.cc
|
| diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc
|
| index 8fde19930d003330ac8cb73c01e09506dd850a82..12dfaa6619cea2a8e81175509979366e67a53434 100644
|
| --- a/extensions/common/permissions/permissions_data.cc
|
| +++ b/extensions/common/permissions/permissions_data.cc
|
| @@ -5,26 +5,14 @@
|
| #include "extensions/common/permissions/permissions_data.h"
|
|
|
| #include "base/command_line.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/strings/string16.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/values.h"
|
| #include "content/public/common/url_constants.h"
|
| #include "extensions/common/constants.h"
|
| #include "extensions/common/error_utils.h"
|
| -#include "extensions/common/extension.h"
|
| #include "extensions/common/extensions_client.h"
|
| -#include "extensions/common/features/feature.h"
|
| -#include "extensions/common/features/feature_provider.h"
|
| #include "extensions/common/manifest.h"
|
| #include "extensions/common/manifest_constants.h"
|
| -#include "extensions/common/manifest_handler.h"
|
| -#include "extensions/common/permissions/api_permission_set.h"
|
| +#include "extensions/common/manifest_handlers/permissions_parser.h"
|
| #include "extensions/common/permissions/permission_message_provider.h"
|
| -#include "extensions/common/permissions/permission_set.h"
|
| -#include "extensions/common/permissions/permissions_info.h"
|
| #include "extensions/common/switches.h"
|
| #include "extensions/common/url_pattern_set.h"
|
| #include "extensions/common/user_script.h"
|
| @@ -32,241 +20,28 @@
|
|
|
| namespace extensions {
|
|
|
| -namespace keys = manifest_keys;
|
| -namespace errors = manifest_errors;
|
| -
|
| namespace {
|
|
|
| PermissionsData::PolicyDelegate* g_policy_delegate = NULL;
|
|
|
| -// Custom checks for the experimental permission that can't be expressed in
|
| -// _permission_features.json.
|
| -bool CanSpecifyExperimentalPermission(const Extension* extension) {
|
| - if (extension->location() == Manifest::COMPONENT)
|
| - return true;
|
| -
|
| - if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| - switches::kEnableExperimentalExtensionApis)) {
|
| - return true;
|
| - }
|
| -
|
| - // We rely on the webstore to check access to experimental. This way we can
|
| - // whitelist extensions to have access to experimental in just the store, and
|
| - // not have to push a new version of the client.
|
| - if (extension->from_webstore())
|
| - return true;
|
| -
|
| - return false;
|
| -}
|
| -
|
| -// Checks whether the host |pattern| is allowed for the given |extension|,
|
| -// given API permissions |permissions|.
|
| -bool CanSpecifyHostPermission(const Extension* extension,
|
| - const URLPattern& pattern,
|
| - const APIPermissionSet& permissions) {
|
| - if (!pattern.match_all_urls() &&
|
| - pattern.MatchesScheme(content::kChromeUIScheme)) {
|
| - URLPatternSet chrome_scheme_hosts = ExtensionsClient::Get()->
|
| - GetPermittedChromeSchemeHosts(extension, permissions);
|
| - if (chrome_scheme_hosts.ContainsPattern(pattern))
|
| - return true;
|
| -
|
| - // Component extensions can have access to all of chrome://*.
|
| - if (PermissionsData::CanExecuteScriptEverywhere(extension))
|
| - return true;
|
| -
|
| - if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| - switches::kExtensionsOnChromeURLs)) {
|
| - return true;
|
| - }
|
| -
|
| - // TODO(aboxhall): return from_webstore() when webstore handles blocking
|
| - // extensions which request chrome:// urls
|
| - return false;
|
| - }
|
| -
|
| - // Otherwise, the valid schemes were handled by URLPattern.
|
| - return true;
|
| -}
|
| -
|
| -// Parses the host and api permissions from the specified permission |key|
|
| -// from |extension|'s manifest.
|
| -bool ParseHelper(Extension* extension,
|
| - const char* key,
|
| - APIPermissionSet* api_permissions,
|
| - URLPatternSet* host_permissions,
|
| - base::string16* error) {
|
| - if (!extension->manifest()->HasKey(key))
|
| - return true;
|
| -
|
| - const base::ListValue* permissions = NULL;
|
| - if (!extension->manifest()->GetList(key, &permissions)) {
|
| - *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidPermissions,
|
| - std::string());
|
| - return false;
|
| - }
|
| -
|
| - // NOTE: We need to get the APIPermission before we check if features
|
| - // associated with them are available because the feature system does not
|
| - // know about aliases.
|
| -
|
| - std::vector<std::string> host_data;
|
| - if (!APIPermissionSet::ParseFromJSON(
|
| - permissions, APIPermissionSet::kDisallowInternalPermissions,
|
| - api_permissions, error, &host_data)) {
|
| - return false;
|
| - }
|
| -
|
| - // Verify feature availability of permissions.
|
| - std::vector<APIPermission::ID> to_remove;
|
| - const FeatureProvider* permission_features =
|
| - FeatureProvider::GetPermissionFeatures();
|
| - for (APIPermissionSet::const_iterator iter = api_permissions->begin();
|
| - iter != api_permissions->end(); ++iter) {
|
| - Feature* feature = permission_features->GetFeature(iter->name());
|
| -
|
| - // The feature should exist since we just got an APIPermission for it. The
|
| - // two systems should be updated together whenever a permission is added.
|
| - DCHECK(feature) << "Could not find feature for " << iter->name();
|
| - // http://crbug.com/176381
|
| - if (!feature) {
|
| - to_remove.push_back(iter->id());
|
| - continue;
|
| - }
|
| -
|
| - Feature::Availability availability =
|
| - feature->IsAvailableToExtension(extension);
|
| -
|
| - if (!availability.is_available()) {
|
| - // Don't fail, but warn the developer that the manifest contains
|
| - // unrecognized permissions. This may happen legitimately if the
|
| - // extensions requests platform- or channel-specific permissions.
|
| - extension->AddInstallWarning(InstallWarning(availability.message(),
|
| - feature->name()));
|
| - to_remove.push_back(iter->id());
|
| - continue;
|
| - }
|
| -
|
| - if (iter->id() == APIPermission::kExperimental) {
|
| - if (!CanSpecifyExperimentalPermission(extension)) {
|
| - *error = base::ASCIIToUTF16(errors::kExperimentalFlagRequired);
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| -
|
| - api_permissions->AddImpliedPermissions();
|
| -
|
| - // Remove permissions that are not available to this extension.
|
| - for (std::vector<APIPermission::ID>::const_iterator iter = to_remove.begin();
|
| - iter != to_remove.end(); ++iter) {
|
| - api_permissions->erase(*iter);
|
| - }
|
| -
|
| - // Parse host pattern permissions.
|
| - const int kAllowedSchemes =
|
| - PermissionsData::CanExecuteScriptEverywhere(extension) ?
|
| - URLPattern::SCHEME_ALL : Extension::kValidHostPermissionSchemes;
|
| -
|
| - for (std::vector<std::string>::const_iterator iter = host_data.begin();
|
| - iter != host_data.end(); ++iter) {
|
| - const std::string& permission_str = *iter;
|
| -
|
| - // Check if it's a host pattern permission.
|
| - URLPattern pattern = URLPattern(kAllowedSchemes);
|
| - URLPattern::ParseResult parse_result = pattern.Parse(permission_str);
|
| - if (parse_result == URLPattern::PARSE_SUCCESS) {
|
| - // The path component is not used for host permissions, so we force it
|
| - // to match all paths.
|
| - pattern.SetPath("/*");
|
| - int valid_schemes = pattern.valid_schemes();
|
| - if (pattern.MatchesScheme(url::kFileScheme) &&
|
| - !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() != content::kChromeUIScheme &&
|
| - !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
|
| - // will fail, so don't check the flag here.
|
| - valid_schemes &= ~URLPattern::SCHEME_CHROMEUI;
|
| - }
|
| - pattern.SetValidSchemes(valid_schemes);
|
| -
|
| - if (!CanSpecifyHostPermission(extension, pattern, *api_permissions)) {
|
| - // TODO(aboxhall): make a warning (see pattern.match_all_urls() block
|
| - // below).
|
| - extension->AddInstallWarning(InstallWarning(
|
| - ErrorUtils::FormatErrorMessage(
|
| - errors::kInvalidPermissionScheme, permission_str),
|
| - key,
|
| - permission_str));
|
| - continue;
|
| - }
|
| -
|
| - host_permissions->AddPattern(pattern);
|
| - // We need to make sure all_urls matches chrome://favicon and (maybe)
|
| - // chrome://thumbnail, so add them back in to host_permissions separately.
|
| - if (pattern.match_all_urls()) {
|
| - host_permissions->AddPatterns(
|
| - ExtensionsClient::Get()->GetPermittedChromeSchemeHosts(
|
| - extension, *api_permissions));
|
| - }
|
| - continue;
|
| - }
|
| -
|
| - // It's probably an unknown API permission. Do not throw an error so
|
| - // extensions can retain backwards compatability (http://crbug.com/42742).
|
| - extension->AddInstallWarning(InstallWarning(
|
| - ErrorUtils::FormatErrorMessage(
|
| - manifest_errors::kPermissionUnknownOrMalformed,
|
| - permission_str),
|
| - key,
|
| - permission_str));
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| // Returns true if this extension id is from a trusted provider.
|
| -bool IsTrustedId(const std::string& extension_id) {
|
| +bool ShouldSkipPermissionWarnings(const std::string& extension_id) {
|
| // See http://b/4946060 for more details.
|
| return extension_id == std::string("nckgahadagoaajjgafhacjanaoiihapd");
|
| }
|
|
|
| -// Returns true if the |extension| has tab-specific permission to operate on
|
| -// the tab specified by |tab_id| with the given |url|.
|
| -// Note that if this returns false, it doesn't mean the extension can't run on
|
| -// the given tab, only that it does not have tab-specific permission to do so.
|
| -bool HasTabSpecificPermissionToExecuteScript(
|
| - const Extension* extension,
|
| - int tab_id,
|
| - const GURL& url) {
|
| - if (tab_id >= 0) {
|
| - scoped_refptr<const PermissionSet> tab_permissions =
|
| - PermissionsData::GetTabSpecificPermissions(extension, tab_id);
|
| - if (tab_permissions.get() &&
|
| - tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| } // namespace
|
|
|
| -struct PermissionsData::InitialPermissions {
|
| - APIPermissionSet api_permissions;
|
| - ManifestPermissionSet manifest_permissions;
|
| - URLPatternSet host_permissions;
|
| - URLPatternSet scriptable_hosts;
|
| -};
|
| -
|
| -PermissionsData::PermissionsData() {
|
| +PermissionsData::PermissionsData(const Extension* extension)
|
| + : extension_id_(extension->id()), manifest_type_(extension->GetType()) {
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + scoped_refptr<const PermissionSet> required_permissions =
|
| + PermissionsParser::GetRequiredPermissions(extension);
|
| + active_permissions_unsafe_ =
|
| + new PermissionSet(required_permissions->apis(),
|
| + required_permissions->manifest_permissions(),
|
| + required_permissions->explicit_hosts(),
|
| + required_permissions->scriptable_hosts());
|
| }
|
|
|
| PermissionsData::~PermissionsData() {
|
| @@ -278,238 +53,166 @@ void PermissionsData::SetPolicyDelegate(PolicyDelegate* delegate) {
|
| }
|
|
|
| // static
|
| -const PermissionSet* PermissionsData::GetOptionalPermissions(
|
| - const Extension* extension) {
|
| - return extension->permissions_data()->optional_permission_set_.get();
|
| -}
|
| -
|
| -// static
|
| -const PermissionSet* PermissionsData::GetRequiredPermissions(
|
| +const PermissionsData* PermissionsData::ForExtension(
|
| const Extension* extension) {
|
| - return extension->permissions_data()->required_permission_set_.get();
|
| + // TODO(rdevlin.cronin): Figure out what we're doing with this (i.e. whether
|
| + // or not we want to expose PermissionsData on the extension).
|
| + return extension->permissions_data();
|
| }
|
|
|
| // static
|
| -const APIPermissionSet* PermissionsData::GetInitialAPIPermissions(
|
| +bool PermissionsData::CanSilentlyIncreasePermissions(
|
| const Extension* extension) {
|
| - return &extension->permissions_data()->
|
| - initial_required_permissions_->api_permissions;
|
| -}
|
| -
|
| -// static
|
| -APIPermissionSet* PermissionsData::GetInitialAPIPermissions(
|
| - Extension* extension) {
|
| - return &extension->permissions_data()->
|
| - initial_required_permissions_->api_permissions;
|
| + return extension->location() != Manifest::INTERNAL;
|
| }
|
|
|
| // static
|
| -void PermissionsData::SetInitialScriptableHosts(
|
| - Extension* extension, const URLPatternSet& scriptable_hosts) {
|
| - extension->permissions_data()->
|
| - initial_required_permissions_->scriptable_hosts = scriptable_hosts;
|
| -}
|
| +bool PermissionsData::CanExecuteScriptEverywhere(const Extension* extension) {
|
| + if (extension->location() == Manifest::COMPONENT)
|
| + return true;
|
|
|
| -// 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;
|
| -}
|
| + const ExtensionsClient::ScriptingWhitelist& whitelist =
|
| + ExtensionsClient::Get()->GetScriptingWhitelist();
|
|
|
| -// static
|
| -scoped_refptr<const PermissionSet> PermissionsData::GetActivePermissions(
|
| - const Extension* extension) {
|
| - return extension->permissions_data()->active_permissions_;
|
| + return std::find(whitelist.begin(), whitelist.end(), extension->id()) !=
|
| + whitelist.end();
|
| }
|
|
|
| -// 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;
|
| +void PermissionsData::SetActivePermissions(
|
| + const PermissionSet* permissions) const {
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + active_permissions_unsafe_ = permissions;
|
| }
|
|
|
| -// static
|
| void PermissionsData::UpdateTabSpecificPermissions(
|
| - const Extension* extension,
|
| int tab_id,
|
| - scoped_refptr<const PermissionSet> permissions) {
|
| + scoped_refptr<const PermissionSet> permissions) const {
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| 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].get(), permissions.get());
|
| - } else {
|
| - (*tab_permissions)[tab_id] = permissions;
|
| - }
|
| + TabPermissionsMap::iterator iter = tab_specific_permissions_.find(tab_id);
|
| + if (iter == tab_specific_permissions_.end())
|
| + tab_specific_permissions_[tab_id] = permissions;
|
| + else
|
| + iter->second = PermissionSet::CreateUnion(iter->second, permissions);
|
| }
|
|
|
| -// static
|
| -void PermissionsData::ClearTabSpecificPermissions(
|
| - const Extension* extension,
|
| - int tab_id) {
|
| +void PermissionsData::ClearTabSpecificPermissions(int tab_id) const {
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| CHECK_GE(tab_id, 0);
|
| - extension->permissions_data()->tab_specific_permissions_.erase(tab_id);
|
| + 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 GetActivePermissions(extension)->HasAPIPermission(permission);
|
| +bool PermissionsData::HasAPIPermission(APIPermission::ID permission) const {
|
| + return active_permissions()->HasAPIPermission(permission);
|
| }
|
|
|
| -// static
|
| bool PermissionsData::HasAPIPermission(
|
| - const Extension* extension,
|
| - const std::string& permission_name) {
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| - return GetActivePermissions(extension)->HasAPIPermission(permission_name);
|
| + const std::string& permission_name) const {
|
| + return active_permissions()->HasAPIPermission(permission_name);
|
| }
|
|
|
| -// static
|
| bool PermissionsData::HasAPIPermissionForTab(
|
| - const Extension* extension,
|
| int tab_id,
|
| - APIPermission::ID permission) {
|
| - if (HasAPIPermission(extension, permission))
|
| + APIPermission::ID permission) const {
|
| + if (HasAPIPermission(permission))
|
| return true;
|
|
|
| - // Place autolock below the HasAPIPermission() check, since HasAPIPermission
|
| - // also acquires the lock.
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| scoped_refptr<const PermissionSet> tab_permissions =
|
| - GetTabSpecificPermissions(extension, tab_id);
|
| + GetTabSpecificPermissions(tab_id);
|
| +
|
| + // Place autolock below the HasAPIPermission() and
|
| + // GetTabSpecificPermissions(), since each already acquires the lock.
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| 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 GetActivePermissions(extension)->CheckAPIPermissionWithParam(
|
| - permission, param);
|
| + const APIPermission::CheckParam* param) const {
|
| + return active_permissions()->CheckAPIPermissionWithParam(permission, param);
|
| }
|
|
|
| -// static
|
| -const URLPatternSet& PermissionsData::GetEffectiveHostPermissions(
|
| - const Extension* extension) {
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| - return GetActivePermissions(extension)->effective_hosts();
|
| +const URLPatternSet& PermissionsData::GetEffectiveHostPermissions() const {
|
| + return active_permissions()->effective_hosts();
|
| }
|
|
|
| -// static
|
| -bool PermissionsData::CanSilentlyIncreasePermissions(
|
| - const Extension* extension) {
|
| - return extension->location() != Manifest::INTERNAL;
|
| +bool PermissionsData::HasHostPermission(const GURL& url) const {
|
| + return active_permissions()->HasExplicitAccessToOrigin(url);
|
| }
|
|
|
| -// static
|
| -bool PermissionsData::ShouldSkipPermissionWarnings(const Extension* extension) {
|
| - return IsTrustedId(extension->id());
|
| +bool PermissionsData::HasEffectiveAccessToAllHosts() const {
|
| + return active_permissions()->HasEffectiveAccessToAllHosts();
|
| }
|
|
|
| -// static
|
| -bool PermissionsData::HasHostPermission(const Extension* extension,
|
| - const GURL& url) {
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| - return GetActivePermissions(extension)->HasExplicitAccessToOrigin(url);
|
| -}
|
| -
|
| -// static
|
| -bool PermissionsData::HasEffectiveAccessToAllHosts(const Extension* extension) {
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| - return GetActivePermissions(extension)->HasEffectiveAccessToAllHosts();
|
| -}
|
| -
|
| -// static
|
| -PermissionMessages PermissionsData::GetPermissionMessages(
|
| - const Extension* extension) {
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| - if (ShouldSkipPermissionWarnings(extension)) {
|
| +PermissionMessages PermissionsData::GetPermissionMessages() const {
|
| + if (ShouldSkipPermissionWarnings(extension_id_)) {
|
| return PermissionMessages();
|
| } else {
|
| return PermissionMessageProvider::Get()->GetPermissionMessages(
|
| - GetActivePermissions(extension), extension->GetType());
|
| + active_permissions(), manifest_type_);
|
| }
|
| }
|
|
|
| -// static
|
| -std::vector<base::string16> PermissionsData::GetPermissionMessageStrings(
|
| - const Extension* extension) {
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| - if (ShouldSkipPermissionWarnings(extension)) {
|
| +std::vector<base::string16> PermissionsData::GetPermissionMessageStrings()
|
| + const {
|
| + if (ShouldSkipPermissionWarnings(extension_id_))
|
| return std::vector<base::string16>();
|
| - } else {
|
| - return PermissionMessageProvider::Get()->GetWarningMessages(
|
| - GetActivePermissions(extension), extension->GetType());
|
| - }
|
| + return PermissionMessageProvider::Get()->GetWarningMessages(
|
| + active_permissions(), manifest_type_);
|
| }
|
|
|
| -// static
|
| -std::vector<base::string16> PermissionsData::GetPermissionMessageDetailsStrings(
|
| - const Extension* extension) {
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| - if (ShouldSkipPermissionWarnings(extension)) {
|
| +std::vector<base::string16>
|
| +PermissionsData::GetPermissionMessageDetailsStrings() const {
|
| + if (ShouldSkipPermissionWarnings(extension_id_))
|
| return std::vector<base::string16>();
|
| - } else {
|
| - return PermissionMessageProvider::Get()->GetWarningMessagesDetails(
|
| - GetActivePermissions(extension), extension->GetType());
|
| - }
|
| + return PermissionMessageProvider::Get()->GetWarningMessagesDetails(
|
| + active_permissions(), manifest_type_);
|
| }
|
|
|
| -// static
|
| bool PermissionsData::CanExecuteScriptOnPage(const Extension* extension,
|
| const GURL& document_url,
|
| const GURL& top_frame_url,
|
| int tab_id,
|
| const UserScript* script,
|
| int process_id,
|
| - std::string* error) {
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| - const CommandLine* command_line = CommandLine::ForCurrentProcess();
|
| - bool can_execute_everywhere = CanExecuteScriptEverywhere(extension);
|
| -
|
| + std::string* error) const {
|
| if (g_policy_delegate &&
|
| - !g_policy_delegate->CanExecuteScriptOnPage(
|
| - extension, document_url, top_frame_url, tab_id,
|
| - script, process_id, error))
|
| + !g_policy_delegate->CanExecuteScriptOnPage(extension,
|
| + document_url,
|
| + top_frame_url,
|
| + tab_id,
|
| + script,
|
| + process_id,
|
| + error)) {
|
| return false;
|
| + }
|
|
|
| + bool can_execute_everywhere = CanExecuteScriptEverywhere(extension);
|
| if (!can_execute_everywhere &&
|
| !ExtensionsClient::Get()->IsScriptableURL(document_url, error)) {
|
| return false;
|
| }
|
|
|
| - if (!command_line->HasSwitch(switches::kExtensionsOnChromeURLs)) {
|
| + if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kExtensionsOnChromeURLs)) {
|
| if (document_url.SchemeIs(content::kChromeUIScheme) &&
|
| !can_execute_everywhere) {
|
| if (error)
|
| - *error = errors::kCannotAccessChromeUrl;
|
| + *error = manifest_errors::kCannotAccessChromeUrl;
|
| return false;
|
| }
|
| }
|
|
|
| - if (top_frame_url.SchemeIs(extensions::kExtensionScheme) &&
|
| + if (top_frame_url.SchemeIs(kExtensionScheme) &&
|
| top_frame_url.GetOrigin() !=
|
| Extension::GetBaseURLFromExtensionId(extension->id()).GetOrigin() &&
|
| !can_execute_everywhere) {
|
| if (error)
|
| - *error = errors::kCannotAccessExtensionUrl;
|
| + *error = manifest_errors::kCannotAccessExtensionUrl;
|
| return false;
|
| }
|
|
|
| - if (HasTabSpecificPermissionToExecuteScript(extension, tab_id, top_frame_url))
|
| + if (HasTabSpecificPermissionToExecuteScript(tab_id, top_frame_url))
|
| return true;
|
|
|
| bool can_access = false;
|
| @@ -520,61 +223,45 @@ bool PermissionsData::CanExecuteScriptOnPage(const Extension* extension,
|
| } else {
|
| // Otherwise, see if this extension has permission to execute script
|
| // programmatically on pages.
|
| - can_access = GetActivePermissions(extension)->
|
| - HasExplicitAccessToOrigin(document_url);
|
| + can_access = active_permissions()->HasExplicitAccessToOrigin(document_url);
|
| }
|
|
|
| if (!can_access && error) {
|
| - *error = ErrorUtils::FormatErrorMessage(errors::kCannotAccessPage,
|
| + *error = ErrorUtils::FormatErrorMessage(manifest_errors::kCannotAccessPage,
|
| document_url.spec());
|
| }
|
|
|
| return can_access;
|
| }
|
|
|
| -// static
|
| -bool PermissionsData::CanExecuteScriptEverywhere(const Extension* extension) {
|
| - if (extension->location() == Manifest::COMPONENT)
|
| - return true;
|
| -
|
| - const ExtensionsClient::ScriptingWhitelist& whitelist =
|
| - ExtensionsClient::Get()->GetScriptingWhitelist();
|
| -
|
| - return std::find(whitelist.begin(), whitelist.end(), extension->id()) !=
|
| - whitelist.end();
|
| -}
|
| -
|
| -// static
|
| -bool PermissionsData::CanCaptureVisiblePage(const Extension* extension,
|
| - int tab_id,
|
| - std::string* error) {
|
| - scoped_refptr<const PermissionSet> active_permissions =
|
| - GetActivePermissions(extension);
|
| +bool PermissionsData::CanCaptureVisiblePage(int tab_id,
|
| + std::string* error) const {
|
| const URLPattern all_urls(URLPattern::SCHEME_ALL,
|
| URLPattern::kAllUrlsPattern);
|
| - if (active_permissions->explicit_hosts().ContainsPattern(all_urls))
|
| +
|
| + if (active_permissions()->explicit_hosts().ContainsPattern(all_urls))
|
| return true;
|
|
|
| if (tab_id >= 0) {
|
| scoped_refptr<const PermissionSet> tab_permissions =
|
| - GetTabSpecificPermissions(extension, tab_id);
|
| + GetTabSpecificPermissions(tab_id);
|
| if (tab_permissions &&
|
| tab_permissions->HasAPIPermission(APIPermission::kTab)) {
|
| return true;
|
| }
|
| if (error)
|
| - *error = errors::kActiveTabPermissionNotGranted;
|
| + *error = manifest_errors::kActiveTabPermissionNotGranted;
|
| return false;
|
| }
|
|
|
| if (error)
|
| - *error = errors::kAllURLOrActiveTabNeeded;
|
| + *error = manifest_errors::kAllURLOrActiveTabNeeded;
|
| return false;
|
| }
|
|
|
| // static
|
| bool PermissionsData::RequiresActionForScriptExecution(
|
| - const Extension* extension) {
|
| + const Extension* extension) const {
|
| return RequiresActionForScriptExecution(extension, -1, GURL());
|
| }
|
|
|
| @@ -582,7 +269,7 @@ bool PermissionsData::RequiresActionForScriptExecution(
|
| bool PermissionsData::RequiresActionForScriptExecution(
|
| const Extension* extension,
|
| int tab_id,
|
| - const GURL& url) {
|
| + const GURL& url) const {
|
| // For now, the user should be notified when an extension with all hosts
|
| // permission tries to execute a script on a page. Exceptions for policy-
|
| // enabled and component extensions, and extensions which are whitelisted to
|
| @@ -591,72 +278,39 @@ bool PermissionsData::RequiresActionForScriptExecution(
|
| Manifest::IsPolicyLocation(extension->location()) ||
|
| Manifest::IsComponentLocation(extension->location()) ||
|
| CanExecuteScriptEverywhere(extension) ||
|
| - !ShouldWarnAllHosts(extension)) {
|
| + !active_permissions()->ShouldWarnAllHosts()) {
|
| return false;
|
| }
|
|
|
| // If the extension has explicit permission to run on the given tab, then
|
| // we don't need to alert the user.
|
| - if (HasTabSpecificPermissionToExecuteScript(extension, tab_id, url))
|
| - return false;
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool PermissionsData::ParsePermissions(Extension* extension,
|
| - base::string16* error) {
|
| - initial_required_permissions_.reset(new InitialPermissions);
|
| - if (!ParseHelper(extension,
|
| - keys::kPermissions,
|
| - &initial_required_permissions_->api_permissions,
|
| - &initial_required_permissions_->host_permissions,
|
| - error)) {
|
| + if (HasTabSpecificPermissionToExecuteScript(tab_id, url))
|
| return false;
|
| - }
|
| -
|
| - initial_optional_permissions_.reset(new InitialPermissions);
|
| - if (!ParseHelper(extension,
|
| - keys::kOptionalPermissions,
|
| - &initial_optional_permissions_->api_permissions,
|
| - &initial_optional_permissions_->host_permissions,
|
| - error)) {
|
| - return false;
|
| - }
|
|
|
| return true;
|
| }
|
|
|
| -void PermissionsData::InitializeManifestPermissions(Extension* extension) {
|
| - ManifestHandler::AddExtensionInitialRequiredPermissions(
|
| - extension, &initial_required_permissions_->manifest_permissions);
|
| -}
|
| -
|
| -void PermissionsData::FinalizePermissions(Extension* extension) {
|
| - active_permissions_ = new PermissionSet(
|
| - initial_required_permissions_->api_permissions,
|
| - initial_required_permissions_->manifest_permissions,
|
| - initial_required_permissions_->host_permissions,
|
| - initial_required_permissions_->scriptable_hosts);
|
| -
|
| - required_permission_set_ = new PermissionSet(
|
| - initial_required_permissions_->api_permissions,
|
| - initial_required_permissions_->manifest_permissions,
|
| - initial_required_permissions_->host_permissions,
|
| - initial_required_permissions_->scriptable_hosts);
|
| -
|
| - optional_permission_set_ = new PermissionSet(
|
| - initial_optional_permissions_->api_permissions,
|
| - initial_optional_permissions_->manifest_permissions,
|
| - initial_optional_permissions_->host_permissions,
|
| - URLPatternSet());
|
| -
|
| - initial_required_permissions_.reset();
|
| - initial_optional_permissions_.reset();
|
| +scoped_refptr<const PermissionSet> PermissionsData::GetTabSpecificPermissions(
|
| + int tab_id) const {
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + CHECK_GE(tab_id, 0);
|
| + TabPermissionsMap::const_iterator iter =
|
| + tab_specific_permissions_.find(tab_id);
|
| + return (iter != tab_specific_permissions_.end()) ? iter->second : NULL;
|
| }
|
|
|
| -bool PermissionsData::ShouldWarnAllHosts(const Extension* extension) {
|
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_);
|
| - return PermissionsData::GetActivePermissions(extension)->ShouldWarnAllHosts();
|
| +bool PermissionsData::HasTabSpecificPermissionToExecuteScript(
|
| + int tab_id,
|
| + const GURL& url) const {
|
| + if (tab_id >= 0) {
|
| + scoped_refptr<const PermissionSet> tab_permissions =
|
| + GetTabSpecificPermissions(tab_id);
|
| + if (tab_permissions.get() &&
|
| + tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) {
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| }
|
|
|
| } // namespace extensions
|
|
|