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

Unified Diff: chrome/renderer/extensions/extension_process_bindings.cc

Issue 164039: Add module-level permissions to extensions. (Closed)
Patch Set: final nits Created 11 years, 4 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
« no previous file with comments | « chrome/renderer/extensions/extension_process_bindings.h ('k') | chrome/renderer/render_thread.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/extensions/extension_process_bindings.cc
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index 131b9a037e8ce64368179ae734190b2881a48f30..09a13119e68e0f8fc346fc44cb6742a6bbc03626 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -5,6 +5,7 @@
#include "chrome/renderer/extensions/extension_process_bindings.h"
#include "base/singleton.h"
+#include "chrome/common/extensions/extension.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/extensions/bindings_utils.h"
@@ -30,6 +31,12 @@ namespace {
// A map of extension ID to vector of page action ids.
typedef std::map< std::string, std::vector<std::string> > PageActionIdMap;
+// 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, PermissionsMap> ExtensionPermissionsMap;
+
const char kExtensionName[] = "chrome/ExtensionProcessBindings";
const char* kExtensionDeps[] = {
BaseJsV8Extension::kName,
@@ -41,6 +48,7 @@ const char* kExtensionDeps[] = {
struct SingletonData {
std::set<std::string> function_names_;
PageActionIdMap page_action_ids_;
+ ExtensionPermissionsMap permissions_;
};
static std::set<std::string>* GetFunctionNameSet() {
@@ -51,6 +59,10 @@ static PageActionIdMap* GetPageActionMap() {
return &Singleton<SingletonData>()->page_action_ids_;
}
+static PermissionsMap* GetPermissionsMap(const std::string& extension_id) {
+ return &Singleton<SingletonData>()->permissions_[extension_id];
+}
+
class ExtensionImpl : public ExtensionBase {
public:
ExtensionImpl() : ExtensionBase(
@@ -64,6 +76,18 @@ class ExtensionImpl : public ExtensionBase {
}
}
+ // Note: do not call this function before or during the chromeHidden.onLoad
+ // event dispatch. The URL might not have been committed yet and might not
+ // be an extension URL.
+ static std::string ExtensionIdForCurrentContext() {
+ RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
+ DCHECK(renderview);
+ GURL url = renderview->webview()->GetMainFrame()->GetURL();
+ if (url.SchemeIs(chrome::kExtensionScheme))
+ return url.host();
+ return std::string();
+ }
+
virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
v8::Handle<v8::String> name) {
if (name->Equals(v8::String::New("GetExtensionAPIDefinition"))) {
@@ -84,20 +108,13 @@ class ExtensionImpl : public ExtensionBase {
}
private:
- static std::string ExtensionIdFromCurrentContext() {
- RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
- DCHECK(renderview);
- GURL url = renderview->webview()->GetMainFrame()->GetURL();
- return url.host();
- }
-
static v8::Handle<v8::Value> GetExtensionAPIDefinition(
const v8::Arguments& args) {
return v8::String::New(GetStringResource<IDR_EXTENSION_API_JSON>());
}
static v8::Handle<v8::Value> GetViews(const v8::Arguments& args) {
- std::string extension_id = ExtensionIdFromCurrentContext();
+ std::string extension_id = ExtensionIdForCurrentContext();
ContextList contexts =
bindings_utils::GetContextsForExtension(extension_id);
@@ -145,11 +162,9 @@ class ExtensionImpl : public ExtensionBase {
static v8::Handle<v8::Value> GetCurrentPageActions(
const v8::Arguments& args) {
- std::string extension_id = ExtensionIdFromCurrentContext();
- PageActionIdMap* page_action_map =
- GetPageActionMap();
- PageActionIdMap::const_iterator it =
- page_action_map->find(extension_id);
+ std::string extension_id = *v8::String::Utf8Value(args[0]->ToString());
+ PageActionIdMap* page_action_map = GetPageActionMap();
+ PageActionIdMap::const_iterator it = page_action_map->find(extension_id);
std::vector<std::string> page_actions;
size_t size = 0;
@@ -187,6 +202,9 @@ class ExtensionImpl : public ExtensionBase {
return v8::Undefined();
}
+ if (!ExtensionProcessBindings::CurrentContextHasPermission(name))
+ return ExtensionProcessBindings::ThrowPermissionDeniedException(name);
+
std::string json_args = *v8::String::Utf8Value(args[1]);
int request_id = args[2]->Int32Value();
bool has_callback = args[3]->BooleanValue();
@@ -249,3 +267,75 @@ void ExtensionProcessBindings::SetPageActions(
page_action_map.erase(extension_id);
}
}
+
+// static
+void ExtensionProcessBindings::SetPermissions(
+ const std::string& extension_id,
+ const std::vector<std::string>& permissions) {
+ PermissionsMap& permissions_map = *GetPermissionsMap(extension_id);
+
+ // Default all permissions to false, then enable the ones in the vector.
+ 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;
+}
+
+// Given a name like "tabs.onConnect", return the permission name required
+// to access that API ("tabs" in this example).
+static std::string GetPermissionName(const std::string& function_name) {
+ size_t first_dot = function_name.find('.');
+ std::string permission_name = function_name.substr(0, first_dot);
+ if (permission_name == "windows")
+ return "tabs"; // windows and tabs are the same permission.
+ return permission_name;
+}
+
+// static
+bool ExtensionProcessBindings::CurrentContextHasPermission(
+ const std::string& function_name) {
+ std::string extension_id = ExtensionImpl::ExtensionIdForCurrentContext();
+ PermissionsMap& permissions_map = *GetPermissionsMap(extension_id);
+ std::string permission_name = GetPermissionName(function_name);
+ PermissionsMap::iterator it = permissions_map.find(permission_name);
+
+ // We explicitly check if the permission entry is present and false, because
+ // some APIs do not have a required permission entry (ie, "chrome.self").
+ return (it == permissions_map.end() || it->second);
+}
+
+// static
+v8::Handle<v8::Value>
+ ExtensionProcessBindings::ThrowPermissionDeniedException(
+ const std::string& function_name) {
+ static const char kMessage[] =
+ "You do not have permission to use 'chrome.%s'. Be sure to declare"
+ " in your manifest what permissions you need.";
+ std::string permission_name = GetPermissionName(function_name);
+ std::string error_msg = StringPrintf(kMessage, permission_name.c_str());
+
+#if EXTENSION_TIME_TO_BREAK_API
+ return v8::ThrowException(v8::Exception::Error(
+ v8::String::New(error_msg.c_str())));
+#else
+ // Call console.error for now.
+
+ v8::HandleScope scope;
+
+ v8::Local<v8::Value> console =
+ v8::Context::GetCurrent()->Global()->Get(v8::String::New("console"));
+ v8::Local<v8::Value> console_error;
+ if (!console.IsEmpty() && console->IsObject())
+ console_error = console->ToObject()->Get(v8::String::New("error"));
+ if (console_error.IsEmpty() || !console_error->IsFunction())
+ return v8::Undefined();
+
+ v8::Local<v8::Function> function =
+ v8::Local<v8::Function>::Cast(console_error);
+ v8::Local<v8::Value> argv[] = { v8::String::New(error_msg.c_str()) };
+ if (!function.IsEmpty())
+ function->Call(console->ToObject(), arraysize(argv), argv);
+
+ return v8::Undefined();
+#endif
+}
« no previous file with comments | « chrome/renderer/extensions/extension_process_bindings.h ('k') | chrome/renderer/render_thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698