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

Unified Diff: chrome/browser/extensions/permissions_updater.cc

Issue 348313003: Create withheld permissions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Latest master Created 6 years, 5 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/browser/extensions/permissions_updater.cc
diff --git a/chrome/browser/extensions/permissions_updater.cc b/chrome/browser/extensions/permissions_updater.cc
index 9d4a7b6f9dcabf2084940fc0ab69304650d20910..d95f812f68813406144a27be1f73a34871335c27 100644
--- a/chrome/browser/extensions/permissions_updater.cc
+++ b/chrome/browser/extensions/permissions_updater.cc
@@ -9,6 +9,7 @@
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/permissions/permissions_api_helpers.h"
+#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/permissions.h"
#include "content/public/browser/notification_observer.h"
@@ -19,9 +20,12 @@
#include "extensions/browser/extension_prefs.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_messages.h"
+#include "extensions/common/feature_switch.h"
#include "extensions/common/manifest_handlers/permissions_parser.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/common/url_pattern.h"
+#include "extensions/common/url_pattern_set.h"
using content::RenderProcessHost;
using extensions::permissions_api_helpers::PackPermissionSet;
@@ -30,6 +34,61 @@ namespace extensions {
namespace permissions = api::permissions;
+namespace {
+
+// Returns a PermissionSet that has the active permissions of the extension,
+// bounded to its current manifest.
+scoped_refptr<const PermissionSet> GetBoundedActivePermissions(
+ const Extension* extension, ExtensionPrefs* extension_prefs) {
+ // If the extension has used the optional permissions API, it will have a
+ // custom set of active permissions defined in the extension prefs. Here,
+ // we update the extension's active permissions based on the prefs.
+ scoped_refptr<const PermissionSet> active_permissions =
+ extension_prefs->GetActivePermissions(extension->id());
+ if (!active_permissions)
+ return extension->permissions_data()->active_permissions();
+
+ scoped_refptr<const PermissionSet> required_permissions =
+ PermissionsParser::GetRequiredPermissions(extension);
+
+ // We restrict the active permissions to be within the bounds defined in the
+ // extension's manifest.
+ // a) active permissions must be a subset of optional + default permissions
+ // b) active permissions must contains all default permissions
+ scoped_refptr<PermissionSet> total_permissions = PermissionSet::CreateUnion(
+ required_permissions,
+ PermissionsParser::GetOptionalPermissions(extension));
+
+ // Make sure the active permissions contain no more than optional + default.
+ scoped_refptr<PermissionSet> adjusted_active =
+ PermissionSet::CreateIntersection(total_permissions, active_permissions);
+
+ // Make sure the active permissions contain the default permissions.
+ adjusted_active =
+ PermissionSet::CreateUnion(required_permissions, adjusted_active);
+
+ return adjusted_active;
+}
+
+// Divvy up the |url patterns| between those we grant and those we do not. If
+// |withhold_permissions| is false (because the requisite feature is not
+// enabled), no permissions are withheld.
+void SegregateUrlPermissions(const URLPatternSet& url_patterns,
+ bool withhold_permissions,
+ URLPatternSet* granted,
+ URLPatternSet* withheld) {
+ for (URLPatternSet::const_iterator iter = url_patterns.begin();
+ iter != url_patterns.end();
+ ++iter) {
+ if (withhold_permissions && iter->ImpliesAllHosts())
+ withheld->AddPattern(*iter);
+ else
+ granted->AddPattern(*iter);
+ }
+}
+
+} // namespace
+
PermissionsUpdater::PermissionsUpdater(content::BrowserContext* browser_context)
: browser_context_(browser_context) {
}
@@ -45,7 +104,7 @@ void PermissionsUpdater::AddPermissions(
scoped_refptr<PermissionSet> added(
PermissionSet::CreateDifference(total.get(), existing.get()));
- SetActivePermissions(extension, total.get());
+ SetPermissions(extension, total, NULL);
// Update the granted permissions so we don't auto-disable the extension.
GrantActivePermissions(extension);
@@ -65,7 +124,7 @@ void PermissionsUpdater::RemovePermissions(
// We update the active permissions, and not the granted permissions, because
// the extension, not the user, removed the permissions. This allows the
// extension to add them again without prompting the user.
- SetActivePermissions(extension, total.get());
+ SetPermissions(extension, total, NULL);
NotifyPermissionsUpdated(REMOVED, extension, removed.get());
}
@@ -84,42 +143,122 @@ void PermissionsUpdater::GrantActivePermissions(const Extension* extension) {
extension->permissions_data()->active_permissions().get());
}
-void PermissionsUpdater::InitializeActivePermissions(
- const Extension* extension) {
- // If the extension has used the optional permissions API, it will have a
- // custom set of active permissions defined in the extension prefs. Here,
- // we update the extension's active permissions based on the prefs.
- scoped_refptr<PermissionSet> active_permissions =
- ExtensionPrefs::Get(browser_context_)->GetActivePermissions(
- extension->id());
- if (!active_permissions)
- return;
-
- // We restrict the active permissions to be within the bounds defined in the
- // extension's manifest.
- // a) active permissions must be a subset of optional + default permissions
- // b) active permissions must contains all default permissions
- scoped_refptr<PermissionSet> total_permissions = PermissionSet::CreateUnion(
- PermissionsParser::GetRequiredPermissions(extension),
- PermissionsParser::GetOptionalPermissions(extension));
-
- // Make sure the active permissions contain no more than optional + default.
- scoped_refptr<PermissionSet> adjusted_active =
- PermissionSet::CreateIntersection(total_permissions, active_permissions);
+void PermissionsUpdater::InitializePermissions(const Extension* extension) {
+ scoped_refptr<const PermissionSet> bounded_active =
+ GetBoundedActivePermissions(extension,
+ ExtensionPrefs::Get(browser_context_));
+
+ // We withhold permissions iff the switch to do so is enabled, the extension
+ // shows up in chrome:extensions (so the user can grant withheld permissions),
+ // the extension is not part of chrome or corporate policy, and also not on
+ // the scripting whitelist. Additionally, we don't withhold if the extension
+ // has the preference to allow scripting on all urls.
+ bool should_withhold_permissions =
+ FeatureSwitch::scripts_require_action()->IsEnabled() &&
+ extension->ShouldDisplayInExtensionSettings() &&
+ !Manifest::IsPolicyLocation(extension->location()) &&
+ !Manifest::IsComponentLocation(extension->location()) &&
+ !PermissionsData::CanExecuteScriptEverywhere(extension) &&
+ !util::AllowedScriptingOnAllUrls(extension->id(), browser_context_);
+
+ URLPatternSet granted_explicit_hosts;
+ URLPatternSet withheld_explicit_hosts;
+ SegregateUrlPermissions(bounded_active->explicit_hosts(),
+ should_withhold_permissions,
+ &granted_explicit_hosts,
+ &withheld_explicit_hosts);
+
+ URLPatternSet granted_scriptable_hosts;
+ URLPatternSet withheld_scriptable_hosts;
+ SegregateUrlPermissions(bounded_active->scriptable_hosts(),
+ should_withhold_permissions,
+ &granted_scriptable_hosts,
+ &withheld_scriptable_hosts);
+
+ bounded_active = new PermissionSet(bounded_active->apis(),
+ bounded_active->manifest_permissions(),
+ granted_explicit_hosts,
+ granted_scriptable_hosts);
+
+ scoped_refptr<const PermissionSet> withheld =
+ new PermissionSet(APIPermissionSet(),
+ ManifestPermissionSet(),
+ withheld_explicit_hosts,
+ withheld_scriptable_hosts);
+ SetPermissions(extension, bounded_active, withheld);
+}
- // Make sure the active permissions contain the default permissions.
- adjusted_active = PermissionSet::CreateUnion(
- PermissionsParser::GetRequiredPermissions(extension),
- adjusted_active);
+void PermissionsUpdater::WithholdImpliedAllHosts(const Extension* extension) {
+ scoped_refptr<const PermissionSet> active =
+ extension->permissions_data()->active_permissions();
+ scoped_refptr<const PermissionSet> withheld =
+ extension->permissions_data()->withheld_permissions();
+
+ URLPatternSet withheld_scriptable = withheld->scriptable_hosts();
+ URLPatternSet active_scriptable;
+ SegregateUrlPermissions(active->scriptable_hosts(),
+ true, // withhold permissions
+ &active_scriptable,
+ &withheld_scriptable);
+
+ URLPatternSet withheld_explicit = withheld->explicit_hosts();
+ URLPatternSet active_explicit;
+ SegregateUrlPermissions(active->explicit_hosts(),
+ true, // withhold permissions
+ &active_explicit,
+ &withheld_explicit);
+
+ SetPermissions(extension,
+ new PermissionSet(active->apis(),
+ active->manifest_permissions(),
+ active_explicit,
+ active_scriptable),
+ new PermissionSet(withheld->apis(),
+ withheld->manifest_permissions(),
+ withheld_explicit,
+ withheld_scriptable));
+ // TODO(rdevlin.cronin) We should notify the observers/renderer.
+}
- SetActivePermissions(extension, adjusted_active);
+void PermissionsUpdater::GrantWithheldImpliedAllHosts(
+ const Extension* extension) {
+ scoped_refptr<const PermissionSet> active =
+ extension->permissions_data()->active_permissions();
+ scoped_refptr<const PermissionSet> withheld =
+ extension->permissions_data()->withheld_permissions();
+
+ // Move the all-hosts permission from withheld to active.
+ // We can cheat a bit here since we know that the only host permission we
+ // withhold is allhosts (or something similar enough to it), so we can just
+ // grant all withheld host permissions.
+ URLPatternSet explicit_hosts;
+ URLPatternSet::CreateUnion(
+ active->explicit_hosts(), withheld->explicit_hosts(), &explicit_hosts);
+ URLPatternSet scriptable_hosts;
+ URLPatternSet::CreateUnion(active->scriptable_hosts(),
+ withheld->scriptable_hosts(),
+ &scriptable_hosts);
+
+ // Since we only withhold host permissions (so far), we know that withheld
+ // permissions will be empty.
+ SetPermissions(extension,
+ new PermissionSet(active->apis(),
+ active->manifest_permissions(),
+ explicit_hosts,
+ scriptable_hosts),
+ new PermissionSet());
+ // TODO(rdevlin.cronin) We should notify the observers/renderer.
}
-void PermissionsUpdater::SetActivePermissions(
- const Extension* extension, const PermissionSet* permissions) {
+void PermissionsUpdater::SetPermissions(
+ const Extension* extension,
+ const scoped_refptr<const PermissionSet>& active,
+ scoped_refptr<const PermissionSet> withheld) {
+ withheld = withheld.get() ? withheld
+ : extension->permissions_data()->withheld_permissions();
+ extension->permissions_data()->SetPermissions(active, withheld);
ExtensionPrefs::Get(browser_context_)->SetActivePermissions(
- extension->id(), permissions);
- extension->permissions_data()->SetActivePermissions(permissions);
+ extension->id(), active.get());
}
void PermissionsUpdater::DispatchEvent(
@@ -168,12 +307,11 @@ void PermissionsUpdater::NotifyPermissionsUpdated(
content::Details<UpdatedExtensionPermissionsInfo>(&info));
ExtensionMsg_UpdatePermissions_Params params;
- params.reason_id = static_cast<int>(reason);
params.extension_id = extension->id();
- params.apis = changed->apis();
- params.manifest_permissions = changed->manifest_permissions();
- params.explicit_hosts = changed->explicit_hosts();
- params.scriptable_hosts = changed->scriptable_hosts();
+ params.active_permissions = ExtensionMsg_PermissionSetStruct(
+ extension->permissions_data()->active_permissions());
+ params.withheld_permissions = ExtensionMsg_PermissionSetStruct(
+ extension->permissions_data()->withheld_permissions());
// Send the new permissions to the renderers.
for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
« no previous file with comments | « chrome/browser/extensions/permissions_updater.h ('k') | chrome/browser/extensions/permissions_updater_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698