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