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

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

Issue 2622983003: Implement embargo in PermissionDecisionAutoBlocker (Closed)
Patch Set: Testing clean up and nits 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
« no previous file with comments | « chrome/browser/permissions/permission_decision_auto_blocker.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
33 // TODO(meredithl): Write unit tests to simulate entering Permissions
34 // Blacklisting embargo status via the public API.
24 class PermissionDecisionAutoBlockerUnitTest 35 class PermissionDecisionAutoBlockerUnitTest
25 : public ChromeRenderViewHostTestHarness { 36 : public ChromeRenderViewHostTestHarness {
26 protected: 37 protected:
27 int GetDismissalCount(const GURL& url, 38 int GetDismissalCount(const GURL& url, content::PermissionType permission) {
28 content::PermissionType permission) { 39 return PermissionDecisionAutoBlocker::GetDismissCount(url, permission,
29 return PermissionDecisionAutoBlocker::GetDismissCount( 40 profile());
30 url, permission, profile());
31 } 41 }
32 42
33 int GetIgnoreCount(const GURL& url, content::PermissionType permission) { 43 int GetIgnoreCount(const GURL& url, content::PermissionType permission) {
34 return PermissionDecisionAutoBlocker::GetIgnoreCount( 44 return PermissionDecisionAutoBlocker::GetIgnoreCount(url, permission,
35 url, permission, profile()); 45 profile());
36 } 46 }
37 47
38 int RecordDismiss(const GURL& url, content::PermissionType permission) { 48 int RecordDismissAndEmbargo(const GURL& url,
39 return PermissionDecisionAutoBlocker::RecordDismiss(url, permission, 49 content::PermissionType permission,
40 profile()); 50 base::Time current_time) {
51 return PermissionDecisionAutoBlocker::RecordDismissAndEmbargo(
52 url, permission, profile(), current_time);
41 } 53 }
42 54
43 int RecordIgnore(const GURL& url, content::PermissionType permission) { 55 int RecordIgnore(const GURL& url, content::PermissionType permission) {
44 return PermissionDecisionAutoBlocker::RecordIgnore(url, permission, 56 return PermissionDecisionAutoBlocker::RecordIgnore(url, permission,
45 profile()); 57 profile());
46 } 58 }
59
60 void UpdateEmbargoedStatus(content::PermissionType permission,
61 const GURL& url,
62 base::Time current_time,
63 bool expected_result) {
64 PermissionDecisionAutoBlocker::UpdateEmbargoedStatus(
65 nullptr /* db manager */, permission, url, nullptr /* web contents */,
66 2000 /* timeout in ms */, profile(), current_time,
67 base::Bind(&AutoBlockerCallback, expected_result));
68 }
69
70 // Manually placing an origin, permission pair under embargo for blacklisting.
71 // To embargo on dismissals, RecordDismissAndEmbargo can be used.
72 void PlaceUnderBlacklistEmbargo(content::PermissionType permission,
73 const GURL& url,
74 HostContentSettingsMap* map,
75 base::Time current_time) {
76 PermissionDecisionAutoBlocker::PlaceUnderEmbargo(
77 permission, url, map, current_time,
78 PermissionDecisionAutoBlocker::kPermissionBlacklistEmbargoKey);
79 }
47 }; 80 };
48 81
49 TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveCountsByUrl) { 82 TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveCountsByUrl) {
50 GURL url1("https://www.google.com"); 83 GURL url1("https://www.google.com");
51 GURL url2("https://www.example.com"); 84 GURL url2("https://www.example.com");
85 base::test::ScopedFeatureList feature_list;
86 feature_list.InitAndEnableFeature(features::kBlockPromptsIfDismissedOften);
52 87
53 // Record some dismissals. 88 // Record some dismissals.
54 EXPECT_EQ(1, RecordDismiss(url1, content::PermissionType::GEOLOCATION)); 89 EXPECT_FALSE(RecordDismissAndEmbargo(
55 EXPECT_EQ(2, RecordDismiss(url1, content::PermissionType::GEOLOCATION)); 90 url1, content::PermissionType::GEOLOCATION, base::Time::Now()));
56 EXPECT_EQ(3, RecordDismiss(url1, content::PermissionType::GEOLOCATION)); 91 EXPECT_EQ(1, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
57 92
58 EXPECT_EQ(1, RecordDismiss(url2, content::PermissionType::GEOLOCATION)); 93 EXPECT_FALSE(RecordDismissAndEmbargo(
59 EXPECT_EQ(1, RecordDismiss(url1, content::PermissionType::NOTIFICATIONS)); 94 url1, content::PermissionType::GEOLOCATION, base::Time::Now()));
95 EXPECT_EQ(2, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
96
97 EXPECT_TRUE(RecordDismissAndEmbargo(
98 url1, content::PermissionType::GEOLOCATION, base::Time::Now()));
99 EXPECT_EQ(3, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
100
101 EXPECT_FALSE(RecordDismissAndEmbargo(
102 url2, content::PermissionType::GEOLOCATION, base::Time::Now()));
103 EXPECT_EQ(1, GetDismissalCount(url2, content::PermissionType::GEOLOCATION));
104
105 EXPECT_FALSE(RecordDismissAndEmbargo(
106 url1, content::PermissionType::NOTIFICATIONS, base::Time::Now()));
107 EXPECT_EQ(1, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS));
60 108
61 // Record some ignores. 109 // Record some ignores.
62 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::MIDI_SYSEX)); 110 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::MIDI_SYSEX));
63 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::DURABLE_STORAGE)); 111 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::DURABLE_STORAGE));
64 EXPECT_EQ(1, RecordIgnore(url2, content::PermissionType::GEOLOCATION)); 112 EXPECT_EQ(1, RecordIgnore(url2, content::PermissionType::GEOLOCATION));
65 EXPECT_EQ(2, RecordIgnore(url2, content::PermissionType::GEOLOCATION)); 113 EXPECT_EQ(2, RecordIgnore(url2, content::PermissionType::GEOLOCATION));
66 114
67 PermissionDecisionAutoBlocker::RemoveCountsByUrl(profile(), 115 PermissionDecisionAutoBlocker::RemoveCountsByUrl(profile(),
68 base::Bind(&FilterGoogle)); 116 base::Bind(&FilterGoogle));
69 117
70 // Expect that url1's actions are gone, but url2's remain. 118 // Expect that url1's actions are gone, but url2's remain.
71 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::GEOLOCATION)); 119 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
72 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS)); 120 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS));
73 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::MIDI_SYSEX)); 121 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::MIDI_SYSEX));
74 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::DURABLE_STORAGE)); 122 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::DURABLE_STORAGE));
75 123
76 EXPECT_EQ(1, GetDismissalCount(url2, content::PermissionType::GEOLOCATION)); 124 EXPECT_EQ(1, GetDismissalCount(url2, content::PermissionType::GEOLOCATION));
77 EXPECT_EQ(2, GetIgnoreCount(url2, content::PermissionType::GEOLOCATION)); 125 EXPECT_EQ(2, GetIgnoreCount(url2, content::PermissionType::GEOLOCATION));
78 126
79 // Add some more actions. 127 // Add some more actions.
80 EXPECT_EQ(1, RecordDismiss(url1, content::PermissionType::GEOLOCATION)); 128 EXPECT_FALSE(RecordDismissAndEmbargo(
81 EXPECT_EQ(1, RecordDismiss(url1, content::PermissionType::NOTIFICATIONS)); 129 url1, content::PermissionType::GEOLOCATION, base::Time::Now()));
82 EXPECT_EQ(2, RecordDismiss(url2, content::PermissionType::GEOLOCATION)); 130 EXPECT_EQ(1, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
131
132 EXPECT_FALSE(RecordDismissAndEmbargo(
133 url1, content::PermissionType::NOTIFICATIONS, base::Time::Now()));
134 EXPECT_EQ(1, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS));
135
136 EXPECT_FALSE(RecordDismissAndEmbargo(
137 url2, content::PermissionType::GEOLOCATION, base::Time::Now()));
138 EXPECT_EQ(2, GetDismissalCount(url2, content::PermissionType::GEOLOCATION));
83 139
84 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::GEOLOCATION)); 140 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::GEOLOCATION));
85 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::NOTIFICATIONS)); 141 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::NOTIFICATIONS));
86 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::DURABLE_STORAGE)); 142 EXPECT_EQ(1, RecordIgnore(url1, content::PermissionType::DURABLE_STORAGE));
87 EXPECT_EQ(1, RecordIgnore(url2, content::PermissionType::MIDI_SYSEX)); 143 EXPECT_EQ(1, RecordIgnore(url2, content::PermissionType::MIDI_SYSEX));
88 144
89 // Remove everything and expect that it's all gone. 145 // Remove everything and expect that it's all gone.
90 PermissionDecisionAutoBlocker::RemoveCountsByUrl(profile(), 146 PermissionDecisionAutoBlocker::RemoveCountsByUrl(profile(),
91 base::Bind(&FilterAll)); 147 base::Bind(&FilterAll));
92 148
93 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::GEOLOCATION)); 149 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::GEOLOCATION));
94 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS)); 150 EXPECT_EQ(0, GetDismissalCount(url1, content::PermissionType::NOTIFICATIONS));
95 EXPECT_EQ(0, GetDismissalCount(url2, content::PermissionType::GEOLOCATION)); 151 EXPECT_EQ(0, GetDismissalCount(url2, content::PermissionType::GEOLOCATION));
96 152
97 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::GEOLOCATION)); 153 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::GEOLOCATION));
98 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::NOTIFICATIONS)); 154 EXPECT_EQ(0, GetIgnoreCount(url1, content::PermissionType::NOTIFICATIONS));
99 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::GEOLOCATION)); 155 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::GEOLOCATION));
100 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::DURABLE_STORAGE)); 156 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::DURABLE_STORAGE));
101 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::MIDI_SYSEX)); 157 EXPECT_EQ(0, GetIgnoreCount(url2, content::PermissionType::MIDI_SYSEX));
102 } 158 }
159
160 // Check that IsUnderEmbargo returns the correct value when the embargo is set
161 // and expires.
162 TEST_F(PermissionDecisionAutoBlockerUnitTest, CheckEmbargoStatus) {
163 GURL url("https://www.google.com");
164 auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
165 base::Time time_now = base::Time::Now();
166 base::test::ScopedFeatureList feature_list;
167
168 feature_list.InitAndEnableFeature(features::kPermissionsBlacklist);
169 EXPECT_TRUE(base::FeatureList::IsEnabled(features::kPermissionsBlacklist));
170
171 // Manually place url under embargo and confirm embargo status.
172 PlaceUnderBlacklistEmbargo(content::PermissionType::GEOLOCATION, url, map,
173 time_now);
174 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
175 content::PermissionType::GEOLOCATION, profile(), url, time_now));
176
177 // Check that the origin is not under embargo for another permission.
178 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
179 content::PermissionType::NOTIFICATIONS, profile(), url, time_now));
180
181 // Confirm embargo status during the embargo period.
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 and verify the embargo status.
199 time_now = base::Time::Now();
200 PlaceUnderBlacklistEmbargo(content::PermissionType::NOTIFICATIONS, url, map,
201 time_now);
202 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
203 content::PermissionType::NOTIFICATIONS, profile(), url, time_now));
204 }
205
206 // Tests the alternating pattern of the block on multiple dismiss behaviour. On
207 // N dismissals, the origin to be embargoed for the requested permission and
208 // automatically blocked. Each time the embargo is lifted, the site gets another
209 // chance to request the permission, but if it is again dismissed it is placed
210 // under embargo again and its permission requests blocked.
211 TEST_F(PermissionDecisionAutoBlockerUnitTest, TestDismissEmbargo) {
212 GURL url("https://www.google.com");
213 base::Time time_now = base::Time::Now();
214 // Enable the autoblocking feature, which is disabled by default.
215 base::test::ScopedFeatureList feature_list;
216 feature_list.InitAndEnableFeature(features::kBlockPromptsIfDismissedOften);
217
218 EXPECT_TRUE(
219 base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften));
220
221 // Record some dismisses.
222 EXPECT_FALSE(RecordDismissAndEmbargo(
223 url, content::PermissionType::GEOLOCATION, time_now));
224 EXPECT_FALSE(RecordDismissAndEmbargo(
225 url, content::PermissionType::GEOLOCATION, time_now));
226
227 // A request with < 3 prior dismisses should not be automatically blocked.
228 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
229 content::PermissionType::GEOLOCATION, profile(), url, time_now));
230
231 // After the 3rd dismiss subsequent permission requests should be autoblocked.
232 EXPECT_TRUE(RecordDismissAndEmbargo(url, content::PermissionType::GEOLOCATION,
233 time_now));
234 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
235 content::PermissionType::GEOLOCATION, profile(), url, time_now));
236
237 // Accelerate time forward, check that the embargo status is lifted and the
238 // request won't be automatically blocked.
239 time_now += base::TimeDelta::FromDays(8);
240 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
241 content::PermissionType::GEOLOCATION, profile(), url, time_now));
242
243 // Record another dismiss, subsequent requests should be autoblocked again.
244 EXPECT_TRUE(RecordDismissAndEmbargo(url, content::PermissionType::GEOLOCATION,
245 time_now));
246 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
247 content::PermissionType::GEOLOCATION, profile(), url, time_now));
248
249 // Accelerate time again, check embargo is lifted and another permission
250 // request is let through.
251 time_now += base::TimeDelta::FromDays(8);
252 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
253 content::PermissionType::GEOLOCATION, profile(), url, time_now));
254 }
255
256 // Test the logic for a combination of blacklisting and dismissal embargo.
257 TEST_F(PermissionDecisionAutoBlockerUnitTest, TestExpiredBlacklistEmbargo) {
258 GURL url("https://www.google.com");
259 base::Time time_now = base::Time::Now();
260 auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
261
262 // Enable both dismissals and permissions blacklisting features.
263 base::test::ScopedFeatureList feature_list;
264 feature_list.InitWithFeatures({features::kBlockPromptsIfDismissedOften,
265 features::kPermissionsBlacklist},
266 {});
267 EXPECT_TRUE(
268 base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften));
269 EXPECT_TRUE(base::FeatureList::IsEnabled(features::kPermissionsBlacklist));
270
271 // Place under blacklist embargo and check the status.
272 PlaceUnderBlacklistEmbargo(content::PermissionType::GEOLOCATION, url, map,
273 base::Time::Now());
274
275 time_now += base::TimeDelta::FromDays(5);
276 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
277 content::PermissionType::GEOLOCATION, profile(), url, time_now));
278
279 // Record dismisses to place it under dismissal embargo.
280 EXPECT_FALSE(RecordDismissAndEmbargo(
281 url, content::PermissionType::GEOLOCATION, time_now));
282 EXPECT_FALSE(RecordDismissAndEmbargo(
283 url, content::PermissionType::GEOLOCATION, time_now));
284 EXPECT_TRUE(RecordDismissAndEmbargo(url, content::PermissionType::GEOLOCATION,
285 time_now));
286
287 // Accelerate time to a point where the blacklist embargo should be expired.
288 time_now += base::TimeDelta::FromDays(3);
289 EXPECT_FALSE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
290 content::PermissionType::GEOLOCATION, profile(), url,
291 time_now + base::TimeDelta::FromDays(5)));
292
293 // Check that dismissal embargo is still set, even though the blacklisting
294 // embargo has expired.
295 EXPECT_TRUE(PermissionDecisionAutoBlocker::IsUnderEmbargo(
296 content::PermissionType::GEOLOCATION, profile(), url, time_now));
297 }
OLDNEW
« no previous file with comments | « chrome/browser/permissions/permission_decision_auto_blocker.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698