Commit 013c4006 authored by Rohan Pavone's avatar Rohan Pavone Committed by Commit Bot

[Permissions] Checks if permissions should be overridden.

Determines if platform supports overridden status of permission by
querying PermissionControllerDelegate. Since most delegates have static
permission statuses, this queries the permission status by default.
Overridden classes, such as PermissionManager (used for Chrome) and
WebTestPermissionManager, have dynamic permission settings which are
queried in a different fashion. If permission is not supported, this
is indicated. PermissionControllerImpl, which controls overrides,
uses this decision to choose whether or not to override, which is
then forwarded to the callee. Browser.setPermission uses this to
indicate if setting permission failed/succeeded. Browser.grantPermission
ignores the result.

Design doc: go/chromedriver-permissions-ext

Bug: 976308
Change-Id: I0124ea1b2238a33c379476b74d6ef322327413a2
Tested: Adds unit tests to each affected level.
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1752176
Commit-Queue: Rohan Pavone <rohpavone@chromium.org>
Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarAndrey Kosyakov <caseq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#689139}
parent b6bb8c6c
......@@ -208,22 +208,9 @@ PermissionResult PermissionContextBase::GetPermissionStatus(
PermissionStatusSource::KILL_SWITCH);
}
if (IsRestrictedToSecureOrigins()) {
if (!content::IsOriginSecure(requesting_origin)) {
return PermissionResult(CONTENT_SETTING_BLOCK,
PermissionStatusSource::INSECURE_ORIGIN);
}
// TODO(raymes): We should check the entire chain of embedders here whenever
// possible as this corresponds to the requirements of the secure contexts
// spec and matches what is implemented in blink. Right now we just check
// the top level and requesting origins. Note: chrome-extension:// origins
// are currently exempt from checking the embedder chain. crbug.com/530507.
if (!requesting_origin.SchemeIs(extensions::kExtensionScheme) &&
!content::IsOriginSecure(embedding_origin)) {
return PermissionResult(CONTENT_SETTING_BLOCK,
PermissionStatusSource::INSECURE_ORIGIN);
}
if (!IsPermissionAvailableToOrigins(requesting_origin, embedding_origin)) {
return PermissionResult(CONTENT_SETTING_BLOCK,
PermissionStatusSource::INSECURE_ORIGIN);
}
// Check whether the feature is enabled for the frame by feature policy. We
......@@ -273,6 +260,25 @@ PermissionResult PermissionContextBase::GetPermissionStatus(
return PermissionResult(content_setting, PermissionStatusSource::UNSPECIFIED);
}
bool PermissionContextBase::IsPermissionAvailableToOrigins(
const GURL& requesting_origin,
const GURL& embedding_origin) const {
if (IsRestrictedToSecureOrigins()) {
if (!content::IsOriginSecure(requesting_origin))
return false;
// TODO(raymes): We should check the entire chain of embedders here whenever
// possible as this corresponds to the requirements of the secure contexts
// spec and matches what is implemented in blink. Right now we just check
// the top level and requesting origins. Note: chrome-extension:// origins
// are currently exempt from checking the embedder chain. crbug.com/530507.
if (!requesting_origin.SchemeIs(extensions::kExtensionScheme) &&
!content::IsOriginSecure(embedding_origin))
return false;
}
return true;
}
PermissionResult PermissionContextBase::UpdatePermissionStatusWithDeviceStatus(
PermissionResult result,
const GURL& requesting_origin,
......
......@@ -85,6 +85,10 @@ class PermissionContextBase : public KeyedService {
const GURL& requesting_origin,
const GURL& embedding_origin) const;
// Returns whether the permission is usable by requesting/embedding origins.
bool IsPermissionAvailableToOrigins(const GURL& requesting_origin,
const GURL& embedding_origin) const;
// Update |result| with any modifications based on the device state. For
// example, if |result| is ALLOW but Chrome does not have the relevant
// permission at the device level, but will prompt the user, return ASK.
......
......@@ -168,6 +168,21 @@ class TestKillSwitchPermissionContext : public TestPermissionContext {
DISALLOW_COPY_AND_ASSIGN(TestKillSwitchPermissionContext);
};
class TestSecureOriginRestrictedPermissionContext
: public TestPermissionContext {
public:
TestSecureOriginRestrictedPermissionContext(
Profile* profile,
const ContentSettingsType content_settings_type)
: TestPermissionContext(profile, content_settings_type) {}
protected:
bool IsRestrictedToSecureOrigins() const override { return true; }
private:
DISALLOW_COPY_AND_ASSIGN(TestSecureOriginRestrictedPermissionContext);
};
class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
protected:
PermissionContextBaseTests() {}
......@@ -567,6 +582,32 @@ class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
EXPECT_TRUE(permission_context.IsPermissionKillSwitchOn());
}
void TestSecureOriginRestrictedPermissionContextCheck(
const std::string& requesting_url_spec,
const std::string& embedding_url_spec,
bool expect_allowed) {
GURL requesting_origin(requesting_url_spec);
GURL embedding_origin(embedding_url_spec);
TestSecureOriginRestrictedPermissionContext permission_context(
profile(), CONTENT_SETTINGS_TYPE_GEOLOCATION);
bool result = permission_context.IsPermissionAvailableToOrigins(
requesting_origin, embedding_origin);
EXPECT_EQ(expect_allowed, result)
<< "test case (requesting, embedding): (" << requesting_url_spec << ", "
<< embedding_url_spec << ") with secure-origin requirement"
<< " on";
// With no secure-origin limitation, this check should always return pass.
TestPermissionContext new_context(profile(),
CONTENT_SETTINGS_TYPE_GEOLOCATION);
result = new_context.IsPermissionAvailableToOrigins(requesting_origin,
embedding_origin);
EXPECT_EQ(true, result)
<< "test case (requesting, embedding): (" << requesting_url_spec << ", "
<< embedding_url_spec << ") with secure-origin requirement"
<< " off";
}
// Don't call this more than once in the same test, as it persists data to
// HostContentSettingsMap.
void TestParallelRequests(ContentSetting response) {
......@@ -726,6 +767,65 @@ TEST_F(PermissionContextBaseTests, TestGlobalKillSwitch) {
TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
}
// Tests that secure origins are examined if switch is on, or ignored if off.
TEST_F(PermissionContextBaseTests,
TestSecureOriginRestrictedPermissionContextSwitch) {
struct {
std::string requesting_url_spec;
std::string embedding_url_spec;
bool expect_permission_allowed;
} kTestCases[] = {
// Secure-origins that should be allowed.
{"https://google.com", "https://foo.com",
/*expect_allowed=*/true},
{"https://www.bar.com", "https://foo.com",
/*expect_allowed=*/true},
{"https://localhost", "http://localhost",
/*expect_allowed=*/true},
{"http://localhost", "https://google.com",
/*expect_allowed=*/true},
{"https://google.com", "http://localhost",
/*expect_allowed=*/true},
{"https://foo.com", "file://some-file",
/*expect_allowed=*/true},
{"file://some-file", "https://foo.com",
/*expect_allowed=*/true},
{"https://foo.com", "about:blank",
/*expect_allowed=*/true},
{"about:blank", "https://foo.com",
/*expect_allowed=*/true},
// Extensions are exempt from checking the embedder chain.
{"chrome-extension://some-extension", "http://not-secure.com",
/*expect_allowed=*/true},
// Insecure-origins that should be blocked.
{"http://foo.com", "file://some-file",
/*expect_allowed=*/false},
{"fake://foo.com", "about:blank",
/*expect_allowed=*/false},
{"http://localhost", "http://foo.com",
/*expect_allowed=*/false},
{"http://localhost", "foo.com",
/*expect_allowed=*/false},
{"http://bar.com", "https://foo.com",
/*expect_permission_allowed=*/false},
{"https://foo.com", "http://bar.com",
/*expect_permission_allowed=*/false},
{"http://localhost", "http://foo.com",
/*expect_permission_allowed=*/false},
{"http://foo.com", "http://localhost",
/*expect_permission_allowed=*/false},
{"bar.com", "https://foo.com", /*expect_permission_allowed=*/false},
{"https://foo.com", "bar.com", /*expect_permission_allowed=*/false}};
for (const auto& test_case : kTestCases) {
TestSecureOriginRestrictedPermissionContextCheck(
test_case.requesting_url_spec, test_case.embedding_url_spec,
test_case.expect_permission_allowed);
}
}
TEST_F(PermissionContextBaseTests, TestParallelRequestsAllowed) {
TestParallelRequests(CONTENT_SETTING_ALLOW);
}
......
......@@ -104,7 +104,10 @@ ContentSetting PermissionStatusToContentSetting(PermissionStatus status) {
}
// Helper method to convert PermissionType to ContentSettingType.
ContentSettingsType PermissionTypeToContentSetting(PermissionType permission) {
// If PermissionType is not supported or found, returns
// CONTENT_SETTINGS_TYPE_DEFAULT.
ContentSettingsType PermissionTypeToContentSettingSafe(
PermissionType permission) {
switch (permission) {
case PermissionType::MIDI:
return CONTENT_SETTINGS_TYPE_MIDI;
......@@ -118,7 +121,6 @@ ContentSettingsType PermissionTypeToContentSetting(PermissionType permission) {
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
return CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER;
#else
NOTIMPLEMENTED();
break;
#endif
case PermissionType::DURABLE_STORAGE:
......@@ -152,15 +154,22 @@ ContentSettingsType PermissionTypeToContentSetting(PermissionType permission) {
case PermissionType::WAKE_LOCK_SYSTEM:
return CONTENT_SETTINGS_TYPE_WAKE_LOCK_SYSTEM;
case PermissionType::NUM:
// This will hit the NOTREACHED below.
break;
}
NOTREACHED() << "Unknown content setting for permission "
<< static_cast<int>(permission);
return CONTENT_SETTINGS_TYPE_DEFAULT;
}
// Helper method to convert PermissionType to ContentSettingType.
ContentSettingsType PermissionTypeToContentSetting(PermissionType permission) {
ContentSettingsType content_setting =
PermissionTypeToContentSettingSafe(permission);
DCHECK_NE(content_setting, CONTENT_SETTINGS_TYPE_DEFAULT)
<< "Unknown content setting for permission "
<< static_cast<int>(permission);
return content_setting;
}
void SubscriptionCallbackWrapper(
base::OnceCallback<void(PermissionStatus)> callback,
ContentSetting content_setting) {
......@@ -603,6 +612,16 @@ PermissionStatus PermissionManager::GetPermissionStatusForFrame(
return ContentSettingToPermissionStatus(result.content_setting);
}
bool PermissionManager::IsPermissionOverridableByDevTools(
content::PermissionType permission,
const GURL& origin) {
ContentSettingsType type = PermissionTypeToContentSettingSafe(permission);
PermissionContextBase* context = GetPermissionContext(type);
return context && !context->IsPermissionKillSwitchOn() &&
context->IsPermissionAvailableToOrigins(origin, origin);
}
int PermissionManager::SubscribePermissionStatusChange(
PermissionType permission,
content::RenderFrameHost* render_frame_host,
......@@ -747,8 +766,10 @@ void PermissionManager::SetPermissionOverridesForDevTools(
const PermissionOverrides& overrides) {
ContentSettingsTypeOverrides result;
for (const auto& item : overrides) {
result[PermissionTypeToContentSetting(item.first)] =
PermissionStatusToContentSetting(item.second);
ContentSettingsType content_setting =
PermissionTypeToContentSettingSafe(item.first);
if (content_setting != CONTENT_SETTINGS_TYPE_DEFAULT)
result[content_setting] = PermissionStatusToContentSetting(item.second);
}
devtools_permission_overrides_[url::Origin::Create(origin)] =
std::move(result);
......
......@@ -104,6 +104,8 @@ class PermissionManager : public KeyedService,
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin) override;
bool IsPermissionOverridableByDevTools(content::PermissionType permission,
const GURL& origin) override;
int SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
......
......@@ -8,9 +8,11 @@
#include "base/bind.h"
#include "base/macros.h"
#include "base/test/mock_entropy_provider.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/permissions/permission_context_base.h"
#include "chrome/browser/permissions/permission_manager_factory.h"
#include "chrome/browser/permissions/permission_request_manager.h"
#include "chrome/browser/permissions/permission_result.h"
......@@ -22,6 +24,7 @@
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/variations/variations_associated_data.h"
#include "content/public/browser/permission_type.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_browser_thread_bundle.h"
......@@ -588,6 +591,57 @@ TEST_F(PermissionManagerTest, InsecureOrigin) {
EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
}
TEST_F(PermissionManagerTest, InsecureOriginIsNotOverridable) {
const GURL kInsecureOrigin("http://example.com/geolocation");
const GURL kSecureOrigin("https://example.com/geolocation");
EXPECT_FALSE(
GetPermissionControllerDelegate()->IsPermissionOverridableByDevTools(
PermissionType::GEOLOCATION, kInsecureOrigin));
EXPECT_TRUE(
GetPermissionControllerDelegate()->IsPermissionOverridableByDevTools(
PermissionType::GEOLOCATION, kSecureOrigin));
}
TEST_F(PermissionManagerTest, MissingContextIsNotOverridable) {
// Permissions that are not implemented should be denied overridability.
#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
EXPECT_FALSE(
GetPermissionControllerDelegate()->IsPermissionOverridableByDevTools(
PermissionType::PROTECTED_MEDIA_IDENTIFIER,
GURL("http://localhost")));
#endif
EXPECT_TRUE(
GetPermissionControllerDelegate()->IsPermissionOverridableByDevTools(
PermissionType::MIDI_SYSEX, GURL("http://localhost")));
}
TEST_F(PermissionManagerTest, KillSwitchOnIsNotOverridable) {
EXPECT_TRUE(
GetPermissionControllerDelegate()->IsPermissionOverridableByDevTools(
PermissionType::GEOLOCATION, GURL("http://localhost")));
// Turn on kill switch for GEOLOCATION.
base::FieldTrialList field_trial_list(
std::make_unique<base::MockEntropyProvider>());
variations::testing::ClearAllVariationParams();
std::map<std::string, std::string> params;
params[PermissionUtil::GetPermissionString(
CONTENT_SETTINGS_TYPE_GEOLOCATION)] =
PermissionContextBase::kPermissionsKillSwitchBlockedValue;
variations::AssociateVariationParams(
PermissionContextBase::kPermissionsKillSwitchFieldStudy, "TestGroup",
params);
base::FieldTrialList::CreateFieldTrial(
PermissionContextBase::kPermissionsKillSwitchFieldStudy, "TestGroup");
EXPECT_FALSE(
GetPermissionControllerDelegate()->IsPermissionOverridableByDevTools(
PermissionType::GEOLOCATION, GURL("http://localhost")));
// Clean-up.
variations::testing::ClearAllVariationParams();
}
TEST_F(PermissionManagerTest, GetCanonicalOriginSearch) {
const GURL google_com("https://www.google.com");
const GURL google_de("https://www.google.de");
......
......@@ -11,6 +11,7 @@
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_samples.h"
#include "base/metrics/statistics_recorder.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "content/browser/devtools/devtools_manager.h"
......@@ -316,7 +317,14 @@ Response BrowserHandler::SetPermission(
PermissionControllerImpl* permission_controller =
PermissionControllerImpl::FromBrowserContext(browser_context);
GURL url = GURL(origin).GetOrigin();
permission_controller->SetOverrideForDevTools(url, type, permission_status);
PermissionControllerImpl::OverrideStatus status =
permission_controller->SetOverrideForDevTools(url, type,
permission_status);
if (status != PermissionControllerImpl::OverrideStatus::kOverrideSet) {
return Response::InvalidParams(
"Permission can't be granted in current context.");
}
contexts_with_overridden_permissions_.insert(
browser_context_id.fromMaybe(std::string()));
return Response::OK();
......@@ -345,7 +353,13 @@ Response BrowserHandler::GrantPermissions(
PermissionControllerImpl* permission_controller =
PermissionControllerImpl::FromBrowserContext(browser_context);
GURL url = GURL(origin).GetOrigin();
permission_controller->GrantOverridesForDevTools(url, internal_permissions);
PermissionControllerImpl::OverrideStatus status =
permission_controller->GrantOverridesForDevTools(url,
internal_permissions);
if (status != PermissionControllerImpl::OverrideStatus::kOverrideSet) {
return Response::InvalidParams(
"Permissions can't be granted in current context.");
}
contexts_with_overridden_permissions_.insert(
browser_context_id.fromMaybe(""));
return Response::OK();
......
......@@ -183,10 +183,17 @@ void PermissionControllerImpl::NotifyChangedSubscriptions(
callback.Run();
}
void PermissionControllerImpl::SetOverrideForDevTools(
PermissionControllerImpl::OverrideStatus
PermissionControllerImpl::SetOverrideForDevTools(
const GURL& origin,
const PermissionType& permission,
const blink::mojom::PermissionStatus& status) {
PermissionControllerDelegate* delegate =
browser_context_->GetPermissionControllerDelegate();
if (delegate &&
!delegate->IsPermissionOverridableByDevTools(permission, origin)) {
return OverrideStatus::kOverrideNotSet;
}
const auto old_statuses = GetSubscriptionsStatuses(origin);
devtools_permission_overrides_.Set(url::Origin::Create(origin), permission,
......@@ -194,11 +201,20 @@ void PermissionControllerImpl::SetOverrideForDevTools(
NotifyChangedSubscriptions(old_statuses);
UpdateDelegateOverridesForDevTools(origin);
return OverrideStatus::kOverrideSet;
}
void PermissionControllerImpl::GrantOverridesForDevTools(
PermissionControllerImpl::OverrideStatus
PermissionControllerImpl::GrantOverridesForDevTools(
const GURL& origin,
const std::vector<PermissionType>& permissions) {
PermissionControllerDelegate* delegate =
browser_context_->GetPermissionControllerDelegate();
if (delegate)
for (const auto permission : permissions)
if (!delegate->IsPermissionOverridableByDevTools(permission, origin))
return OverrideStatus::kOverrideNotSet;
const auto old_statuses = GetSubscriptionsStatuses(origin);
devtools_permission_overrides_.GrantPermissions(url::Origin::Create(origin),
permissions);
......@@ -208,6 +224,7 @@ void PermissionControllerImpl::GrantOverridesForDevTools(
NotifyChangedSubscriptions(old_statuses);
UpdateDelegateOverridesForDevTools(origin);
return OverrideStatus::kOverrideSet;
}
void PermissionControllerImpl::ResetOverridesForDevTools() {
......
......@@ -27,15 +27,17 @@ class CONTENT_EXPORT PermissionControllerImpl : public PermissionController {
BrowserContext* browser_context);
using PermissionOverrides = DevToolsPermissionOverrides::PermissionOverrides;
enum class OverrideStatus { kOverrideNotSet, kOverrideSet };
// For the given |origin|, grant permissions in |overrides| and reject all
// others.
void GrantOverridesForDevTools(
OverrideStatus GrantOverridesForDevTools(
const GURL& origin,
const std::vector<PermissionType>& permissions);
void SetOverrideForDevTools(const GURL& origin,
const PermissionType& permission,
const blink::mojom::PermissionStatus& status);
OverrideStatus SetOverrideForDevTools(
const GURL& origin,
const PermissionType& permission,
const blink::mojom::PermissionStatus& status);
void ResetOverridesForDevTools();
// PermissionController implementation.
......
......@@ -22,6 +22,7 @@ namespace content {
namespace {
using ::testing::Unused;
using OverrideStatus = PermissionControllerImpl::OverrideStatus;
using RequestsCallback =
base::Callback<void(const std::vector<blink::mojom::PermissionStatus>&)>;
......@@ -42,6 +43,8 @@ class MockManagerWithRequests : public MockPermissionManager {
MOCK_METHOD2(SetPermissionOverridesForDevTools,
void(const GURL& origin, const PermissionOverrides& overrides));
MOCK_METHOD0(ResetPermissionOverridesForDevTools, void());
MOCK_METHOD2(IsPermissionOverridableByDevTools,
bool(PermissionType, const GURL&));
private:
DISALLOW_COPY_AND_ASSIGN(MockManagerWithRequests);
......@@ -57,6 +60,11 @@ class PermissionControllerImplTest : public ::testing::Test {
}
~PermissionControllerImplTest() override {}
void SetUp() override {
ON_CALL(*mock_manager(), IsPermissionOverridableByDevTools)
.WillByDefault(testing::Return(true));
}
PermissionControllerImpl* permission_controller() {
return permission_controller_.get();
}
......@@ -326,6 +334,90 @@ TEST_F(PermissionControllerImplTest,
blink::mojom::PermissionStatus::ASK);
}
TEST_F(PermissionControllerImplTest,
PermissionsCannotBeOverriddenIfNotOverridable) {
GURL kTestOrigin(kTestUrl);
EXPECT_EQ(permission_controller()->SetOverrideForDevTools(
kTestOrigin, PermissionType::GEOLOCATION,
blink::mojom::PermissionStatus::DENIED),
OverrideStatus::kOverrideSet);
// Delegate will be called, but prevents override from being set.
EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
PermissionType::GEOLOCATION, testing::_))
.WillOnce(testing::Return(false));
EXPECT_EQ(permission_controller()->SetOverrideForDevTools(
kTestOrigin, PermissionType::GEOLOCATION,
blink::mojom::PermissionStatus::ASK),
OverrideStatus::kOverrideNotSet);
blink::mojom::PermissionStatus status =
permission_controller()->GetPermissionStatus(PermissionType::GEOLOCATION,
kTestOrigin, kTestOrigin);
EXPECT_EQ(status, blink::mojom::PermissionStatus::DENIED);
}
TEST_F(PermissionControllerImplTest,
GrantPermissionsReturnsStatusesBeingSetIfOverridable) {
GURL kTestOrigin(kTestUrl);
permission_controller()->SetOverrideForDevTools(
kTestOrigin, PermissionType::GEOLOCATION,
blink::mojom::PermissionStatus::DENIED);
permission_controller()->SetOverrideForDevTools(
kTestOrigin, PermissionType::MIDI, blink::mojom::PermissionStatus::ASK);
permission_controller()->SetOverrideForDevTools(
kTestOrigin, PermissionType::BACKGROUND_SYNC,
blink::mojom::PermissionStatus::ASK);
// Delegate will be called, but prevents override from being set.
EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
PermissionType::GEOLOCATION, testing::_))
.WillOnce(testing::Return(false));
EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
PermissionType::MIDI, testing::_))
.WillOnce(testing::Return(true));
// Since one cannot be overridden, none are overridden.
auto result = permission_controller()->GrantOverridesForDevTools(
kTestOrigin, {PermissionType::MIDI, PermissionType::GEOLOCATION,
PermissionType::BACKGROUND_SYNC});
EXPECT_EQ(OverrideStatus::kOverrideNotSet, result);
// Keep original settings as before.
EXPECT_EQ(blink::mojom::PermissionStatus::DENIED,
permission_controller()->GetPermissionStatus(
PermissionType::GEOLOCATION, kTestOrigin, kTestOrigin));
EXPECT_EQ(blink::mojom::PermissionStatus::ASK,
permission_controller()->GetPermissionStatus(
PermissionType::MIDI, kTestOrigin, kTestOrigin));
EXPECT_EQ(blink::mojom::PermissionStatus::ASK,
permission_controller()->GetPermissionStatus(
PermissionType::BACKGROUND_SYNC, kTestOrigin, kTestOrigin));
EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
PermissionType::GEOLOCATION, testing::_))
.WillOnce(testing::Return(true));
EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
PermissionType::MIDI, testing::_))
.WillOnce(testing::Return(true));
EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
PermissionType::BACKGROUND_SYNC, testing::_))
.WillOnce(testing::Return(true));
// If all can be set, overrides will be stored.
result = permission_controller()->GrantOverridesForDevTools(
kTestOrigin, {PermissionType::MIDI, PermissionType::GEOLOCATION,
PermissionType::BACKGROUND_SYNC});
EXPECT_EQ(OverrideStatus::kOverrideSet, result);
EXPECT_EQ(blink::mojom::PermissionStatus::GRANTED,
permission_controller()->GetPermissionStatus(
PermissionType::GEOLOCATION, kTestOrigin, kTestOrigin));
EXPECT_EQ(blink::mojom::PermissionStatus::GRANTED,
permission_controller()->GetPermissionStatus(
PermissionType::MIDI, kTestOrigin, kTestOrigin));
EXPECT_EQ(blink::mojom::PermissionStatus::GRANTED,
permission_controller()->GetPermissionStatus(
PermissionType::BACKGROUND_SYNC, kTestOrigin, kTestOrigin));
}
} // namespace
} // namespace content
......@@ -241,6 +241,7 @@ jumbo_source_set("browser_sources") {
"pepper_flash_settings_helper.h",
"pepper_vpn_provider_resource_host_proxy.h",
"permission_controller.h",
"permission_controller_delegate.cc",
"permission_controller_delegate.h",
"permission_type.cc",
"permission_type.h",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/public/browser/permission_controller_delegate.h"
namespace content {
bool PermissionControllerDelegate::IsPermissionOverridableByDevTools(
PermissionType permission,
const GURL& origin) {
return true;
}
} // namespace content
......@@ -106,6 +106,11 @@ class CONTENT_EXPORT PermissionControllerDelegate {
// Removes overrides that have been set, if any, for all origins. If delegate
// does not maintain own permission set, then nothing happens.
virtual void ResetPermissionOverridesForDevTools() {}
// Returns whether permission can be overridden by
// DevToolsPermissionOverrides.
virtual bool IsPermissionOverridableByDevTools(PermissionType permission,
const GURL& origin);
};
} // namespace content
......
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