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

Unified Diff: chrome/browser/permissions/permission_context_base_unittest.cc

Issue 2555913002: Implement origin specific Permissions Blacklisting. (Closed)
Patch Set: Comments Created 3 years, 11 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/browser/permissions/permission_context_base.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/permissions/permission_context_base_unittest.cc
diff --git a/chrome/browser/permissions/permission_context_base_unittest.cc b/chrome/browser/permissions/permission_context_base_unittest.cc
index 4dfe1e4118a4e5217d71ae5a570799305f596080..9284d1abadc55932bce4451b1ad4d4fd4d790189 100644
--- a/chrome/browser/permissions/permission_context_base_unittest.cc
+++ b/chrome/browser/permissions/permission_context_base_unittest.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/permissions/permission_context_base.h"
#include <map>
+#include <set>
#include <string>
#include <utility>
#include <vector>
@@ -14,6 +15,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial.h"
+#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "base/test/mock_entropy_provider.h"
#include "base/test/scoped_feature_list.h"
@@ -31,7 +33,10 @@
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
+#include "components/safe_browsing_db/database_manager.h"
+#include "components/safe_browsing_db/test_database_manager.h"
#include "components/variations/variations_associated_data.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -50,6 +55,47 @@ const char kPermissionsKillSwitchTestGroup[] = "TestGroup";
const char* const kPromptGroupName = kPermissionsKillSwitchTestGroup;
const char kPromptTrialName[] = "PermissionPromptsUX";
+class MockSafeBrowsingDatabaseManager
+ : public safe_browsing::TestSafeBrowsingDatabaseManager {
+ public:
+ explicit MockSafeBrowsingDatabaseManager(bool perform_callback)
+ : perform_callback_(perform_callback) {}
+
+ bool CheckApiBlacklistUrl(
+ const GURL& url,
+ safe_browsing::SafeBrowsingDatabaseManager::Client* client) override {
+ if (perform_callback_) {
+ safe_browsing::ThreatMetadata metadata;
+ const auto& blacklisted_permissions = permissions_blacklist_.find(url);
+ if (blacklisted_permissions != permissions_blacklist_.end())
+ metadata.api_permissions = blacklisted_permissions->second;
+ client->OnCheckApiBlacklistUrlResult(url, metadata);
+ }
+ // Returns false if scheme is HTTP/HTTPS and able to be checked.
+ return false;
+ }
+
+ bool CancelApiCheck(Client* client) override {
+ DCHECK(!perform_callback_);
+ // Returns true when client check could be stopped.
+ return true;
+ }
+
+ void BlacklistUrlPermissions(const GURL& url,
+ const std::set<std::string> permissions) {
+ permissions_blacklist_[url] = permissions;
+ }
+
+ protected:
+ ~MockSafeBrowsingDatabaseManager() override {}
+
+ private:
+ bool perform_callback_;
+ std::map<GURL, std::set<std::string>> permissions_blacklist_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
+};
+
class TestPermissionContext : public PermissionContextBase {
public:
TestPermissionContext(Profile* profile,
@@ -70,8 +116,16 @@ class TestPermissionContext : public PermissionContextBase {
bool tab_context_updated() const { return tab_context_updated_; }
+ // Once a decision for the requested permission has been made, run the
+ // callback.
void TrackPermissionDecision(ContentSetting content_setting) {
decisions_.push_back(content_setting);
+ // Null check required here as the quit_closure_ can also be run and reset
+ // first from within DecidePermission.
+ if (quit_closure_) {
+ quit_closure_.Run();
+ quit_closure_.Reset();
+ }
}
ContentSetting GetContentSettingFromMap(const GURL& url_a,
@@ -81,6 +135,44 @@ class TestPermissionContext : public PermissionContextBase {
content_settings_type(), std::string());
}
+ void RequestPermission(content::WebContents* web_contents,
+ const PermissionRequestID& id,
+ const GURL& requesting_frame,
+ bool user_gesture,
+ const BrowserPermissionCallback& callback) override {
+ base::RunLoop run_loop;
+ quit_closure_ = run_loop.QuitClosure();
+ PermissionContextBase::RequestPermission(web_contents, id, requesting_frame,
+ true /* user_gesture */, callback);
+ run_loop.Run();
+ }
+
+ void DecidePermission(content::WebContents* web_contents,
+ const PermissionRequestID& id,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ bool user_gesture,
+ const BrowserPermissionCallback& callback) override {
+ PermissionContextBase::DecidePermission(web_contents, id, requesting_origin,
+ embedding_origin, user_gesture,
+ callback);
+ if (respond_permission_) {
+ respond_permission_.Run();
+ respond_permission_.Reset();
+ } else {
+ // Stop the run loop from spinning indefinitely if no response callback
+ // has been set, as is the case with TestParallelRequests.
+ quit_closure_.Run();
+ quit_closure_.Reset();
+ }
+ }
+
+ // Permission request will need to be responded to, so pass a callback to be
+ // run once the request has completed and the decision has been made.
+ void SetRespondPermissionCallback(base::Closure callback) {
+ respond_permission_ = callback;
+ }
+
protected:
void UpdateTabContext(const PermissionRequestID& id,
const GURL& requesting_origin,
@@ -95,7 +187,10 @@ class TestPermissionContext : public PermissionContextBase {
private:
std::vector<ContentSetting> decisions_;
bool tab_context_updated_;
-
+ base::Closure quit_closure_;
+ // Callback for responding to a permission once the request has been completed
+ // (valid URL, kill switch disabled, not blacklisted)
+ base::Closure respond_permission_;
DISALLOW_COPY_AND_ASSIGN(TestPermissionContext);
};
@@ -180,13 +275,15 @@ class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
web_contents()->GetRenderProcessHost()->GetID(),
web_contents()->GetMainFrame()->GetRoutingID(),
-1);
+ permission_context.SetRespondPermissionCallback(
+ base::Bind(&PermissionContextBaseTests::RespondToPermission,
+ base::Unretained(this), &permission_context, id, url,
+ persist, decision));
permission_context.RequestPermission(
web_contents(),
id, url, true /* user_gesture */,
base::Bind(&TestPermissionContext::TrackPermissionDecision,
base::Unretained(&permission_context)));
-
- RespondToPermission(&permission_context, id, url, persist, decision);
ASSERT_EQ(1u, permission_context.decisions().size());
EXPECT_EQ(decision, permission_context.decisions()[0]);
EXPECT_TRUE(permission_context.tab_context_updated());
@@ -237,13 +334,16 @@ class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
const PermissionRequestID id(
web_contents()->GetRenderProcessHost()->GetID(),
web_contents()->GetMainFrame()->GetRoutingID(), i);
+
+ permission_context.SetRespondPermissionCallback(
+ base::Bind(&PermissionContextBaseTests::RespondToPermission,
+ base::Unretained(this), &permission_context, id, url,
+ false, CONTENT_SETTING_ASK));
+
permission_context.RequestPermission(
web_contents(), id, url, true /* user_gesture */,
base::Bind(&TestPermissionContext::TrackPermissionDecision,
base::Unretained(&permission_context)));
-
- RespondToPermission(&permission_context, id, url, false, /* persist */
- CONTENT_SETTING_ASK);
histograms.ExpectTotalCount(
"Permissions.Prompt.Dismissed.PriorDismissCount." +
PermissionUtil::GetPermissionString(permission_type),
@@ -281,13 +381,15 @@ class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
const PermissionRequestID id(
web_contents()->GetRenderProcessHost()->GetID(),
web_contents()->GetMainFrame()->GetRoutingID(), i);
+
+ permission_context.SetRespondPermissionCallback(
+ base::Bind(&PermissionContextBaseTests::RespondToPermission,
+ base::Unretained(this), &permission_context, id, url,
+ false, CONTENT_SETTING_ASK));
permission_context.RequestPermission(
web_contents(), id, url, true /* user_gesture */,
base::Bind(&TestPermissionContext::TrackPermissionDecision,
base::Unretained(&permission_context)));
-
- RespondToPermission(&permission_context, id, url, false, /* persist */
- CONTENT_SETTING_ASK);
histograms.ExpectTotalCount(
"Permissions.Prompt.Dismissed.PriorDismissCount.Geolocation",
i + 1);
@@ -365,13 +467,15 @@ class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
const PermissionRequestID id(
web_contents()->GetRenderProcessHost()->GetID(),
web_contents()->GetMainFrame()->GetRoutingID(), i);
+ permission_context.SetRespondPermissionCallback(
+ base::Bind(&PermissionContextBaseTests::RespondToPermission,
+ base::Unretained(this), &permission_context, id, url,
+ false, CONTENT_SETTING_ASK));
permission_context.RequestPermission(
web_contents(), id, url, true /* user_gesture */,
base::Bind(&TestPermissionContext::TrackPermissionDecision,
- base::Unretained(&permission_context)));
+ base::Unretained(&permission_context)));
- RespondToPermission(&permission_context, id, url, false, /* persist */
- CONTENT_SETTING_ASK);
EXPECT_EQ(1u, permission_context.decisions().size());
ASSERT_EQ(expected, permission_context.decisions()[0]);
EXPECT_TRUE(permission_context.tab_context_updated());
@@ -431,14 +535,17 @@ class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
web_contents()->GetRenderProcessHost()->GetID(),
web_contents()->GetMainFrame()->GetRoutingID(),
-1);
+ permission_context.SetRespondPermissionCallback(
+ base::Bind(&PermissionContextBaseTests::RespondToPermission,
+ base::Unretained(this), &permission_context, id, url, true,
+ CONTENT_SETTING_ALLOW));
+
permission_context.RequestPermission(
web_contents(),
id, url, true /* user_gesture */,
base::Bind(&TestPermissionContext::TrackPermissionDecision,
base::Unretained(&permission_context)));
- RespondToPermission(&permission_context, id, url, true, /* persist */
- CONTENT_SETTING_ALLOW);
ASSERT_EQ(1u, permission_context.decisions().size());
EXPECT_EQ(CONTENT_SETTING_ALLOW, permission_context.decisions()[0]);
EXPECT_TRUE(permission_context.tab_context_updated());
@@ -490,21 +597,27 @@ class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
web_contents()->GetRenderProcessHost()->GetID(),
web_contents()->GetMainFrame()->GetRoutingID(), 1);
+ bool persist = (response == CONTENT_SETTING_ALLOW ||
+ response == CONTENT_SETTING_BLOCK);
+
+ // Request a permission without setting the callback to DecidePermission.
permission_context.RequestPermission(
web_contents(), id0, url, true /* user_gesture */,
base::Bind(&TestPermissionContext::TrackPermissionDecision,
base::Unretained(&permission_context)));
+
+ EXPECT_EQ(0u, permission_context.decisions().size());
+
+ // Set the callback, and make a second permission request.
+ permission_context.SetRespondPermissionCallback(
+ base::Bind(&PermissionContextBaseTests::RespondToPermission,
+ base::Unretained(this), &permission_context, id0, url,
+ persist, response));
permission_context.RequestPermission(
web_contents(), id1, url, true /* user_gesture */,
base::Bind(&TestPermissionContext::TrackPermissionDecision,
base::Unretained(&permission_context)));
- EXPECT_EQ(0u, permission_context.decisions().size());
-
- bool persist = (response == CONTENT_SETTING_ALLOW ||
- response == CONTENT_SETTING_BLOCK);
- RespondToPermission(&permission_context, id0, url, persist, response);
-
ASSERT_EQ(2u, permission_context.decisions().size());
EXPECT_EQ(response, permission_context.decisions()[0]);
EXPECT_EQ(response, permission_context.decisions()[1]);
@@ -513,6 +626,37 @@ class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
EXPECT_EQ(response, permission_context.GetContentSettingFromMap(url, url));
}
+ void TestPermissionsBlacklisting(
+ content::PermissionType permission_type,
+ ContentSettingsType content_settings_type,
+ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
+ const GURL& url,
+ int timeout,
+ ContentSetting response) {
+ NavigateAndCommit(url);
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(features::kPermissionsBlacklist);
+ TestPermissionContext permission_context(profile(), permission_type,
+ content_settings_type);
+ permission_context.SetSafeBrowsingDatabaseManagerAndTimeoutForTest(
+ db_manager, timeout);
+ const PermissionRequestID id(
+ web_contents()->GetRenderProcessHost()->GetID(),
+ web_contents()->GetMainFrame()->GetRoutingID(), -1);
+ // The response callback needs to be set here to test a response being made
+ // in the case of a site not being blacklisted or a safe browsing timeout.
+ permission_context.SetRespondPermissionCallback(base::Bind(
+ &PermissionContextBaseTests::RespondToPermission,
+ base::Unretained(this), &permission_context, id, url, false, response));
+ permission_context.RequestPermission(
+ web_contents(), id, url, true /* user_gesture */,
+ base::Bind(&TestPermissionContext::TrackPermissionDecision,
+ base::Unretained(&permission_context)));
+
+ ASSERT_EQ(1u, permission_context.decisions().size());
+ EXPECT_EQ(response, permission_context.decisions()[0]);
+ }
+
private:
// ChromeRenderViewHostTestHarness:
void SetUp() override {
@@ -667,3 +811,52 @@ TEST_F(PermissionContextBaseTests, TestParallelRequestsBlocked) {
TEST_F(PermissionContextBaseTests, TestParallelRequestsDismissed) {
TestParallelRequests(CONTENT_SETTING_ASK);
}
+
+// Tests a blacklisted (URL, permission) pair has had its permission request
+// blocked.
+TEST_F(PermissionContextBaseTests, TestPermissionsBlacklistingBlocked) {
+ scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
+ new MockSafeBrowsingDatabaseManager(true /* perform_callback */);
+ const GURL url("https://www.example.com");
+ std::set<std::string> blacklisted_permissions{
+ PermissionUtil::GetPermissionString(
+ content::PermissionType::GEOLOCATION)};
+ db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
+ TestPermissionsBlacklisting(content::PermissionType::GEOLOCATION,
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, db_manager,
+ url, 2000 /* timeout */, CONTENT_SETTING_BLOCK);
+}
+
+// Tests that a URL with a blacklisted permission is permitted to request a
+// non-blacklisted permission.
+TEST_F(PermissionContextBaseTests, TestPermissionsBlacklistingAllowed) {
+ scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
+ new MockSafeBrowsingDatabaseManager(true /* perform_callback */);
+ const GURL url("https://www.example.com");
+ std::set<std::string> blacklisted_permissions{
+ PermissionUtil::GetPermissionString(
+ content::PermissionType::GEOLOCATION)};
+ db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
+ TestPermissionsBlacklisting(
+ content::PermissionType::GEOLOCATION, CONTENT_SETTINGS_TYPE_GEOLOCATION,
+ db_manager, url, 2000 /* timeout in ms */, CONTENT_SETTING_BLOCK);
+ TestPermissionsBlacklisting(content::PermissionType::NOTIFICATIONS,
+ CONTENT_SETTINGS_TYPE_NOTIFICATIONS, db_manager,
+ url, 2000 /* timeout in ms */,
+ CONTENT_SETTING_ALLOW);
+}
+
+// Tests that a URL with a blacklisted permisison is permitted to request that
+// permission if Safe Browsing has timed out.
+TEST_F(PermissionContextBaseTests, TestSafeBrowsingTimeout) {
+ scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
+ new MockSafeBrowsingDatabaseManager(false /* perform_callback */);
+ const GURL url("https://www.example.com");
+ std::set<std::string> blacklisted_permissions{
+ PermissionUtil::GetPermissionString(
+ content::PermissionType::GEOLOCATION)};
+ db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
+ TestPermissionsBlacklisting(content::PermissionType::GEOLOCATION,
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, db_manager,
+ url, 0 /* timeout in ms */, CONTENT_SETTING_ASK);
+}
« no previous file with comments | « chrome/browser/permissions/permission_context_base.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698