Chromium Code Reviews| Index: extensions/common/permissions/permissions_data.cc |
| diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc |
| index 85000a21e6388583bf27b0134ce2173817b82f1d..d356d1cec3508e787b1a0fe901cc29b699e6202b 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" |
|
not at google - send to devlin
2014/06/02 23:20:06
changes to this file is pretty crazy. effectively
Devlin
2014/06/03 15:28:21
Effectively... yes.
|
| -#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()) { |
| + scoped_refptr<const PermissionSet> required_permissions = |
| + PermissionsParser::GetRequiredPermissions(extension); |
| + active_permissions_ = |
| + new PermissionSet(required_permissions->apis(), |
| + required_permissions->manifest_permissions(), |
| + required_permissions->explicit_hosts(), |
| + required_permissions->scriptable_hosts()); |
| } |
| PermissionsData::~PermissionsData() { |
| @@ -278,238 +53,175 @@ 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( |
|
not at google - send to devlin
2014/06/02 23:20:06
i actually liked this method, it means you don't n
Devlin
2014/06/03 15:28:21
Since active_permissions() is public, it seems odd
not at google - send to devlin
2014/06/03 15:45:16
Hm I didn't see that active_permissions() got adde
|
| - 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_ = 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 { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + 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 { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + 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); |
| -} |
| - |
| -// static |
| -const URLPatternSet& PermissionsData::GetEffectiveHostPermissions( |
| - const Extension* extension) { |
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_); |
| - return GetActivePermissions(extension)->effective_hosts(); |
| -} |
| - |
| -// static |
| -bool PermissionsData::CanSilentlyIncreasePermissions( |
| - const Extension* extension) { |
| - return extension->location() != Manifest::INTERNAL; |
| + const APIPermission::CheckParam* param) const { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + return active_permissions_->CheckAPIPermissionWithParam(permission, param); |
| } |
| -// static |
| -bool PermissionsData::ShouldSkipPermissionWarnings(const Extension* extension) { |
| - return IsTrustedId(extension->id()); |
| +const URLPatternSet& PermissionsData::GetEffectiveHostPermissions() const { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + return active_permissions_->effective_hosts(); |
| } |
| -// static |
| -bool PermissionsData::HasHostPermission(const Extension* extension, |
| - const GURL& url) { |
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_); |
| - return GetActivePermissions(extension)->HasExplicitAccessToOrigin(url); |
| +bool PermissionsData::HasHostPermission(const GURL& url) const { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + return active_permissions_->HasExplicitAccessToOrigin(url); |
| } |
| -// static |
| -bool PermissionsData::HasEffectiveAccessToAllHosts(const Extension* extension) { |
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_); |
| - return GetActivePermissions(extension)->HasEffectiveAccessToAllHosts(); |
| +bool PermissionsData::HasEffectiveAccessToAllHosts() const { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + return active_permissions_->HasEffectiveAccessToAllHosts(); |
| } |
| -// static |
| -PermissionMessages PermissionsData::GetPermissionMessages( |
| - const Extension* extension) { |
| - base::AutoLock auto_lock(extension->permissions_data()->runtime_lock_); |
| - if (ShouldSkipPermissionWarnings(extension)) { |
| +PermissionMessages PermissionsData::GetPermissionMessages() const { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + 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 { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + 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 { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + 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; |
| @@ -518,63 +230,51 @@ bool PermissionsData::CanExecuteScriptOnPage(const Extension* extension, |
| // If a script is specified, use its matches. |
| can_access = script->MatchesURL(document_url); |
| } else { |
| + base::AutoLock auto_lock(runtime_lock_); |
| // 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)) |
| - return true; |
| + |
| + { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + 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,80 +282,50 @@ bool PermissionsData::RequiresActionForScriptExecution( |
| bool PermissionsData::RequiresActionForScriptExecution( |
| const Extension* extension, |
| int tab_id, |
| - const GURL& url) { |
| - // For now, the user should be notified when an extension with all hosts |
| - // permission tries to execute a script on a page, with exceptions for policy- |
| - // enabled and component extensions. If this doesn't meet those criteria, |
| - // return immediately. |
| - if (!extension->ShouldDisplayInExtensionSettings() || |
| - Manifest::IsPolicyLocation(extension->location()) || |
| - Manifest::IsComponentLocation(extension->location()) || |
| - !ShouldWarnAllHosts(extension)) { |
| - return false; |
| + const GURL& url) const { |
| + { |
| + base::AutoLock auto_lock(runtime_lock_); |
| + // For now, the user should be notified when an extension with all hosts |
| + // permission tries to execute a script on a page, with exceptions for |
| + // policy-enabled and component extensions. If this doesn't meet those |
| + // criteria, return immediately. |
| + if (!extension->ShouldDisplayInExtensionSettings() || |
| + Manifest::IsPolicyLocation(extension->location()) || |
| + Manifest::IsComponentLocation(extension->location()) || |
| + !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 |