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

Side by Side Diff: chrome/browser/permissions/permission_decision_auto_blocker.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
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 <memory> 7 #include <memory>
8 8
9 #include "base/feature_list.h" 9 #include "base/feature_list.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/time/time.h"
13 #include "base/values.h" 14 #include "base/values.h"
14 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 15 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
16 #include "chrome/browser/permissions/permission_blacklist_client.h"
15 #include "chrome/browser/permissions/permission_util.h" 17 #include "chrome/browser/permissions/permission_util.h"
16 #include "chrome/common/chrome_features.h" 18 #include "chrome/common/chrome_features.h"
17 #include "components/content_settings/core/browser/host_content_settings_map.h" 19 #include "components/content_settings/core/browser/host_content_settings_map.h"
18 #include "components/variations/variations_associated_data.h" 20 #include "components/variations/variations_associated_data.h"
19 #include "content/public/browser/permission_type.h" 21 #include "content/public/browser/permission_type.h"
22 #include "content/public/browser/web_contents.h"
20 #include "url/gurl.h" 23 #include "url/gurl.h"
21 24
22 namespace { 25 namespace {
23 26
24 // The number of times that users may explicitly dismiss a permission prompt 27 // The number of times that users may explicitly dismiss a permission prompt
25 // from an origin before it is automatically blocked. 28 // from an origin before it is automatically blocked.
26 int g_prompt_dismissals_before_block = 3; 29 int g_prompt_dismissals_before_block = 3;
27 30
31 // The number of days that an origin will stay under embargo for a requested
32 // permission due to blacklisting.
33 int g_blacklist_embargo_days = 7;
34
35 // The number of days that an origin will stay under embargo for a requested
36 // permission due to repeated dismissals.
37 int g_dismissal_embargo_days = 7;
38
28 std::unique_ptr<base::DictionaryValue> GetOriginDict( 39 std::unique_ptr<base::DictionaryValue> GetOriginDict(
29 HostContentSettingsMap* settings, 40 HostContentSettingsMap* settings,
30 const GURL& origin_url) { 41 const GURL& origin_url) {
31 std::unique_ptr<base::DictionaryValue> dict = 42 std::unique_ptr<base::DictionaryValue> dict =
32 base::DictionaryValue::From(settings->GetWebsiteSetting( 43 base::DictionaryValue::From(settings->GetWebsiteSetting(
33 origin_url, origin_url, 44 origin_url, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
34 CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, std::string(), 45 std::string(), nullptr));
35 nullptr));
36 if (!dict) 46 if (!dict)
37 return base::MakeUnique<base::DictionaryValue>(); 47 return base::MakeUnique<base::DictionaryValue>();
38 48
39 return dict; 49 return dict;
40 } 50 }
41 51
42 base::DictionaryValue* GetOrCreatePermissionDict( 52 base::DictionaryValue* GetOrCreatePermissionDict(
43 base::DictionaryValue* origin_dict, 53 base::DictionaryValue* origin_dict,
44 const std::string& permission) { 54 const std::string& permission) {
45 base::DictionaryValue* permission_dict = nullptr; 55 base::DictionaryValue* permission_dict = nullptr;
(...skipping 29 matching lines...) Expand all
75 return current_count; 85 return current_count;
76 } 86 }
77 87
78 int GetActionCount(const GURL& url, 88 int GetActionCount(const GURL& url,
79 content::PermissionType permission, 89 content::PermissionType permission,
80 const char* key, 90 const char* key,
81 Profile* profile) { 91 Profile* profile) {
82 HostContentSettingsMap* map = 92 HostContentSettingsMap* map =
83 HostContentSettingsMapFactory::GetForProfile(profile); 93 HostContentSettingsMapFactory::GetForProfile(profile);
84 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); 94 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
85
86 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( 95 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
87 dict.get(), PermissionUtil::GetPermissionString(permission)); 96 dict.get(), PermissionUtil::GetPermissionString(permission));
88 97
89 int current_count = 0; 98 int current_count = 0;
90 permission_dict->GetInteger(key, &current_count); 99 permission_dict->GetInteger(key, &current_count);
91 return current_count; 100 return current_count;
92 } 101 }
93 102
94 } // namespace 103 } // namespace
95 104
96 // static 105 // static
97 const char PermissionDecisionAutoBlocker::kPromptDismissCountKey[] = 106 const char PermissionDecisionAutoBlocker::kPromptDismissCountKey[] =
98 "dismiss_count"; 107 "dismiss_count";
99 108
100 // static 109 // static
101 const char PermissionDecisionAutoBlocker::kPromptIgnoreCountKey[] = 110 const char PermissionDecisionAutoBlocker::kPromptIgnoreCountKey[] =
102 "ignore_count"; 111 "ignore_count";
103 112
104 // static 113 // static
114 const char PermissionDecisionAutoBlocker::kPermissionBlacklistEmbargoKey[] =
115 "blacklisting_embargo_days";
116
117 // static
118 const char PermissionDecisionAutoBlocker::kPermissionDismissalEmbargoKey[] =
119 "dismissal_embargo_days";
120
121 // static
105 void PermissionDecisionAutoBlocker::RemoveCountsByUrl( 122 void PermissionDecisionAutoBlocker::RemoveCountsByUrl(
106 Profile* profile, 123 Profile* profile,
107 base::Callback<bool(const GURL& url)> filter) { 124 base::Callback<bool(const GURL& url)> filter) {
108 HostContentSettingsMap* map = 125 HostContentSettingsMap* map =
109 HostContentSettingsMapFactory::GetForProfile(profile); 126 HostContentSettingsMapFactory::GetForProfile(profile);
110 127
111 std::unique_ptr<ContentSettingsForOneType> settings( 128 std::unique_ptr<ContentSettingsForOneType> settings(
112 new ContentSettingsForOneType); 129 new ContentSettingsForOneType);
113 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, 130 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
114 std::string(), settings.get()); 131 std::string(), settings.get());
(...skipping 19 matching lines...) Expand all
134 151
135 // static 152 // static
136 int PermissionDecisionAutoBlocker::GetIgnoreCount( 153 int PermissionDecisionAutoBlocker::GetIgnoreCount(
137 const GURL& url, 154 const GURL& url,
138 content::PermissionType permission, 155 content::PermissionType permission,
139 Profile* profile) { 156 Profile* profile) {
140 return GetActionCount(url, permission, kPromptIgnoreCountKey, profile); 157 return GetActionCount(url, permission, kPromptIgnoreCountKey, profile);
141 } 158 }
142 159
143 // static 160 // static
144 int PermissionDecisionAutoBlocker::RecordDismiss( 161 bool PermissionDecisionAutoBlocker::RecordDismissAndEmbargo(
145 const GURL& url, 162 const GURL& url,
146 content::PermissionType permission, 163 content::PermissionType permission,
147 Profile* profile) { 164 Profile* profile,
148 return RecordActionInWebsiteSettings(url, permission, kPromptDismissCountKey, 165 base::Time current_time) {
149 profile); 166 int current_dismissal_count = RecordActionInWebsiteSettings(
167 url, permission, kPromptDismissCountKey, profile);
168 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) &&
169 current_dismissal_count >= g_prompt_dismissals_before_block) {
170 HostContentSettingsMap* map =
171 HostContentSettingsMapFactory::GetForProfile(profile);
172 PlaceUnderEmbargo(permission, url, map, current_time,
173 kPermissionDismissalEmbargoKey);
174 return true;
175 }
176 return false;
150 } 177 }
151 178
152 // static 179 // static
153 int PermissionDecisionAutoBlocker::RecordIgnore( 180 int PermissionDecisionAutoBlocker::RecordIgnore(
154 const GURL& url, 181 const GURL& url,
155 content::PermissionType permission, 182 content::PermissionType permission,
156 Profile* profile) { 183 Profile* profile) {
157 return RecordActionInWebsiteSettings(url, permission, kPromptIgnoreCountKey, 184 return RecordActionInWebsiteSettings(url, permission, kPromptIgnoreCountKey,
158 profile); 185 profile);
159 } 186 }
160 187
161 // static 188 // static
162 bool PermissionDecisionAutoBlocker::ShouldChangeDismissalToBlock( 189 bool PermissionDecisionAutoBlocker::ShouldChangeDismissalToBlock(
163 const GURL& url, 190 const GURL& url,
164 content::PermissionType permission, 191 content::PermissionType permission,
165 Profile* profile) { 192 Profile* profile) {
166 int current_dismissal_count = RecordDismiss(url, permission, profile); 193 int current_dismissal_count =
194 RecordDismissAndEmbargo(url, permission, profile, base::Time::Now());
167 195
168 if (!base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften)) 196 if (!base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften))
169 return false; 197 return false;
170 198
171 return current_dismissal_count >= g_prompt_dismissals_before_block; 199 return current_dismissal_count >= g_prompt_dismissals_before_block;
172 } 200 }
173 201
174 // static 202 // static
175 void PermissionDecisionAutoBlocker::UpdateFromVariations() { 203 void PermissionDecisionAutoBlocker::UpdateFromVariations() {
176 int prompt_dismissals = -1; 204 int prompt_dismissals = -1;
177 std::string value = variations::GetVariationParamValueByFeature( 205 int blacklist_embargo_days = -1;
206 int dismissal_embargo_days = -1;
207 std::string dismissals_value = variations::GetVariationParamValueByFeature(
178 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey); 208 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey);
209 std::string blacklist_embargo_value =
210 variations::GetVariationParamValueByFeature(
211 features::kPermissionsBlacklist, kPermissionBlacklistEmbargoKey);
212 std::string dismissal_embargo_value =
213 variations::GetVariationParamValueByFeature(
214 features::kBlockPromptsIfDismissedOften,
215 kPermissionDismissalEmbargoKey);
216 // If converting the value fails, stick with the current value.
217 if (base::StringToInt(dismissals_value, &prompt_dismissals) &&
218 prompt_dismissals > 0) {
219 g_prompt_dismissals_before_block = prompt_dismissals;
220 }
221 if (base::StringToInt(blacklist_embargo_value, &blacklist_embargo_days) &&
222 blacklist_embargo_days > 0) {
223 g_blacklist_embargo_days = blacklist_embargo_days;
224 }
225 if (base::StringToInt(dismissal_embargo_value, &dismissal_embargo_days) &&
226 dismissal_embargo_days > 0) {
227 g_dismissal_embargo_days = dismissal_embargo_days;
228 }
229 }
179 230
180 // If converting the value fails, stick with the current value. 231 // static
181 if (base::StringToInt(value, &prompt_dismissals) && prompt_dismissals > 0) 232 // TODO(meredithl): Have PermissionDecisionAutoBlocker handle the database
182 g_prompt_dismissals_before_block = prompt_dismissals; 233 // manager, rather than passing it in.
234 void PermissionDecisionAutoBlocker::UpdateEmbargoedStatus(
235 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
236 content::PermissionType permission,
237 const GURL& request_origin,
238 content::WebContents* web_contents,
239 int timeout,
240 Profile* profile,
241 base::Time current_time,
242 base::Callback<void(bool)> callback) {
243 // Check if origin is currently under embargo for the requested permission.
244 if (IsUnderEmbargo(permission, profile, request_origin, current_time)) {
245 callback.Run(true /* permission_blocked */);
246 return;
247 }
248
249 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) &&
250 db_manager) {
251 PermissionBlacklistClient::CheckSafeBrowsingBlacklist(
252 db_manager, permission, request_origin, web_contents, timeout,
253 base::Bind(&PermissionDecisionAutoBlocker::CheckSafeBrowsingResult,
254 permission, profile, request_origin, current_time,
255 callback));
256 return;
257 }
258
259 callback.Run(false /* permission blocked */);
183 } 260 }
261
262 // static
263 bool PermissionDecisionAutoBlocker::IsUnderEmbargo(
264 content::PermissionType permission,
265 Profile* profile,
266 const GURL& request_origin,
267 base::Time current_time) {
268 HostContentSettingsMap* map =
269 HostContentSettingsMapFactory::GetForProfile(profile);
270 std::unique_ptr<base::DictionaryValue> dict =
271 GetOriginDict(map, request_origin);
272 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
273 dict.get(), PermissionUtil::GetPermissionString(permission));
274 double embargo_date = -1;
275 bool is_under_dismiss_embargo = false;
276 bool is_under_blacklist_embargo = false;
277 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) &&
278 permission_dict->GetDouble(kPermissionBlacklistEmbargoKey,
279 &embargo_date)) {
280 if (current_time <
281 base::Time::FromInternalValue(embargo_date) +
282 base::TimeDelta::FromDays(g_blacklist_embargo_days)) {
283 is_under_blacklist_embargo = true;
284 }
285 }
286
287 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) &&
288 permission_dict->GetDouble(kPermissionDismissalEmbargoKey,
289 &embargo_date)) {
290 if (current_time <
291 base::Time::FromInternalValue(embargo_date) +
292 base::TimeDelta::FromDays(g_dismissal_embargo_days)) {
293 is_under_dismiss_embargo = true;
294 }
295 }
296 // If either embargoes is still in effect, return true.
297 return is_under_dismiss_embargo || is_under_blacklist_embargo;
298 }
299
300 void PermissionDecisionAutoBlocker::PlaceUnderEmbargo(
301 content::PermissionType permission,
302 const GURL& request_origin,
303 HostContentSettingsMap* map,
304 base::Time current_time,
305 const char* key) {
306 std::unique_ptr<base::DictionaryValue> dict =
307 GetOriginDict(map, request_origin);
308 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
309 dict.get(), PermissionUtil::GetPermissionString(permission));
310 permission_dict->SetDouble(key, current_time.ToInternalValue());
311 map->SetWebsiteSettingDefaultScope(
312 request_origin, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
313 std::string(), std::move(dict));
314 }
315
316 // static
317 void PermissionDecisionAutoBlocker::CheckSafeBrowsingResult(
318 content::PermissionType permission,
319 Profile* profile,
320 const GURL& request_origin,
321 base::Time current_time,
322 base::Callback<void(bool)> callback,
323 bool should_be_embargoed) {
324 if (should_be_embargoed) {
325 // Requesting site is blacklisted for this permission, update the content
326 // setting to place it under embargo.
327 PlaceUnderEmbargo(permission, request_origin,
328 HostContentSettingsMapFactory::GetForProfile(profile),
329 current_time, kPermissionBlacklistEmbargoKey);
330 }
331 callback.Run(should_be_embargoed /* permission blocked */);
332 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698