Commit b8dffe56 authored by rdevlin.cronin's avatar rdevlin.cronin Committed by Commit bot

[Extensions] Enable the scripts-require-action feature based on all-urls pref

The scripts-require-action feature should affect all extensions that don't have
the "can run on all urls" preference. When an extension is installed, it should
have the "all urls" flag by default if the switch is off.

This is necessary in order to allow syncing the all urls flag.

BUG=454832

Review URL: https://codereview.chromium.org/874683005

Cr-Commit-Position: refs/heads/master@{#315153}
parent 681ceae0
......@@ -37,31 +37,11 @@
namespace extensions {
namespace {
// Returns true if the extension should be regarded as a "permitted" extension
// for the case of metrics. We need this because we only actually withhold
// permissions if the switch is enabled, but want to record metrics in all
// cases.
// "ExtensionWouldHaveHadHostPermissionsWithheldIfSwitchWasOn()" would be
// more accurate, but too long.
bool ShouldRecordExtension(const Extension* extension) {
return extension->ShouldDisplayInExtensionSettings() &&
!Manifest::IsPolicyLocation(extension->location()) &&
!Manifest::IsComponentLocation(extension->location()) &&
!PermissionsData::CanExecuteScriptEverywhere(extension) &&
extension->permissions_data()
->active_permissions()
->ShouldWarnAllHosts();
}
} // namespace
ActiveScriptController::ActiveScriptController(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
browser_context_(web_contents->GetBrowserContext()),
enabled_(FeatureSwitch::scripts_require_action()->IsEnabled()),
was_used_on_page_(false),
extension_registry_observer_(this) {
CHECK(web_contents);
extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
......@@ -143,7 +123,7 @@ void ActiveScriptController::OnClicked(const Extension* extension) {
}
bool ActiveScriptController::WantsToRun(const Extension* extension) {
return enabled_ && pending_requests_.count(extension->id()) > 0;
return pending_requests_.count(extension->id()) > 0;
}
PermissionsData::AccessType
......@@ -152,11 +132,6 @@ ActiveScriptController::RequiresUserConsentForScriptInjection(
UserScript::InjectionType type) {
CHECK(extension);
// If the feature is not enabled, we automatically allow all extensions to
// run scripts.
if (!enabled_)
permitted_extensions_.insert(extension->id());
// Allow the extension if it's been explicitly granted permission.
if (permitted_extensions_.count(extension->id()) > 0)
return PermissionsData::ACCESS_ALLOWED;
......@@ -187,6 +162,8 @@ void ActiveScriptController::RequestScriptInjection(
// to run.
if (list.size() == 1u)
NotifyChange(extension);
was_used_on_page_ = true;
}
void ActiveScriptController::RunPendingForExtension(
......@@ -253,8 +230,9 @@ void ActiveScriptController::OnRequestScriptInjectionPermission(
// ran (because this feature is not enabled). Add the extension to the list of
// permitted extensions (for metrics), and return immediately.
if (request_id == -1) {
if (ShouldRecordExtension(extension)) {
DCHECK(!enabled_);
if (util::ScriptsMayRequireActionForExtension(
extension,
extension->permissions_data()->active_permissions().get())) {
permitted_extensions_.insert(extension->id());
}
return;
......@@ -313,9 +291,9 @@ void ActiveScriptController::LogUMA() const {
"Extensions.ActiveScriptController.ShownActiveScriptsOnPage",
pending_requests_.size());
// We only log the permitted extensions metric if the feature is enabled,
// because otherwise the data will be boring (100% allowed).
if (enabled_) {
// We only log the permitted extensions metric if the feature was used at all
// on the page, because otherwise the data will be boring.
if (was_used_on_page_) {
UMA_HISTOGRAM_COUNTS_100(
"Extensions.ActiveScriptController.PermittedExtensions",
permitted_extensions_.size());
......@@ -344,6 +322,7 @@ void ActiveScriptController::DidNavigateMainFrame(
LogUMA();
permitted_extensions_.clear();
pending_requests_.clear();
was_used_on_page_ = false;
}
void ActiveScriptController::OnExtensionUnloaded(
......
......@@ -130,10 +130,9 @@ class ActiveScriptController : public content::WebContentsObserver,
// The associated browser context.
content::BrowserContext* browser_context_;
// Whether or not the ActiveScriptController is enabled (corresponding to the
// kActiveScriptEnforcement switch). If it is not, it acts as an empty shell,
// always allowing scripts to run and never displaying actions.
bool enabled_;
// Whether or not the feature was used for any extensions. This may not be the
// case if the user never enabled the scripts-require-action flag.
bool was_used_on_page_;
// The map of extension_id:pending_request of all pending requests.
PendingRequestMap pending_requests_;
......
......@@ -598,42 +598,4 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, ManagementPolicy) {
EXPECT_FALSE(InstallExtension(crx_path, 0));
}
IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, WithheldElevationCheck) {
// Enable consent flag and install extension. The <all_hosts> permission will
// be withheld.
scoped_ptr<FeatureSwitch::ScopedOverride> enable_scripts_switch(
new FeatureSwitch::ScopedOverride(
FeatureSwitch::scripts_require_action(), true));
const char kManifest[] =
"{"
" \"name\": \"Withheld test\","
" \"version\": \"1.0\","
" \"permissions\": ["
" \"http://*/*\""
" ],"
" \"manifest_version\": 2"
"}";
TestExtensionDir dir;
dir.WriteManifest(kManifest);
base::FilePath crx_path = dir.Pack();
EXPECT_FALSE(crx_path.empty());
const Extension* extension = InstallExtension(crx_path, 1);
EXPECT_TRUE(base::PathExists(extension->path()));
std::string extension_id = extension->id();
ExtensionRegistry* registry = ExtensionRegistry::Get(
browser()->profile());
EXPECT_TRUE(registry->enabled_extensions().GetByID(extension_id));
// Disable consent flag and reinstall extension. It should now be disabled
// because previously withheld permissions are now being requested.
enable_scripts_switch.reset();
extension = InstallExtension(crx_path, -1);
EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id));
EXPECT_TRUE(registry->disabled_extensions().GetByID(extension_id));
EXPECT_TRUE(ExtensionPrefs::Get(browser()->profile())->GetDisableReasons(
extension_id) & Extension::DISABLE_PERMISSIONS_INCREASE);
}
} // namespace extensions
......@@ -329,23 +329,22 @@ TEST_F(ExtensionUITest, ExtensionUIAllUrlsCheckbox) {
scoped_ptr<base::DictionaryValue> value(handler()->CreateExtensionDetailValue(
all_urls_extension.get(), std::vector<ExtensionPage>(), NULL));
bool result = false;
const std::string kWantsAllUrls = "wantsAllUrls";
const std::string kShowAllUrls = "showAllUrls";
const std::string kAllowAllUrls = "allowAllUrls";
// The extension should want all urls, but not currently have it.
EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result));
EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result));
EXPECT_TRUE(result);
EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result));
EXPECT_FALSE(result);
// Give the extension all urls.
util::SetAllowedScriptingOnAllUrls(
all_urls_extension->id(), profile(), true);
util::SetAllowedScriptingOnAllUrls(all_urls_extension->id(), profile(), true);
// Now the extension should both want and have all urls.
value.reset(handler()->CreateExtensionDetailValue(
all_urls_extension.get(), std::vector<ExtensionPage>(), NULL));
EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result));
EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result));
EXPECT_TRUE(result);
EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result));
EXPECT_TRUE(result);
......@@ -353,20 +352,34 @@ TEST_F(ExtensionUITest, ExtensionUIAllUrlsCheckbox) {
// The other extension should neither want nor have all urls.
value.reset(handler()->CreateExtensionDetailValue(
no_urls_extension.get(), std::vector<ExtensionPage>(), NULL));
EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result));
EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result));
EXPECT_FALSE(result);
EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result));
EXPECT_FALSE(result);
// Revoke the first extension's permissions.
util::SetAllowedScriptingOnAllUrls(
all_urls_extension->id(), profile(), false);
// Turn off the switch and load another extension (so permissions are
// re-initialized).
enable_scripts_switch.reset();
// Even though the extension has the all urls preference, the checkbox
// shouldn't show up with the switch off.
// Since the extension doesn't have access to all urls (but normally would),
// the extension should have the "want" flag even with the switch off.
value.reset(handler()->CreateExtensionDetailValue(
all_urls_extension.get(), std::vector<ExtensionPage>(), NULL));
EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result));
EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result));
EXPECT_TRUE(result);
EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result));
EXPECT_FALSE(result);
// If we grant the extension all urls, then it should no longer "want" it,
// since it is back in its normal state (with the switch off).
util::SetAllowedScriptingOnAllUrls(all_urls_extension->id(), profile(), true);
value.reset(handler()->CreateExtensionDetailValue(
all_urls_extension.get(), std::vector<ExtensionPage>(), NULL));
EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result));
EXPECT_FALSE(result);
EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result));
EXPECT_TRUE(result);
......@@ -379,10 +392,10 @@ TEST_F(ExtensionUITest, ExtensionUIAllUrlsCheckbox) {
// show up without the switch.
value.reset(handler()->CreateExtensionDetailValue(
all_urls_extension.get(), std::vector<ExtensionPage>(), NULL));
EXPECT_TRUE(value->GetBoolean(kWantsAllUrls, &result));
EXPECT_TRUE(value->GetBoolean(kShowAllUrls, &result));
EXPECT_FALSE(result);
EXPECT_TRUE(value->GetBoolean(kAllowAllUrls, &result));
EXPECT_FALSE(result);
EXPECT_TRUE(result);
}
} // namespace extensions
......@@ -70,6 +70,35 @@ std::string ReloadExtensionIfEnabled(const std::string& extension_id,
return id;
}
// Sets the preference for scripting on all urls to |allowed|, optionally
// updating the extension's active permissions (based on |update_permissions|).
void SetAllowedScriptingOnAllUrlsHelper(
content::BrowserContext* context,
const std::string& extension_id,
bool allowed,
bool update_permissions) {
// TODO(devlin): Right now, we always need to have a value for this pref.
// Once the scripts-require-action feature launches, we can change the set
// to be null if false.
ExtensionPrefs::Get(context)->UpdateExtensionPref(
extension_id,
kExtensionAllowedOnAllUrlsPrefName,
new base::FundamentalValue(allowed));
if (update_permissions) {
const Extension* extension =
ExtensionRegistry::Get(context)->enabled_extensions().GetByID(
extension_id);
if (extension) {
PermissionsUpdater updater(context);
if (allowed)
updater.GrantWithheldImpliedAllHosts(extension);
else
updater.WithholdImpliedAllHosts(extension);
}
}
}
} // namespace
bool IsIncognitoEnabled(const std::string& extension_id,
......@@ -176,46 +205,42 @@ void SetAllowFileAccess(const std::string& extension_id,
bool AllowedScriptingOnAllUrls(const std::string& extension_id,
content::BrowserContext* context) {
bool allowed = false;
return ExtensionPrefs::Get(context)->ReadPrefAsBoolean(
extension_id,
ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
if (!prefs->ReadPrefAsBoolean(extension_id,
kExtensionAllowedOnAllUrlsPrefName,
&allowed) &&
allowed;
&allowed)) {
// If there is no value present, we make one, defaulting it to the value of
// the 'scripts require action' flag. If the flag is on, then the extension
// does not have permission to script on all urls by default.
allowed = DefaultAllowedScriptingOnAllUrls();
SetAllowedScriptingOnAllUrlsHelper(context, extension_id, allowed, false);
}
return allowed;
}
void SetAllowedScriptingOnAllUrls(const std::string& extension_id,
content::BrowserContext* context,
bool allowed) {
if (allowed == AllowedScriptingOnAllUrls(extension_id, context))
return; // Nothing to do here.
ExtensionPrefs::Get(context)->UpdateExtensionPref(
extension_id,
kExtensionAllowedOnAllUrlsPrefName,
allowed ? new base::FundamentalValue(true) : NULL);
if (allowed != AllowedScriptingOnAllUrls(extension_id, context))
SetAllowedScriptingOnAllUrlsHelper(context, extension_id, allowed, true);
}
const Extension* extension =
ExtensionRegistry::Get(context)->enabled_extensions().GetByID(
extension_id);
if (extension) {
PermissionsUpdater updater(context);
if (allowed)
updater.GrantWithheldImpliedAllHosts(extension);
else
updater.WithholdImpliedAllHosts(extension);
}
bool DefaultAllowedScriptingOnAllUrls() {
return !FeatureSwitch::scripts_require_action()->IsEnabled();
}
bool ScriptsMayRequireActionForExtension(const Extension* extension) {
// An extension requires user action to execute scripts 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.
return FeatureSwitch::scripts_require_action()->IsEnabled() &&
extension->ShouldDisplayInExtensionSettings() &&
bool ScriptsMayRequireActionForExtension(
const Extension* extension,
const PermissionSet* permissions) {
// An extension may require user action to execute scripts iff the extension
// shows up in chrome:extensions (so the user can grant withheld permissions),
// is not part of chrome or corporate policy, not on the scripting whitelist,
// and requires enough permissions that we should withhold them.
return extension->ShouldDisplayInExtensionSettings() &&
!Manifest::IsPolicyLocation(extension->location()) &&
!Manifest::IsComponentLocation(extension->location()) &&
!PermissionsData::CanExecuteScriptEverywhere(extension);
!PermissionsData::CanExecuteScriptEverywhere(extension) &&
permissions->ShouldWarnAllHosts();
}
bool IsAppLaunchable(const std::string& extension_id,
......
......@@ -26,6 +26,7 @@ namespace extensions {
class Extension;
struct ExtensionInfo;
class PermissionSet;
namespace util {
......@@ -68,6 +69,9 @@ void SetAllowFileAccess(const std::string& extension_id,
bool AllowedScriptingOnAllUrls(const std::string& extension_id,
content::BrowserContext* context);
// Returns the default value for being allowed to script on all urls.
bool DefaultAllowedScriptingOnAllUrls();
// Sets whether the extension with |extension_id| is allowed to execute scripts
// on all urls (exempting chrome:// urls, etc) without explicit user consent.
// This should only be used with FeatureSwitch::scripts_require_action()
......@@ -77,8 +81,12 @@ void SetAllowedScriptingOnAllUrls(const std::string& extension_id,
bool allowed);
// Returns true if the --scripts-require-action flag would possibly affect
// the given |extension|.
bool ScriptsMayRequireActionForExtension(const Extension* extension);
// the given |extension| and |permissions|. We pass in the |permissions|
// explicitly, as we may need to check with permissions other than the ones
// that are currently on the extension's PermissionsData.
bool ScriptsMayRequireActionForExtension(
const Extension* extension,
const PermissionSet* permissions);
// Returns true if |extension_id| can be launched (possibly only after being
// enabled).
......
......@@ -182,13 +182,13 @@ void PermissionsUpdater::InitializePermissions(const Extension* extension) {
bounded_active = GetBoundedActivePermissions(extension, active_permissions);
}
// Withhold permissions if the switch applies to this extension.
// Non-transient extensions also must not have the preference to allow
// scripting on all urls.
bool should_withhold_permissions =
util::ScriptsMayRequireActionForExtension(extension);
if ((init_flag_ & INIT_FLAG_TRANSIENT) == 0) {
should_withhold_permissions &=
// Determine whether or not to withhold host permissions.
bool should_withhold_permissions = false;
if (util::ScriptsMayRequireActionForExtension(extension,
bounded_active.get())) {
should_withhold_permissions =
init_flag_ & INIT_FLAG_TRANSIENT ?
!util::DefaultAllowedScriptingOnAllUrls() :
!util::AllowedScriptingOnAllUrls(extension->id(), browser_context_);
}
......
......@@ -11,10 +11,12 @@
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/permissions_updater.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_test_util.h"
#include "chrome/test/base/testing_profile.h"
#include "components/crx_file/id_util.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
......@@ -36,7 +38,8 @@ namespace {
scoped_refptr<const Extension> CreateExtensionWithPermissions(
const std::set<URLPattern>& scriptable_hosts,
const std::set<URLPattern>& explicit_hosts,
Manifest::Location location) {
Manifest::Location location,
const std::string& name) {
ListBuilder scriptable_host_list;
for (std::set<URLPattern>::const_iterator pattern = scriptable_hosts.begin();
pattern != scriptable_hosts.end();
......@@ -59,12 +62,13 @@ scoped_refptr<const Extension> CreateExtensionWithPermissions(
.SetLocation(location)
.SetManifest(
DictionaryBuilder()
.Set("name", "extension")
.Set("name", name)
.Set("description", "foo")
.Set("manifest_version", 2)
.Set("version", "0.1.2.3")
.Set("content_scripts", ListBuilder().Append(script.Pass()))
.Set("permissions", explicit_host_list.Pass()))
.SetID(crx_file::id_util::GenerateId(name))
.Build();
}
......@@ -300,7 +304,7 @@ TEST_F(PermissionsUpdaterTest, WithholdAllHosts) {
all_host_patterns, safe_patterns);
scoped_refptr<const Extension> extension = CreateExtensionWithPermissions(
all_patterns, all_patterns, Manifest::INTERNAL);
all_patterns, all_patterns, Manifest::INTERNAL, "a");
const PermissionsData* permissions_data = extension->permissions_data();
PermissionsUpdater updater(profile_.get());
updater.InitializePermissions(extension.get());
......@@ -359,7 +363,7 @@ TEST_F(PermissionsUpdaterTest, WithholdAllHosts) {
// Creating a component extension should result in no withheld permissions.
extension = CreateExtensionWithPermissions(
all_patterns, all_patterns, Manifest::COMPONENT);
all_patterns, all_patterns, Manifest::COMPONENT, "b");
permissions_data = extension->permissions_data();
updater.InitializePermissions(extension.get());
EXPECT_TRUE(SetsAreEqual(
......@@ -380,7 +384,7 @@ TEST_F(PermissionsUpdaterTest, WithholdAllHosts) {
// Without the switch, we shouldn't withhold anything.
switch_override.reset();
extension = CreateExtensionWithPermissions(
all_patterns, all_patterns, Manifest::INTERNAL);
all_patterns, all_patterns, Manifest::INTERNAL, "c");
permissions_data = extension->permissions_data();
updater.InitializePermissions(extension.get());
EXPECT_TRUE(SetsAreEqual(
......@@ -399,4 +403,73 @@ TEST_F(PermissionsUpdaterTest, WithholdAllHosts) {
.empty());
}
// Tests that withholding all hosts behaves properly with extensions installed
// when the switch is turned on and off.
TEST_F(PermissionsUpdaterTest, WithholdAllHostsWithTransientSwitch) {
InitializeEmptyExtensionService();
URLPattern all_hosts(URLPattern::SCHEME_ALL, "<all_urls>");
std::set<URLPattern> all_host_patterns;
all_host_patterns.insert(all_hosts);
scoped_refptr<const Extension> extension_a = CreateExtensionWithPermissions(
all_host_patterns, all_host_patterns, Manifest::INTERNAL, "a");
PermissionsUpdater updater(profile());
updater.InitializePermissions(extension_a.get());
const PermissionsData* permissions_data = extension_a->permissions_data();
// Since the extension was created without the switch on, it should default
// to having all urls access.
EXPECT_TRUE(SetsAreEqual(
permissions_data->active_permissions()->scriptable_hosts().patterns(),
all_host_patterns));
EXPECT_TRUE(
permissions_data->withheld_permissions()->scriptable_hosts().is_empty());
EXPECT_TRUE(util::AllowedScriptingOnAllUrls(extension_a->id(), profile()));
// Enable the switch, and re-init permission for the extension.
scoped_ptr<FeatureSwitch::ScopedOverride> switch_override(
new FeatureSwitch::ScopedOverride(FeatureSwitch::scripts_require_action(),
FeatureSwitch::OVERRIDE_ENABLED));
updater.InitializePermissions(extension_a.get());
// Since the extension was installed when the switch was off, it should still
// have the all urls pref.
permissions_data = extension_a->permissions_data();
EXPECT_TRUE(SetsAreEqual(
permissions_data->active_permissions()->scriptable_hosts().patterns(),
all_host_patterns));
EXPECT_TRUE(
permissions_data->withheld_permissions()->scriptable_hosts().is_empty());
EXPECT_TRUE(util::AllowedScriptingOnAllUrls(extension_a->id(), profile()));
// Load a new extension, which also has all urls. Since the switch is now on,
// the permissions should be withheld.
scoped_refptr<const Extension> extension_b = CreateExtensionWithPermissions(
all_host_patterns, all_host_patterns, Manifest::INTERNAL, "b");
updater.InitializePermissions(extension_b.get());
permissions_data = extension_b->permissions_data();
EXPECT_TRUE(
permissions_data->active_permissions()->scriptable_hosts().is_empty());
EXPECT_TRUE(SetsAreEqual(
permissions_data->withheld_permissions()->scriptable_hosts().patterns(),
all_host_patterns));
EXPECT_FALSE(util::AllowedScriptingOnAllUrls(extension_b->id(), profile()));
// Disable the switch, and reload the extension.
switch_override.reset();
updater.InitializePermissions(extension_b.get());
// Since the extension was installed with the switch on, it should still be
// restricted with the switch off.
permissions_data = extension_b->permissions_data();
EXPECT_TRUE(
permissions_data->active_permissions()->scriptable_hosts().is_empty());
EXPECT_TRUE(SetsAreEqual(
permissions_data->withheld_permissions()->scriptable_hosts().patterns(),
all_host_patterns));
EXPECT_FALSE(util::AllowedScriptingOnAllUrls(extension_b->id(), profile()));
}
} // namespace extensions
......@@ -51,6 +51,7 @@
* prettifiedPath: (string|undefined),
* recommendedInstall: boolean,
* runtimeErrors: (Array.<RuntimeError>|undefined),
* showAllUrls: boolean,
* suspiciousInstall: boolean,
* terminated: boolean,
* updateRequiredByPolicy: boolean,
......@@ -58,7 +59,6 @@
* views: Array.<{renderViewId: number, renderProcessId: number,
* path: string, incognito: boolean,
* generatedBackgroundPage: boolean}>,
* wantsAllUrls: boolean,
* wantsErrorCollection: boolean,
* wantsFileAccess: boolean,
* warnings: (Array|undefined)}}
......@@ -258,7 +258,7 @@ cr.define('options', function() {
// The 'allow on all urls' checkbox. This should only be visible if
// active script restrictions are enabled. If they are not enabled, no
// extensions should want all urls.
if (extension.wantsAllUrls) {
if (extension.showAllUrls) {
var allUrls = node.querySelector('.all-urls-control');
allUrls.addEventListener('click', function(e) {
chrome.send('extensionSettingsAllowOnAllUrls',
......
......@@ -335,16 +335,17 @@ base::DictionaryValue* ExtensionSettingsHandler::CreateExtensionDetailValue(
}
extension_data->Set("dependentExtensions", dependents_list);
// Extensions only want all URL access if:
// We show the "all urls" checkbox if:
// - The feature is enabled for the given extension.
// - The extension has access to enough urls that we can't just let it run
// on those specified in the permissions.
bool wants_all_urls =
util::ScriptsMayRequireActionForExtension(extension) &&
(extension->permissions_data()->HasWithheldImpliedAllHosts() ||
util::AllowedScriptingOnAllUrls(
extension->id(), extension_service_->GetBrowserContext()));
extension_data->SetBoolean("wantsAllUrls", wants_all_urls);
bool show_all_urls =
(FeatureSwitch::scripts_require_action()->IsEnabled() &&
util::ScriptsMayRequireActionForExtension(
extension,
extension->permissions_data()->active_permissions().get())) ||
extension->permissions_data()->HasWithheldImpliedAllHosts();
extension_data->SetBoolean("showAllUrls", show_all_urls);
extension_data->SetBoolean(
"allowAllUrls",
util::AllowedScriptingOnAllUrls(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment