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

Side by Side Diff: chrome/browser/permissions/permission_decision_auto_blocker_unittest.cc

Issue 2622983003: Implement embargo in PermissionDecisionAutoBlocker (Closed)
Patch Set: Block on nth dismissal and tests 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/permissions/permission_decision_auto_blocker.h" 5 #include "chrome/browser/permissions/permission_decision_auto_blocker.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/test/scoped_feature_list.h"
9 #include "base/time/time.h"
10 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
11 #include "chrome/common/chrome_features.h"
8 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 12 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
9 #include "chrome/test/base/testing_profile.h" 13 #include "chrome/test/base/testing_profile.h"
14 #include "components/safe_browsing_db/test_database_manager.h"
10 #include "content/public/browser/permission_type.h" 15 #include "content/public/browser/permission_type.h"
11 16
12 namespace { 17 namespace {
13 18
14 bool FilterGoogle(const GURL& url) { 19 bool FilterGoogle(const GURL& url) {
15 return url == "https://www.google.com/"; 20 return url == "https://www.google.com/";
16 } 21 }
17 22
18 bool FilterAll(const GURL& url) { 23 bool FilterAll(const GURL& url) {
19 return true; 24 return true;
20 } 25 }
21 26
27 void AutoBlockerCallback(bool expected, bool result) {
28 EXPECT_EQ(expected, result);
29 }
30
22 } // namespace 31 } // namespace
23 32
24 class PermissionDecisionAutoBlockerUnitTest 33 class PermissionDecisionAutoBlockerUnitTest
25 : public ChromeRenderViewHostTestHarness { 34 : public ChromeRenderViewHostTestHarness {
26 protected: 35 protected:
27 int GetDismissalCount(const GURL& url, 36 int GetDismissalCount(const GURL& url, content::PermissionType permission) {
28 content::PermissionType permission) { 37 return PermissionDecisionAutoBlocker::GetDismissCount(url, permission,
29 return PermissionDecisionAutoBlocker::GetDismissCount( 38 profile());
30 url, permission, profile());
31 } 39 }
32 40
33 int GetIgnoreCount(const GURL& url, content::PermissionType permission) { 41 int GetIgnoreCount(const GURL& url, content::PermissionType permission) {
34 return PermissionDecisionAutoBlocker::GetIgnoreCount( 42 return PermissionDecisionAutoBlocker::GetIgnoreCount(url, permission,
35 url, permission, profile()); 43 profile());
36 } 44 }
37 45
38 int RecordDismiss(const GURL& url, content::PermissionType permission) { 46 int RecordDismissAndEmbargo(const GURL& url,
39 return PermissionDecisionAutoBlocker::RecordDismiss(url, permission, 47 content::PermissionType permission,
40 profile()); 48 base::Time current_time) {
49 return PermissionDecisionAutoBlocker::RecordDismissAndEmbargo(
50 url, permission, profile(), current_time);
41 } 51 }
42 52
43 int RecordIgnore(const GURL& url, content::PermissionType permission) { 53 int RecordIgnore(const GURL& url, content::PermissionType permission) {
44 return PermissionDecisionAutoBlocker::RecordIgnore(url, permission, 54 return PermissionDecisionAutoBlocker::RecordIgnore(url, permission,
45 profile()); 55 profile());
46 } 56 }
57
58 void PlaceUnderEmbargo(content::PermissionType permission,
59 const GURL& url,
60 HostContentSettingsMap* map,
61 base::Time current_time) {
62 PermissionDecisionAutoBlocker::PlaceUnderEmbargoForTest(permission, url,
63 map, current_time);
64 }
65
66 bool GetEmbargoStatus(content::PermissionType permission,
67 const GURL& url,
68 HostContentSettingsMap* map) {
69 return PermissionDecisionAutoBlocker::GetEmbargoStatusForTest(permission,
70 url, map);
71 }
72
73 void UpdateEmbargoedStatus(content::PermissionType permission,
74 const GURL& url,
75 base::Time current_time,
76 bool expected_result) {
77 PermissionDecisionAutoBlocker::UpdateEmbargoedStatus(
78 nullptr /* db manager */, permission, url, nullptr /* web contents */,
79 2000 /* timeout in ms */, profile(), current_time,
80 base::Bind(&AutoBlockerCallback, expected_result));
81 }
47 }; 82 };
48 83
49 TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveCountsByUrl) { 84 TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveCountsByUrl) {
50 GURL url1("https://www.google.com"); 85 GURL url1("https://www.google.com");
51 GURL url2("https://www.example.com"); 86 GURL url2("https://www.example.com");
87 base::test::ScopedFeatureList feature_list;
88 feature_list.InitAndEnableFeature(features::kBlockPromptsIfDismissedOften);
52 89
53 // Record some dismissals. 90 // Record some dismissals.
54 EXPECT_EQ(1, RecordDismiss(url1, content::PermissionType::GEOLOCATION)); 91 EXPECT_FALSE(RecordDismissAndEmbargo(
55 EXPECT_EQ(2, RecordDismiss(url1, content::PermissionType::GEOLOCATION)); 92 url1, content::PermissionType::GEOLOCATION, base::Time::Now()));
56 EXPECT_EQ(3, RecordDismiss(url1, content::PermissionType::GEOLOCATION)); 93 EXPECT_EQ(1, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
57 94
58 EXPECT_EQ(1, RecordDismiss(url2, content::PermissionType::GEOLOCATION)); 95 EXPECT_FALSE(RecordDismissAndEmbargo(
59 EXPECT_EQ(1, RecordDismiss(url1, content::PermissionType::NOTIFICATIONS)); 96 url1, content::PermissionType::GEOLOCATION, base::Time::Now()));
97 EXPECT_EQ(2, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
98
99 EXPECT_TRUE(RecordDismissAndEmbargo(
100 url1, content::PermissionType::GEOLOCATION, base::Time::Now()));
101 EXPECT_EQ(3, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
102
103 EXPECT_FALSE(RecordDismissAndEmbargo(
104 url2, content::PermissionType::GEOLOCATION, base::Time::Now()));
105 EXPECT_EQ(1, GetDismissalCount(url2, content::PermissionType::GEOLOCATION));
106
107 EXPECT_FALSE(RecordDismissAndEmbargo(
108 url1, content::PermissionType::NOTIFICATIONS, base::Time::Now()));
109 EXPECT_EQ(1, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS));
60 110
61 // Record some ignores. 111 // Record some ignores.
62 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::MIDI_SYSEX)); 112 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::MIDI_SYSEX));
63 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::DURABLE_STORAGE)); 113 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::DURABLE_STORAGE));
64 EXPECT_EQ(1, RecordIgnore(url2, content::PermissionType::GEOLOCATION)); 114 EXPECT_EQ(1, RecordIgnore(url2, content::PermissionType::GEOLOCATION));
65 EXPECT_EQ(2, RecordIgnore(url2, content::PermissionType::GEOLOCATION)); 115 EXPECT_EQ(2, RecordIgnore(url2, content::PermissionType::GEOLOCATION));
66 116
67 PermissionDecisionAutoBlocker::RemoveCountsByUrl(profile(), 117 PermissionDecisionAutoBlocker::RemoveCountsByUrl(profile(),
68 base::Bind(&FilterGoogle)); 118 base::Bind(&FilterGoogle));
69 119
70 // Expect that url1's actions are gone, but url2's remain. 120 // Expect that url1's actions are gone, but url2's remain.
71 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::GEOLOCATION)); 121 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
72 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS)); 122 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS));
73 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::MIDI_SYSEX)); 123 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::MIDI_SYSEX));
74 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::DURABLE_STORAGE)); 124 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::DURABLE_STORAGE));
75 125
76 EXPECT_EQ(1, GetDismissalCount(url2, content::PermissionType::GEOLOCATION)); 126 EXPECT_EQ(1, GetDismissalCount(url2, content::PermissionType::GEOLOCATION));
77 EXPECT_EQ(2, GetIgnoreCount(url2, content::PermissionType::GEOLOCATION)); 127 EXPECT_EQ(2, GetIgnoreCount(url2, content::PermissionType::GEOLOCATION));
78 128
79 // Add some more actions. 129 // Add some more actions.
80 EXPECT_EQ(1, RecordDismiss(url1, content::PermissionType::GEOLOCATION)); 130 EXPECT_FALSE(RecordDismissAndEmbargo(
81 EXPECT_EQ(1, RecordDismiss(url1, content::PermissionType::NOTIFICATIONS)); 131 url1, content::PermissionType::GEOLOCATION, base::Time::Now()));
82 EXPECT_EQ(2, RecordDismiss(url2, content::PermissionType::GEOLOCATION)); 132 EXPECT_EQ(1, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
133
134 EXPECT_FALSE(RecordDismissAndEmbargo(
135 url1, content::PermissionType::NOTIFICATIONS, base::Time::Now()));
136 EXPECT_EQ(1, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS));
137
138 EXPECT_FALSE(RecordDismissAndEmbargo(
139 url2, content::PermissionType::GEOLOCATION, base::Time::Now()));
140 EXPECT_EQ(2, GetDismissalCount(url2, content::PermissionType::GEOLOCATION));
83 141
84 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::GEOLOCATION)); 142 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::GEOLOCATION));
85 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::NOTIFICATIONS)); 143 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::NOTIFICATIONS));
86 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::DURABLE_STORAGE)); 144 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::DURABLE_STORAGE));
87 EXPECT_EQ(1, RecordIgnore(url2, content::PermissionType::MIDI_SYSEX)); 145 EXPECT_EQ(1, RecordIgnore(url2, content::PermissionType::MIDI_SYSEX));
88 146
89 // Remove everything and expect that it's all gone. 147 // Remove everything and expect that it's all gone.
90 PermissionDecisionAutoBlocker::RemoveCountsByUrl(profile(), 148 PermissionDecisionAutoBlocker::RemoveCountsByUrl(profile(),
91 base::Bind(&FilterAll)); 149 base::Bind(&FilterAll));
92 150
93 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::GEOLOCATION)); 151 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
94 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS)); 152 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS));
95 EXPECT_EQ(0, GetDismissalCount(url2, content::PermissionType::GEOLOCATION)); 153 EXPECT_EQ(0, GetDismissalCount(url2, content::PermissionType::GEOLOCATION));
96 154
97 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::GEOLOCATION)); 155 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::GEOLOCATION));
98 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::NOTIFICATIONS)); 156 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::NOTIFICATIONS));
99 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::GEOLOCATION)); 157 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::GEOLOCATION));
100 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::DURABLE_STORAGE)); 158 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::DURABLE_STORAGE));
101 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::MIDI_SYSEX)); 159 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::MIDI_SYSEX));
102 } 160 }
161
162 // Check that IsUnderEmbargo returns the correct value when the embargo is set
163 // and expires.
164 TEST_F(PermissionDecisionAutoBlockerUnitTest, CheckEmbargoStatus) {
165 GURL url("https://www.google.com");
166 auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
167 base::Time time_now = base::Time::Now();
168 base::test::ScopedFeatureList feature_list;
169 feature_list.InitAndEnableFeature(features::kPermissionsBlacklist);
170
171 EXPECT_TRUE(base::FeatureList::IsEnabled(features::kPermissionsBlacklist));
172
173 PlaceUnderEmbargo(content::PermissionType::GEOLOCATION, url, map, time_now);
174
175 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
176 content::PermissionType::GEOLOCATION, profile(), url, time_now));
177
178 // Check that the origin is not under embargo for another permission.
179 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
180 content::PermissionType::NOTIFICATIONS, profile(), url, time_now));
181
182 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
183 content::PermissionType::GEOLOCATION, profile(), url,
184 time_now + base::TimeDelta::FromDays(5)));
185
186 // Check embargo is lifted on expiry day. A small offset after the exact
187 // embargo expiration date has been added to account for any precision errors
188 // when removing the date stored as a double from the permission dictionary.
189 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
190 content::PermissionType::GEOLOCATION, profile(), url,
191 time_now + base::TimeDelta::FromHours(7 * 24 + 1)));
192
193 // Check embargo is lifted well after the expiry day.
194 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
195 content::PermissionType::GEOLOCATION, profile(), url,
196 time_now + base::TimeDelta::FromDays(8)));
197
198 // Place under embargo again.
199 time_now = base::Time::Now();
200 PlaceUnderEmbargo(content::PermissionType::NOTIFICATIONS, url, map, time_now);
201
202 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
203 content::PermissionType::NOTIFICATIONS, profile(), url, time_now));
204 }
205
206 // Check that the embargo status is correctly recorded in PlaceUnderEmbargo.
207 TEST_F(PermissionDecisionAutoBlockerUnitTest, TestUpdatingEmbargoStatus) {
208 GURL url("https://www.google.com");
209 auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
210
211 EXPECT_FALSE(
212 GetEmbargoStatus(content::PermissionType::GEOLOCATION, url, map));
213
214 PlaceUnderEmbargo(content::PermissionType::GEOLOCATION, url, map,
215 base::Time::Now());
216
217 EXPECT_TRUE(GetEmbargoStatus(content::PermissionType::GEOLOCATION, url, map));
218 }
219
220 // Tests the alternating pattern of the block on multiple dismiss behaviour. On
221 // N prior dismissals, the N+1th request will cause the origin to be embargoed
222 // for the requested permission and automatically blocked. Each time the embargo
223 // is lifted, the site gets another chance to request the permission, but if it
224 // is again dismissed it is placed under embargo again and the request
225 // automatically blocked for that period.
226 TEST_F(PermissionDecisionAutoBlockerUnitTest, TestDismissEmbargo) {
227 GURL url("https://www.google.com");
228 base::Time time_now = base::Time::Now();
229 // Enable the autoblocking feature, which is disabled by default.
230 base::test::ScopedFeatureList feature_list;
231 feature_list.InitAndEnableFeature(features::kBlockPromptsIfDismissedOften);
232
233 EXPECT_TRUE(
234 base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften));
235
236 // Record some dismisses.
237 EXPECT_FALSE(RecordDismissAndEmbargo(
238 url, content::PermissionType::GEOLOCATION, time_now));
239 EXPECT_FALSE(RecordDismissAndEmbargo(
240 url, content::PermissionType::GEOLOCATION, time_now));
241
242 // A request with < 3 prior dismisses should not be automatically blocked.
243 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
244 content::PermissionType::GEOLOCATION, profile(), url, time_now));
245
246 // After the 3rd dismiss subsequent permission requests should be autoblocked.
247 EXPECT_TRUE(RecordDismissAndEmbargo(url, content::PermissionType::GEOLOCATION,
248 time_now));
249 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
250 content::PermissionType::GEOLOCATION, profile(), url, time_now));
251
252 // Accelerate time forward, check that the embargo status is lifted and the
253 // request won't be automatically blocked.
254 time_now += base::TimeDelta::FromDays(8);
255 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
256 content::PermissionType::GEOLOCATION, profile(), url, time_now));
257
258 // Record another dismiss, subsequent requests should be autoblocked again.
259 EXPECT_TRUE(RecordDismissAndEmbargo(url, content::PermissionType::GEOLOCATION,
260 time_now));
261 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
262 content::PermissionType::GEOLOCATION, profile(), url, time_now));
263
264 // Accelerate time again, check embargo is lifted and another permission
265 // request is let through.
266 time_now += base::TimeDelta::FromDays(8);
267 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
268 content::PermissionType::GEOLOCATION, profile(), url, time_now));
269 }
270
271 // Test the logic for different combinations of embargo.
272 TEST_F(PermissionDecisionAutoBlockerUnitTest, TestExpiredBlacklistEmbargo) {
273 GURL url("https://www.google.com");
274 base::Time time_now = base::Time::Now();
275 auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
276
277 // Enable both dismissals and permissions blacklisting features.
278 base::test::ScopedFeatureList feature_list;
279 feature_list.InitWithFeatures({features::kBlockPromptsIfDismissedOften,
280 features::kPermissionsBlacklist},
281 {});
raymes 2017/01/18 23:35:00 nit: it might be worth just setting up these featu
meredithl 2017/01/19 02:11:43 Acknowledged.
282
283 EXPECT_TRUE(
284 base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften));
285 EXPECT_TRUE(base::FeatureList::IsEnabled(features::kPermissionsBlacklist));
286
287 // Place under blacklist embargo and check the status.
288 PlaceUnderEmbargo(content::PermissionType::GEOLOCATION, url, map,
289 base::Time::Now());
290 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
291 content::PermissionType::GEOLOCATION, profile(), url,
292 time_now + base::TimeDelta::FromDays(5)));
293
294 // Accelerate time to a point where the blacklist embargo should be expired.
295 time_now += base::TimeDelta::FromDays(8);
296
297 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
298 content::PermissionType::GEOLOCATION, profile(), url,
299 time_now + base::TimeDelta::FromDays(5)));
300
301 // Record dismisses to place it under dismissal embargo.
302 EXPECT_FALSE(RecordDismissAndEmbargo(
303 url, content::PermissionType::GEOLOCATION, time_now));
304 EXPECT_FALSE(RecordDismissAndEmbargo(
305 url, content::PermissionType::GEOLOCATION, time_now));
306 EXPECT_TRUE(RecordDismissAndEmbargo(url, content::PermissionType::GEOLOCATION,
307 time_now));
308
309 // Check that it still returns true, even though the previous embargo for
310 // blacklisting has expired.
311 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
312 content::PermissionType::GEOLOCATION, profile(), url, time_now));
313 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698