| 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 |