diff options
author | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-28 17:05:51 +0000 |
---|---|---|
committer | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-28 17:05:51 +0000 |
commit | 6ac956af125cd1ff8a8be23f8515dba6809b1aff (patch) | |
tree | 38b3e5caabeb273244b348e1bd101181aa6ce576 /chrome/renderer | |
parent | b84ae679f054d846372e8e8ded5c31e8e9dc2ec8 (diff) | |
download | chromium_src-6ac956af125cd1ff8a8be23f8515dba6809b1aff.zip chromium_src-6ac956af125cd1ff8a8be23f8515dba6809b1aff.tar.gz chromium_src-6ac956af125cd1ff8a8be23f8515dba6809b1aff.tar.bz2 |
Revert 57788 - Expose Extension Bindings to Component Applications
This patch allows component (built-in) extension apps to have extension api bindings.
Note that this patch adds browser-side api permission checking for extension requests.
This is step two along the path to exposing an extension management api to the gallery (webstore).
BUG=27431
Review URL: http://codereview.chromium.org/3163044
TBR=rafaelw@chromium.org
Review URL: http://codereview.chromium.org/3249004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57789 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/extensions/event_bindings.cc | 21 | ||||
-rw-r--r-- | chrome/renderer/extensions/event_bindings.h | 2 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_process_bindings.cc | 57 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_renderer_info.cc | 31 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_renderer_info.h | 14 | ||||
-rw-r--r-- | chrome/renderer/mock_render_thread.cc | 1 | ||||
-rw-r--r-- | chrome/renderer/mock_render_thread.h | 1 | ||||
-rw-r--r-- | chrome/renderer/render_thread.cc | 42 | ||||
-rw-r--r-- | chrome/renderer/resources/extension_process_bindings.js | 6 |
9 files changed, 62 insertions, 113 deletions
diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc index 24a84cb..52f5d0e 100644 --- a/chrome/renderer/extensions/event_bindings.cc +++ b/chrome/renderer/extensions/event_bindings.cc @@ -11,7 +11,6 @@ #include "chrome/renderer/extensions/bindings_utils.h" #include "chrome/renderer/extensions/event_bindings.h" #include "chrome/renderer/extensions/extension_process_bindings.h" -#include "chrome/renderer/extensions/extension_renderer_info.h" #include "chrome/renderer/extensions/js_only_v8_extensions.h" #include "chrome/renderer/render_thread.h" #include "chrome/renderer/render_view.h" @@ -168,8 +167,6 @@ static bool HasSufficientPermissions(ContextInfo* context, } // namespace const char* EventBindings::kName = "chrome/EventBindings"; -const char* EventBindings::kTestingExtensionId = - "oooooooooooooooooooooooooooooooo"; v8::Extension* EventBindings::Get() { static v8::Extension* extension = new ExtensionImpl(); @@ -260,16 +257,10 @@ void EventBindings::HandleContextCreated(WebFrame* frame, bool content_script) { if (!ds) ds = frame->dataSource(); GURL url = ds->request().url(); - std::string extension_id = ExtensionRendererInfo::GetIdByURL(url); - - // Note: because process isolation doesn't work correcly with redirects, - // it is possible that a page that IS in an extension process won't have - // bindings setup for it, so we must also check IsExtensionProcess, otherwise - // we'll attempt to invoke a JS function that doesn't exist. - // Fixing crbug.com/53610 should fix this as well. - if ((!RenderThread::current()->IsExtensionProcess() || - !ExtensionRendererInfo::ExtensionBindingsAllowed(url)) && - !content_script) { + std::string extension_id; + if (url.SchemeIs(chrome::kExtensionScheme)) { + extension_id = url.host(); + } else if (!content_script) { // This context is a regular non-extension web page. Ignore it. We only // care about content scripts and extension frames. // (Unless we're in unit tests, in which case we don't care what the URL @@ -277,10 +268,6 @@ void EventBindings::HandleContextCreated(WebFrame* frame, bool content_script) { DCHECK(frame_context.IsEmpty() || frame_context == context); if (!in_unit_tests) return; - - // For tests, we want the dispatchOnLoad to actually setup our bindings, - // so we give a fake extension id; - extension_id = kTestingExtensionId; } v8::Persistent<v8::Context> persistent_context = diff --git a/chrome/renderer/extensions/event_bindings.h b/chrome/renderer/extensions/event_bindings.h index 037a1eb..98a56cf 100644 --- a/chrome/renderer/extensions/event_bindings.h +++ b/chrome/renderer/extensions/event_bindings.h @@ -22,8 +22,6 @@ class WebFrame; class EventBindings { public: static const char* kName; // The v8::Extension name, for dependencies. - static const char* kTestingExtensionId; - static v8::Extension* Get(); // Allow RenderThread to be mocked out. diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc index 38d2919..f0da91d 100644 --- a/chrome/renderer/extensions/extension_process_bindings.cc +++ b/chrome/renderer/extensions/extension_process_bindings.cc @@ -23,7 +23,6 @@ #include "chrome/common/url_constants.h" #include "chrome/renderer/extensions/bindings_utils.h" #include "chrome/renderer/extensions/event_bindings.h" -#include "chrome/renderer/extensions/extension_renderer_info.h" #include "chrome/renderer/extensions/js_only_v8_extensions.h" #include "chrome/renderer/extensions/renderer_extension_bindings.h" #include "chrome/renderer/user_script_slave.h" @@ -57,11 +56,11 @@ namespace { // A map of extension ID to vector of page action ids. typedef std::map< std::string, std::vector<std::string> > PageActionIdMap; -// A list of permissions that are enabled for this extension. -typedef std::vector<std::string> PermissionsList; +// A map of permission name to whether its enabled for this extension. +typedef std::map<std::string, bool> PermissionsMap; // A map of extension ID to permissions map. -typedef std::map<std::string, PermissionsList> ExtensionPermissionsList; +typedef std::map<std::string, PermissionsMap> ExtensionPermissionsMap; // A map of extension ID to whether this extension was enabled in incognito. typedef std::map<std::string, bool> IncognitoEnabledMap; @@ -75,10 +74,26 @@ const char* kExtensionDeps[] = { ExtensionApiTestV8Extension::kName, }; +// A list of the API packages which have no associated permission. +// TODO(erikkay) It might be nice if for consistency we could merge these with +// the permissions list, or at least have them in one place. +const char* kNonPermissionExtensionPackages[] = { + "extension", + // TODO(erikkay): We're inconsistent about the the package name in the events + // for pageAction and browserAction. + "pageAction", + "pageActions", + "browserAction", + "browserActions", + "i18n", + "devtools", + "test" +}; + struct SingletonData { std::set<std::string> function_names_; PageActionIdMap page_action_ids_; - ExtensionPermissionsList permissions_; + ExtensionPermissionsMap permissions_; IncognitoEnabledMap incognito_enabled_map_; }; @@ -90,7 +105,7 @@ static PageActionIdMap* GetPageActionMap() { return &Singleton<SingletonData>()->page_action_ids_; } -static PermissionsList* GetPermissionsList(const std::string& extension_id) { +static PermissionsMap* GetPermissionsMap(const std::string& extension_id) { return &Singleton<SingletonData>()->permissions_[extension_id]; } @@ -99,10 +114,10 @@ static IncognitoEnabledMap* GetIncognitoEnabledMap() { } static void GetActiveExtensionIDs(std::set<std::string>* extension_ids) { - ExtensionPermissionsList& permissions = + ExtensionPermissionsMap& permissions = Singleton<SingletonData>()->permissions_; - for (ExtensionPermissionsList::iterator iter = permissions.begin(); + for (ExtensionPermissionsMap::iterator iter = permissions.begin(); iter != permissions.end(); ++iter) { extension_ids->insert(iter->first); } @@ -219,10 +234,10 @@ class ExtensionImpl : public ExtensionBase { return std::string(); // this can happen as a tab is closing. GURL url = renderview->webview()->mainFrame()->url(); - if (!ExtensionRendererInfo::ExtensionBindingsAllowed(url)) + if (!url.SchemeIs(chrome::kExtensionScheme)) return std::string(); - return ExtensionRendererInfo::GetIdByURL(url); + return url.host(); } virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( @@ -626,8 +641,13 @@ void ExtensionProcessBindings::SetPageActions( void ExtensionProcessBindings::SetAPIPermissions( const std::string& extension_id, const std::vector<std::string>& permissions) { - PermissionsList& permissions_list = *GetPermissionsList(extension_id); - permissions_list.assign(permissions.begin(), permissions.end()); + PermissionsMap& permissions_map = *GetPermissionsMap(extension_id); + + // Default all the API permissions to off. We will reset them below. + for (size_t i = 0; i < Extension::kNumPermissions; ++i) + permissions_map[Extension::kPermissionNames[i]] = false; + for (size_t i = 0; i < permissions.size(); ++i) + permissions_map[permissions[i]] = true; } // static @@ -672,8 +692,17 @@ bool ExtensionProcessBindings::HasPermission(const std::string& extension_id, if (separator != std::string::npos) permission_name = permission.substr(0, separator); - PermissionsList& permissions_list = *GetPermissionsList(extension_id); - return Extension::HasApiPermission(permissions_list, permission_name); + // windows and tabs are the same permission. + if (permission_name == "windows") + permission_name = Extension::kTabPermission; + + for (size_t i = 0; i < arraysize(kNonPermissionExtensionPackages); ++i) + if (permission_name == kNonPermissionExtensionPackages[i]) + return true; + + PermissionsMap& permissions_map = *GetPermissionsMap(extension_id); + PermissionsMap::iterator it = permissions_map.find(permission_name); + return (it != permissions_map.end() && it->second); } // static diff --git a/chrome/renderer/extensions/extension_renderer_info.cc b/chrome/renderer/extensions/extension_renderer_info.cc index f4b61a1..9abd4f5 100644 --- a/chrome/renderer/extensions/extension_renderer_info.cc +++ b/chrome/renderer/extensions/extension_renderer_info.cc @@ -29,7 +29,6 @@ void ExtensionRendererInfo::Update(const ViewMsg_ExtensionRendererInfo& info) { id_ = info.id; web_extent_ = info.web_extent; name_ = info.name; - location_ = info.location; icon_url_ = info.icon_url; } @@ -47,18 +46,6 @@ void ExtensionRendererInfo::UpdateExtensions( } // static -std::string ExtensionRendererInfo::GetIdByURL(const GURL& url) { - if (url.SchemeIs(chrome::kExtensionScheme)) - return url.host(); - - ExtensionRendererInfo* info = GetByURL(url); - if (!info) - return ""; - - return info->id(); -} - -// static ExtensionRendererInfo* ExtensionRendererInfo::GetByURL(const GURL& url) { if (url.SchemeIs(chrome::kExtensionScheme)) return GetByID(url.host()); @@ -97,21 +84,3 @@ ExtensionRendererInfo* ExtensionRendererInfo::GetByID( } return NULL; } - -// static -bool ExtensionRendererInfo::ExtensionBindingsAllowed(const GURL& url) { - if (url.SchemeIs(chrome::kExtensionScheme)) - return true; - - if (!extensions_) - return false; - - std::vector<ExtensionRendererInfo>::iterator i = extensions_->begin(); - for (; i != extensions_->end(); ++i) { - if (i->location_ == Extension::COMPONENT && - i->web_extent_.ContainsURL(url)) - return true; - } - - return false; -} diff --git a/chrome/renderer/extensions/extension_renderer_info.h b/chrome/renderer/extensions/extension_renderer_info.h index 926f275..ec0d9a3 100644 --- a/chrome/renderer/extensions/extension_renderer_info.h +++ b/chrome/renderer/extensions/extension_renderer_info.h @@ -10,7 +10,6 @@ #include <vector> #include "base/gtest_prod_util.h" -#include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_extent.h" #include "googleurl/src/gurl.h" @@ -35,13 +34,6 @@ class ExtensionRendererInfo { // Returns the extension ID that the given URL is a part of, or empty if // none. This includes web URLs that are part of an extension's web extent. - static std::string GetIdByURL(const GURL& url); - - // Returns the ExtensionRendererInfo that the given URL is a part of, or NULL - // if none. This includes web URLs that are part of an extension's web extent. - // NOTE: This can return NULL if called before UpdateExtensions receives - // bulk extension data (e.g. if called from - // EventBindings::HandleContextCreated) static ExtensionRendererInfo* GetByURL(const GURL& url); // Returns true if |new_url| is in the extent of the same extension as @@ -51,11 +43,6 @@ class ExtensionRendererInfo { // Look up an ExtensionInfo object by id. static ExtensionRendererInfo* GetByID(const std::string& id); - // Returns true if |url| should get extension api bindings and be permitted - // to make api calls. Note that this is independent of what extension - // permissions the given extension has been granted. - static bool ExtensionBindingsAllowed(const GURL& url); - private: void Update(const ViewMsg_ExtensionRendererInfo& info); @@ -64,7 +51,6 @@ class ExtensionRendererInfo { std::string id_; ExtensionExtent web_extent_; std::string name_; - Extension::Location location_; GURL icon_url_; // static diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc index 484ba54..636e33f 100644 --- a/chrome/renderer/mock_render_thread.cc +++ b/chrome/renderer/mock_render_thread.cc @@ -10,7 +10,6 @@ #include "base/process_util.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" -#include "chrome/common/url_constants.h" #include "ipc/ipc_message_utils.h" #include "ipc/ipc_sync_message.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h index 54c0c44..d4ee0aa 100644 --- a/chrome/renderer/mock_render_thread.h +++ b/chrome/renderer/mock_render_thread.h @@ -56,6 +56,7 @@ class MockRenderThread : public RenderThreadBase { virtual bool IsExtensionProcess() const { return is_extension_process_; } void SetExtensionProcess(bool value) { is_extension_process_ = value; } + ////////////////////////////////////////////////////////////////////////// // The following functions are called by the test itself. diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index a3f0120..4ad6a3f 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -853,46 +853,32 @@ void RenderThread::EnsureWebKitInitialized() { WebScriptController::registerExtension( extensions_v8::ExternalExtension::Get()); - // TODO(rafaelw). Note that extension-related v8 extensions are being - // bound currently based on is_extension_process_. This means that - // non-extension renderers that slip into an extension process (for example, - // an extension page opening an iframe) will be extension bindings setup. - // This should be relatively rare, and the offending page won't be able to - // make extension API requests because it'll be denied on both sides of - // the renderer by a permission check. However, this is still fairly lame - // and we should consider implementing a V8Proxy delegate that calls out - // to the render thread and makes a decision as to whether to bind these - // extensions based on the frame's url. - // See: crbug.com/53610. + const WebKit::WebString kExtensionScheme = + WebKit::WebString::fromUTF8(chrome::kExtensionScheme); - if (is_extension_process_) - WebScriptController::registerExtension(ExtensionProcessBindings::Get()); + WebScriptController::registerExtension( + ExtensionProcessBindings::Get(), kExtensionScheme); WebScriptController::registerExtension( BaseJsV8Extension::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension(BaseJsV8Extension::Get()); - + WebScriptController::registerExtension( + BaseJsV8Extension::Get(), kExtensionScheme); WebScriptController::registerExtension( JsonSchemaJsV8Extension::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension(JsonSchemaJsV8Extension::Get()); - + WebScriptController::registerExtension(JsonSchemaJsV8Extension::Get(), + kExtensionScheme); WebScriptController::registerExtension( EventBindings::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension(EventBindings::Get()); - + WebScriptController::registerExtension(EventBindings::Get(), + kExtensionScheme); WebScriptController::registerExtension( RendererExtensionBindings::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension(RendererExtensionBindings::Get()); - + WebScriptController::registerExtension( + RendererExtensionBindings::Get(), kExtensionScheme); + WebScriptController::registerExtension( + ExtensionApiTestV8Extension::Get(), kExtensionScheme); WebScriptController::registerExtension( ExtensionApiTestV8Extension::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension( - ExtensionApiTestV8Extension::Get()); web_database_observer_impl_.reset(new WebDatabaseObserverImpl(this)); WebKit::WebDatabase::setObserver(web_database_observer_impl_.get()); diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index f5856a7..fee9b4c 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -27,9 +27,6 @@ var chrome = chrome || {}; // ensure we don't expose the APIs in that case. if (!IsExtensionProcess()) { chromeHidden.onLoad.addListener(function (extensionId) { - if (!extensionId) { - return; - } chrome.initExtension(extensionId, false); }); return; @@ -299,9 +296,6 @@ var chrome = chrome || {}; } chromeHidden.onLoad.addListener(function (extensionId) { - if (!extensionId) { - return; - } chrome.initExtension(extensionId, false); // |apiFunctions| is a hash of name -> object that stores the |