OLD | NEW |
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/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 14 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
15 #include "chrome/browser/permissions/permission_blacklist_client.h" | 15 #include "chrome/browser/permissions/permission_blacklist_client.h" |
16 #include "chrome/browser/permissions/permission_util.h" | 16 #include "chrome/browser/permissions/permission_util.h" |
17 #include "chrome/browser/profiles/incognito_helpers.h" | 17 #include "chrome/browser/profiles/incognito_helpers.h" |
18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 19 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
20 #include "chrome/common/chrome_features.h" | 20 #include "chrome/common/chrome_features.h" |
21 #include "components/content_settings/core/browser/host_content_settings_map.h" | 21 #include "components/content_settings/core/browser/host_content_settings_map.h" |
22 #include "components/keyed_service/content/browser_context_dependency_manager.h" | 22 #include "components/keyed_service/content/browser_context_dependency_manager.h" |
23 #include "components/safe_browsing_db/database_manager.h" | 23 #include "components/safe_browsing_db/database_manager.h" |
24 #include "components/variations/variations_associated_data.h" | 24 #include "components/variations/variations_associated_data.h" |
25 #include "content/public/browser/permission_type.h" | |
26 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
27 #include "url/gurl.h" | 26 #include "url/gurl.h" |
28 | 27 |
29 namespace { | 28 namespace { |
30 | 29 |
31 // The number of times that users may explicitly dismiss a permission prompt | 30 // The number of times that users may explicitly dismiss a permission prompt |
32 // from an origin before it is automatically blocked. | 31 // from an origin before it is automatically blocked. |
33 int g_prompt_dismissals_before_block = 3; | 32 int g_prompt_dismissals_before_block = 3; |
34 | 33 |
35 // The number of days that an origin will stay under embargo for a requested | 34 // The number of days that an origin will stay under embargo for a requested |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 &permission_dict)) { | 66 &permission_dict)) { |
68 permission_dict = new base::DictionaryValue(); | 67 permission_dict = new base::DictionaryValue(); |
69 origin_dict->SetWithoutPathExpansion(permission, | 68 origin_dict->SetWithoutPathExpansion(permission, |
70 base::WrapUnique(permission_dict)); | 69 base::WrapUnique(permission_dict)); |
71 } | 70 } |
72 | 71 |
73 return permission_dict; | 72 return permission_dict; |
74 } | 73 } |
75 | 74 |
76 int RecordActionInWebsiteSettings(const GURL& url, | 75 int RecordActionInWebsiteSettings(const GURL& url, |
77 content::PermissionType permission, | 76 ContentSettingsType permission, |
78 const char* key, | 77 const char* key, |
79 Profile* profile) { | 78 Profile* profile) { |
80 HostContentSettingsMap* map = | 79 HostContentSettingsMap* map = |
81 HostContentSettingsMapFactory::GetForProfile(profile); | 80 HostContentSettingsMapFactory::GetForProfile(profile); |
82 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); | 81 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); |
83 | 82 |
84 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( | 83 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( |
85 dict.get(), PermissionUtil::GetPermissionString(permission)); | 84 dict.get(), PermissionUtil::GetPermissionString(permission)); |
86 | 85 |
87 int current_count = 0; | 86 int current_count = 0; |
88 permission_dict->GetInteger(key, ¤t_count); | 87 permission_dict->GetInteger(key, ¤t_count); |
89 permission_dict->SetInteger(key, ++current_count); | 88 permission_dict->SetInteger(key, ++current_count); |
90 | 89 |
91 map->SetWebsiteSettingDefaultScope( | 90 map->SetWebsiteSettingDefaultScope( |
92 url, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, | 91 url, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, |
93 std::string(), std::move(dict)); | 92 std::string(), std::move(dict)); |
94 | 93 |
95 return current_count; | 94 return current_count; |
96 } | 95 } |
97 | 96 |
98 int GetActionCount(const GURL& url, | 97 int GetActionCount(const GURL& url, |
99 content::PermissionType permission, | 98 ContentSettingsType permission, |
100 const char* key, | 99 const char* key, |
101 Profile* profile) { | 100 Profile* profile) { |
102 HostContentSettingsMap* map = | 101 HostContentSettingsMap* map = |
103 HostContentSettingsMapFactory::GetForProfile(profile); | 102 HostContentSettingsMapFactory::GetForProfile(profile); |
104 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); | 103 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); |
105 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( | 104 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( |
106 dict.get(), PermissionUtil::GetPermissionString(permission)); | 105 dict.get(), PermissionUtil::GetPermissionString(permission)); |
107 | 106 |
108 int current_count = 0; | 107 int current_count = 0; |
109 permission_dict->GetInteger(key, ¤t_count); | 108 permission_dict->GetInteger(key, ¤t_count); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 if (origin.is_valid() && filter.Run(origin)) { | 198 if (origin.is_valid() && filter.Run(origin)) { |
200 map->SetWebsiteSettingDefaultScope( | 199 map->SetWebsiteSettingDefaultScope( |
201 origin, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, | 200 origin, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, |
202 std::string(), nullptr); | 201 std::string(), nullptr); |
203 } | 202 } |
204 } | 203 } |
205 } | 204 } |
206 | 205 |
207 int PermissionDecisionAutoBlocker::GetDismissCount( | 206 int PermissionDecisionAutoBlocker::GetDismissCount( |
208 const GURL& url, | 207 const GURL& url, |
209 content::PermissionType permission) { | 208 ContentSettingsType permission) { |
210 return GetActionCount(url, permission, kPromptDismissCountKey, profile_); | 209 return GetActionCount(url, permission, kPromptDismissCountKey, profile_); |
211 } | 210 } |
212 | 211 |
213 int PermissionDecisionAutoBlocker::GetIgnoreCount( | 212 int PermissionDecisionAutoBlocker::GetIgnoreCount( |
214 const GURL& url, | 213 const GURL& url, |
215 content::PermissionType permission) { | 214 ContentSettingsType permission) { |
216 return GetActionCount(url, permission, kPromptIgnoreCountKey, profile_); | 215 return GetActionCount(url, permission, kPromptIgnoreCountKey, profile_); |
217 } | 216 } |
218 | 217 |
219 bool PermissionDecisionAutoBlocker::RecordDismissAndEmbargo( | 218 bool PermissionDecisionAutoBlocker::RecordDismissAndEmbargo( |
220 const GURL& url, | 219 const GURL& url, |
221 content::PermissionType permission) { | 220 ContentSettingsType permission) { |
222 int current_dismissal_count = RecordActionInWebsiteSettings( | 221 int current_dismissal_count = RecordActionInWebsiteSettings( |
223 url, permission, kPromptDismissCountKey, profile_); | 222 url, permission, kPromptDismissCountKey, profile_); |
224 | 223 |
225 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) && | 224 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) && |
226 current_dismissal_count >= g_prompt_dismissals_before_block) { | 225 current_dismissal_count >= g_prompt_dismissals_before_block) { |
227 PlaceUnderEmbargo(permission, url, kPermissionDismissalEmbargoKey); | 226 PlaceUnderEmbargo(permission, url, kPermissionDismissalEmbargoKey); |
228 return true; | 227 return true; |
229 } | 228 } |
230 return false; | 229 return false; |
231 } | 230 } |
232 | 231 |
233 int PermissionDecisionAutoBlocker::RecordIgnore( | 232 int PermissionDecisionAutoBlocker::RecordIgnore( |
234 const GURL& url, | 233 const GURL& url, |
235 content::PermissionType permission) { | 234 ContentSettingsType permission) { |
236 return RecordActionInWebsiteSettings(url, permission, kPromptIgnoreCountKey, | 235 return RecordActionInWebsiteSettings(url, permission, kPromptIgnoreCountKey, |
237 profile_); | 236 profile_); |
238 } | 237 } |
239 | 238 |
240 // static | 239 // static |
241 void PermissionDecisionAutoBlocker::UpdateFromVariations() { | 240 void PermissionDecisionAutoBlocker::UpdateFromVariations() { |
242 int prompt_dismissals = -1; | 241 int prompt_dismissals = -1; |
243 int blacklist_embargo_days = -1; | 242 int blacklist_embargo_days = -1; |
244 int dismissal_embargo_days = -1; | 243 int dismissal_embargo_days = -1; |
245 std::string dismissals_value = variations::GetVariationParamValueByFeature( | 244 std::string dismissals_value = variations::GetVariationParamValueByFeature( |
(...skipping 14 matching lines...) Expand all Loading... |
260 blacklist_embargo_days > 0) { | 259 blacklist_embargo_days > 0) { |
261 g_blacklist_embargo_days = blacklist_embargo_days; | 260 g_blacklist_embargo_days = blacklist_embargo_days; |
262 } | 261 } |
263 if (base::StringToInt(dismissal_embargo_value, &dismissal_embargo_days) && | 262 if (base::StringToInt(dismissal_embargo_value, &dismissal_embargo_days) && |
264 dismissal_embargo_days > 0) { | 263 dismissal_embargo_days > 0) { |
265 g_dismissal_embargo_days = dismissal_embargo_days; | 264 g_dismissal_embargo_days = dismissal_embargo_days; |
266 } | 265 } |
267 } | 266 } |
268 | 267 |
269 void PermissionDecisionAutoBlocker::UpdateEmbargoedStatus( | 268 void PermissionDecisionAutoBlocker::UpdateEmbargoedStatus( |
270 content::PermissionType permission, | 269 ContentSettingsType permission, |
271 const GURL& request_origin, | 270 const GURL& request_origin, |
272 content::WebContents* web_contents, | 271 content::WebContents* web_contents, |
273 base::Callback<void(bool)> callback) { | 272 base::Callback<void(bool)> callback) { |
274 DCHECK(!IsUnderEmbargo(permission, request_origin)); | 273 DCHECK(!IsUnderEmbargo(permission, request_origin)); |
275 | 274 |
276 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && | 275 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && |
277 db_manager_) { | 276 db_manager_) { |
278 // The CheckSafeBrowsingResult callback won't be called if the profile is | 277 // The CheckSafeBrowsingResult callback won't be called if the profile is |
279 // destroyed before a result is received. In that case this object will have | 278 // destroyed before a result is received. In that case this object will have |
280 // been destroyed by that point. | 279 // been destroyed by that point. |
281 PermissionBlacklistClient::CheckSafeBrowsingBlacklist( | 280 PermissionBlacklistClient::CheckSafeBrowsingBlacklist( |
282 db_manager_, permission, request_origin, web_contents, | 281 db_manager_, permission, request_origin, web_contents, |
283 safe_browsing_timeout_, | 282 safe_browsing_timeout_, |
284 base::Bind(&PermissionDecisionAutoBlocker::CheckSafeBrowsingResult, | 283 base::Bind(&PermissionDecisionAutoBlocker::CheckSafeBrowsingResult, |
285 base::Unretained(this), permission, request_origin, | 284 base::Unretained(this), permission, request_origin, |
286 callback)); | 285 callback)); |
287 return; | 286 return; |
288 } | 287 } |
289 | 288 |
290 callback.Run(false /* permission blocked */); | 289 callback.Run(false /* permission blocked */); |
291 } | 290 } |
292 | 291 |
293 bool PermissionDecisionAutoBlocker::IsUnderEmbargo( | 292 bool PermissionDecisionAutoBlocker::IsUnderEmbargo( |
294 content::PermissionType permission, | 293 ContentSettingsType permission, |
295 const GURL& request_origin) { | 294 const GURL& request_origin) { |
296 HostContentSettingsMap* map = | 295 HostContentSettingsMap* map = |
297 HostContentSettingsMapFactory::GetForProfile(profile_); | 296 HostContentSettingsMapFactory::GetForProfile(profile_); |
298 std::unique_ptr<base::DictionaryValue> dict = | 297 std::unique_ptr<base::DictionaryValue> dict = |
299 GetOriginDict(map, request_origin); | 298 GetOriginDict(map, request_origin); |
300 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( | 299 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( |
301 dict.get(), PermissionUtil::GetPermissionString(permission)); | 300 dict.get(), PermissionUtil::GetPermissionString(permission)); |
302 double embargo_date = -1; | 301 double embargo_date = -1; |
303 bool is_under_dismiss_embargo = false; | 302 bool is_under_dismiss_embargo = false; |
304 bool is_under_blacklist_embargo = false; | 303 bool is_under_blacklist_embargo = false; |
(...skipping 16 matching lines...) Expand all Loading... |
321 base::TimeDelta::FromDays(g_dismissal_embargo_days)) { | 320 base::TimeDelta::FromDays(g_dismissal_embargo_days)) { |
322 is_under_dismiss_embargo = true; | 321 is_under_dismiss_embargo = true; |
323 } | 322 } |
324 } | 323 } |
325 | 324 |
326 // If either embargo is still in effect, return true. | 325 // If either embargo is still in effect, return true. |
327 return is_under_dismiss_embargo || is_under_blacklist_embargo; | 326 return is_under_dismiss_embargo || is_under_blacklist_embargo; |
328 } | 327 } |
329 | 328 |
330 void PermissionDecisionAutoBlocker::CheckSafeBrowsingResult( | 329 void PermissionDecisionAutoBlocker::CheckSafeBrowsingResult( |
331 content::PermissionType permission, | 330 ContentSettingsType permission, |
332 const GURL& request_origin, | 331 const GURL& request_origin, |
333 base::Callback<void(bool)> callback, | 332 base::Callback<void(bool)> callback, |
334 bool should_be_embargoed) { | 333 bool should_be_embargoed) { |
335 if (should_be_embargoed) { | 334 if (should_be_embargoed) { |
336 // Requesting site is blacklisted for this permission, update the content | 335 // Requesting site is blacklisted for this permission, update the content |
337 // setting to place it under embargo. | 336 // setting to place it under embargo. |
338 PlaceUnderEmbargo(permission, request_origin, | 337 PlaceUnderEmbargo(permission, request_origin, |
339 kPermissionBlacklistEmbargoKey); | 338 kPermissionBlacklistEmbargoKey); |
340 } | 339 } |
341 callback.Run(should_be_embargoed /* permission blocked */); | 340 callback.Run(should_be_embargoed /* permission blocked */); |
342 } | 341 } |
343 | 342 |
344 void PermissionDecisionAutoBlocker::PlaceUnderEmbargo( | 343 void PermissionDecisionAutoBlocker::PlaceUnderEmbargo( |
345 content::PermissionType permission, | 344 ContentSettingsType permission, |
346 const GURL& request_origin, | 345 const GURL& request_origin, |
347 const char* key) { | 346 const char* key) { |
348 HostContentSettingsMap* map = | 347 HostContentSettingsMap* map = |
349 HostContentSettingsMapFactory::GetForProfile(profile_); | 348 HostContentSettingsMapFactory::GetForProfile(profile_); |
350 std::unique_ptr<base::DictionaryValue> dict = | 349 std::unique_ptr<base::DictionaryValue> dict = |
351 GetOriginDict(map, request_origin); | 350 GetOriginDict(map, request_origin); |
352 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( | 351 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( |
353 dict.get(), PermissionUtil::GetPermissionString(permission)); | 352 dict.get(), PermissionUtil::GetPermissionString(permission)); |
354 permission_dict->SetDouble(key, clock_->Now().ToInternalValue()); | 353 permission_dict->SetDouble(key, clock_->Now().ToInternalValue()); |
355 map->SetWebsiteSettingDefaultScope( | 354 map->SetWebsiteSettingDefaultScope( |
356 request_origin, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, | 355 request_origin, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, |
357 std::string(), std::move(dict)); | 356 std::string(), std::move(dict)); |
358 } | 357 } |
359 | 358 |
360 void PermissionDecisionAutoBlocker:: | 359 void PermissionDecisionAutoBlocker:: |
361 SetSafeBrowsingDatabaseManagerAndTimeoutForTesting( | 360 SetSafeBrowsingDatabaseManagerAndTimeoutForTesting( |
362 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, | 361 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, |
363 int timeout) { | 362 int timeout) { |
364 db_manager_ = db_manager; | 363 db_manager_ = db_manager; |
365 safe_browsing_timeout_ = timeout; | 364 safe_browsing_timeout_ = timeout; |
366 } | 365 } |
367 | 366 |
368 void PermissionDecisionAutoBlocker::SetClockForTesting( | 367 void PermissionDecisionAutoBlocker::SetClockForTesting( |
369 std::unique_ptr<base::Clock> clock) { | 368 std::unique_ptr<base::Clock> clock) { |
370 clock_ = std::move(clock); | 369 clock_ = std::move(clock); |
371 } | 370 } |
OLD | NEW |