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" |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include "components/variations/variations_associated_data.h" | 24 #include "components/variations/variations_associated_data.h" |
25 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
26 #include "url/gurl.h" | 26 #include "url/gurl.h" |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 // 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 |
31 // from an origin before it is automatically blocked. | 31 // from an origin before it is automatically blocked. |
32 int g_prompt_dismissals_before_block = 3; | 32 int g_prompt_dismissals_before_block = 3; |
33 | 33 |
34 // The number of times that users may ignore a permission prompt from an origin | |
35 // before it is automatically blocked. | |
36 int g_prompt_ignores_before_block = 4; | |
37 | |
38 // The number of days that an origin will stay under embargo for a requested | |
39 // permission due to repeated dismissals. | |
40 int g_dismissal_embargo_days = 7; | |
41 | |
42 // The number of days that an origin will stay under embargo for a requested | |
43 // permission due to repeated ignores. | |
44 int g_ignore_embargo_days = 7; | |
45 | |
34 // The number of days that an origin will stay under embargo for a requested | 46 // The number of days that an origin will stay under embargo for a requested |
35 // permission due to blacklisting. | 47 // permission due to blacklisting. |
36 int g_blacklist_embargo_days = 7; | 48 int g_blacklist_embargo_days = 7; |
37 | 49 |
38 // The number of days that an origin will stay under embargo for a requested | |
39 // permission due to repeated dismissals. | |
40 int g_dismissal_embargo_days = 7; | |
41 | |
42 // Maximum time in milliseconds to wait for safe browsing service to check a | 50 // Maximum time in milliseconds to wait for safe browsing service to check a |
43 // url for blacklisting. After this amount of time, the check will be aborted | 51 // url for blacklisting. After this amount of time, the check will be aborted |
44 // and the url will be treated as not safe. | 52 // and the url will be treated as not safe. |
45 // TODO(meredithl): Revisit this once UMA metrics have data about request time. | 53 // TODO(meredithl): Revisit this once UMA metrics have data about request time. |
46 const int kCheckUrlTimeoutMs = 2000; | 54 const int kCheckUrlTimeoutMs = 2000; |
47 | 55 |
48 std::unique_ptr<base::DictionaryValue> GetOriginDict( | 56 std::unique_ptr<base::DictionaryValue> GetOriginDict( |
49 HostContentSettingsMap* settings, | 57 HostContentSettingsMap* settings, |
50 const GURL& origin_url) { | 58 const GURL& origin_url) { |
51 std::unique_ptr<base::DictionaryValue> dict = | 59 std::unique_ptr<base::DictionaryValue> dict = |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 HostContentSettingsMapFactory::GetForProfile(profile); | 110 HostContentSettingsMapFactory::GetForProfile(profile); |
103 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); | 111 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); |
104 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( | 112 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( |
105 dict.get(), PermissionUtil::GetPermissionString(permission)); | 113 dict.get(), PermissionUtil::GetPermissionString(permission)); |
106 | 114 |
107 int current_count = 0; | 115 int current_count = 0; |
108 permission_dict->GetInteger(key, ¤t_count); | 116 permission_dict->GetInteger(key, ¤t_count); |
109 return current_count; | 117 return current_count; |
110 } | 118 } |
111 | 119 |
120 bool IsUnderEmbargo(base::DictionaryValue* permission_dict, | |
121 const base::Feature& feature, | |
122 const char* key, | |
123 base::Time current_time, | |
124 base::TimeDelta offset) { | |
125 double embargo_date = -1; | |
126 | |
127 if (base::FeatureList::IsEnabled(feature) && | |
128 permission_dict->GetDouble(key, &embargo_date)) { | |
129 if (current_time < base::Time::FromInternalValue(embargo_date) + offset) | |
130 return true; | |
131 } | |
132 | |
133 return false; | |
134 } | |
135 | |
112 } // namespace | 136 } // namespace |
113 | 137 |
114 // PermissionDecisionAutoBlocker::Factory -------------------------------------- | 138 // PermissionDecisionAutoBlocker::Factory -------------------------------------- |
115 | 139 |
116 // static | 140 // static |
117 PermissionDecisionAutoBlocker* | 141 PermissionDecisionAutoBlocker* |
118 PermissionDecisionAutoBlocker::Factory::GetForProfile(Profile* profile) { | 142 PermissionDecisionAutoBlocker::Factory::GetForProfile(Profile* profile) { |
119 return static_cast<PermissionDecisionAutoBlocker*>( | 143 return static_cast<PermissionDecisionAutoBlocker*>( |
120 GetInstance()->GetServiceForBrowserContext(profile, true)); | 144 GetInstance()->GetServiceForBrowserContext(profile, true)); |
121 } | 145 } |
(...skipping 27 matching lines...) Expand all Loading... | |
149 | 173 |
150 // static | 174 // static |
151 const char PermissionDecisionAutoBlocker::kPromptDismissCountKey[] = | 175 const char PermissionDecisionAutoBlocker::kPromptDismissCountKey[] = |
152 "dismiss_count"; | 176 "dismiss_count"; |
153 | 177 |
154 // static | 178 // static |
155 const char PermissionDecisionAutoBlocker::kPromptIgnoreCountKey[] = | 179 const char PermissionDecisionAutoBlocker::kPromptIgnoreCountKey[] = |
156 "ignore_count"; | 180 "ignore_count"; |
157 | 181 |
158 // static | 182 // static |
183 const char PermissionDecisionAutoBlocker::kPermissionDismissalEmbargoKey[] = | |
184 "dismissal_embargo_days"; | |
185 | |
186 // static | |
187 const char PermissionDecisionAutoBlocker::kPermissionIgnoreEmbargoKey[] = | |
188 "ignore_embargo_days"; | |
189 | |
190 // static | |
159 const char PermissionDecisionAutoBlocker::kPermissionBlacklistEmbargoKey[] = | 191 const char PermissionDecisionAutoBlocker::kPermissionBlacklistEmbargoKey[] = |
160 "blacklisting_embargo_days"; | 192 "blacklisting_embargo_days"; |
161 | 193 |
162 // static | 194 // static |
163 const char PermissionDecisionAutoBlocker::kPermissionDismissalEmbargoKey[] = | |
164 "dismissal_embargo_days"; | |
165 | |
166 // static | |
167 PermissionDecisionAutoBlocker* PermissionDecisionAutoBlocker::GetForProfile( | 195 PermissionDecisionAutoBlocker* PermissionDecisionAutoBlocker::GetForProfile( |
168 Profile* profile) { | 196 Profile* profile) { |
169 return PermissionDecisionAutoBlocker::Factory::GetForProfile(profile); | 197 return PermissionDecisionAutoBlocker::Factory::GetForProfile(profile); |
170 } | 198 } |
171 | 199 |
172 // static | 200 // static |
173 void PermissionDecisionAutoBlocker::UpdateFromVariations() { | 201 void PermissionDecisionAutoBlocker::UpdateFromVariations() { |
174 int prompt_dismissals = -1; | 202 int prompt_dismissals = -1; |
203 int prompt_ignores = -1; | |
204 int dismissal_embargo_days = -1; | |
205 int ignore_embargo_days = -1; | |
175 int blacklist_embargo_days = -1; | 206 int blacklist_embargo_days = -1; |
176 int dismissal_embargo_days = -1; | 207 |
177 std::string dismissals_value = variations::GetVariationParamValueByFeature( | 208 std::string dismissals_value = variations::GetVariationParamValueByFeature( |
178 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey); | 209 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey); |
179 std::string blacklist_embargo_value = | 210 std::string ignores_value = variations::GetVariationParamValueByFeature( |
180 variations::GetVariationParamValueByFeature( | 211 features::kBlockPromptsIfIgnoredOften, kPromptIgnoreCountKey); |
181 features::kPermissionsBlacklist, kPermissionBlacklistEmbargoKey); | |
182 std::string dismissal_embargo_value = | 212 std::string dismissal_embargo_value = |
183 variations::GetVariationParamValueByFeature( | 213 variations::GetVariationParamValueByFeature( |
184 features::kBlockPromptsIfDismissedOften, | 214 features::kBlockPromptsIfDismissedOften, |
185 kPermissionDismissalEmbargoKey); | 215 kPermissionDismissalEmbargoKey); |
216 std::string ignore_embargo_value = | |
217 variations::GetVariationParamValueByFeature( | |
218 features::kBlockPromptsIfIgnoredOften, kPermissionIgnoreEmbargoKey); | |
219 std::string blacklist_embargo_value = | |
220 variations::GetVariationParamValueByFeature( | |
221 features::kPermissionsBlacklist, kPermissionBlacklistEmbargoKey); | |
222 | |
186 // If converting the value fails, stick with the current value. | 223 // If converting the value fails, stick with the current value. |
187 if (base::StringToInt(dismissals_value, &prompt_dismissals) && | 224 if (base::StringToInt(dismissals_value, &prompt_dismissals) && |
188 prompt_dismissals > 0) { | 225 prompt_dismissals > 0) { |
189 g_prompt_dismissals_before_block = prompt_dismissals; | 226 g_prompt_dismissals_before_block = prompt_dismissals; |
190 } | 227 } |
191 if (base::StringToInt(blacklist_embargo_value, &blacklist_embargo_days) && | 228 if (base::StringToInt(ignores_value, &prompt_ignores) && prompt_ignores > 0) { |
192 blacklist_embargo_days > 0) { | 229 g_prompt_ignores_before_block = prompt_ignores; |
193 g_blacklist_embargo_days = blacklist_embargo_days; | |
194 } | 230 } |
195 if (base::StringToInt(dismissal_embargo_value, &dismissal_embargo_days) && | 231 if (base::StringToInt(dismissal_embargo_value, &dismissal_embargo_days) && |
196 dismissal_embargo_days > 0) { | 232 dismissal_embargo_days > 0) { |
197 g_dismissal_embargo_days = dismissal_embargo_days; | 233 g_dismissal_embargo_days = dismissal_embargo_days; |
198 } | 234 } |
235 if (base::StringToInt(ignore_embargo_value, &ignore_embargo_days) && | |
benwells
2017/03/31 04:47:14
These variables are all confusingly named. For g_f
dominickn
2017/04/02 23:45:57
Done.
| |
236 ignore_embargo_days > 0) { | |
237 g_ignore_embargo_days = ignore_embargo_days; | |
238 } | |
239 if (base::StringToInt(blacklist_embargo_value, &blacklist_embargo_days) && | |
240 blacklist_embargo_days > 0) { | |
241 g_blacklist_embargo_days = blacklist_embargo_days; | |
242 } | |
199 } | 243 } |
200 | 244 |
201 void PermissionDecisionAutoBlocker::CheckSafeBrowsingBlacklist( | 245 void PermissionDecisionAutoBlocker::CheckSafeBrowsingBlacklist( |
202 content::WebContents* web_contents, | 246 content::WebContents* web_contents, |
203 const GURL& request_origin, | 247 const GURL& request_origin, |
204 ContentSettingsType permission, | 248 ContentSettingsType permission, |
205 base::Callback<void(bool)> callback) { | 249 base::Callback<void(bool)> callback) { |
206 DCHECK_EQ(CONTENT_SETTING_ASK, | 250 DCHECK_EQ(CONTENT_SETTING_ASK, |
207 GetEmbargoResult(request_origin, permission).content_setting); | 251 GetEmbargoResult(request_origin, permission).content_setting); |
208 | 252 |
(...skipping 16 matching lines...) Expand all Loading... | |
225 | 269 |
226 PermissionResult PermissionDecisionAutoBlocker::GetEmbargoResult( | 270 PermissionResult PermissionDecisionAutoBlocker::GetEmbargoResult( |
227 const GURL& request_origin, | 271 const GURL& request_origin, |
228 ContentSettingsType permission) { | 272 ContentSettingsType permission) { |
229 HostContentSettingsMap* map = | 273 HostContentSettingsMap* map = |
230 HostContentSettingsMapFactory::GetForProfile(profile_); | 274 HostContentSettingsMapFactory::GetForProfile(profile_); |
231 std::unique_ptr<base::DictionaryValue> dict = | 275 std::unique_ptr<base::DictionaryValue> dict = |
232 GetOriginDict(map, request_origin); | 276 GetOriginDict(map, request_origin); |
233 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( | 277 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( |
234 dict.get(), PermissionUtil::GetPermissionString(permission)); | 278 dict.get(), PermissionUtil::GetPermissionString(permission)); |
235 double embargo_date = -1; | |
236 | 279 |
237 base::Time current_time = clock_->Now(); | 280 base::Time current_time = clock_->Now(); |
238 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && | 281 if (IsUnderEmbargo(permission_dict, features::kPermissionsBlacklist, |
benwells
2017/03/31 04:47:14
Nice factoring :)
dominickn
2017/04/02 23:45:57
:)
| |
239 permission_dict->GetDouble(kPermissionBlacklistEmbargoKey, | 282 kPermissionBlacklistEmbargoKey, current_time, |
240 &embargo_date)) { | 283 base::TimeDelta::FromDays(g_blacklist_embargo_days))) { |
241 if (current_time < | 284 return PermissionResult(CONTENT_SETTING_BLOCK, |
242 base::Time::FromInternalValue(embargo_date) + | 285 PermissionStatusSource::SAFE_BROWSING_BLACKLIST); |
243 base::TimeDelta::FromDays(g_blacklist_embargo_days)) { | |
244 return PermissionResult(CONTENT_SETTING_BLOCK, | |
245 PermissionStatusSource::SAFE_BROWSING_BLACKLIST); | |
246 } | |
247 } | 286 } |
248 | 287 |
249 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) && | 288 if (IsUnderEmbargo(permission_dict, features::kBlockPromptsIfDismissedOften, |
250 permission_dict->GetDouble(kPermissionDismissalEmbargoKey, | 289 kPermissionDismissalEmbargoKey, current_time, |
251 &embargo_date)) { | 290 base::TimeDelta::FromDays(g_dismissal_embargo_days))) { |
252 if (current_time < | 291 return PermissionResult(CONTENT_SETTING_BLOCK, |
253 base::Time::FromInternalValue(embargo_date) + | 292 PermissionStatusSource::MULTIPLE_DISMISSALS); |
254 base::TimeDelta::FromDays(g_dismissal_embargo_days)) { | 293 } |
255 return PermissionResult(CONTENT_SETTING_BLOCK, | 294 |
256 PermissionStatusSource::MULTIPLE_DISMISSALS); | 295 if (IsUnderEmbargo(permission_dict, features::kBlockPromptsIfIgnoredOften, |
257 } | 296 kPermissionIgnoreEmbargoKey, current_time, |
297 base::TimeDelta::FromDays(g_ignore_embargo_days))) { | |
298 return PermissionResult(CONTENT_SETTING_BLOCK, | |
299 PermissionStatusSource::MULTIPLE_IGNORES); | |
258 } | 300 } |
259 | 301 |
260 return PermissionResult(CONTENT_SETTING_ASK, | 302 return PermissionResult(CONTENT_SETTING_ASK, |
261 PermissionStatusSource::UNSPECIFIED); | 303 PermissionStatusSource::UNSPECIFIED); |
262 } | 304 } |
263 | 305 |
264 int PermissionDecisionAutoBlocker::GetDismissCount( | 306 int PermissionDecisionAutoBlocker::GetDismissCount( |
265 const GURL& url, | 307 const GURL& url, |
266 ContentSettingsType permission) { | 308 ContentSettingsType permission) { |
267 return GetActionCount(url, permission, kPromptDismissCountKey, profile_); | 309 return GetActionCount(url, permission, kPromptDismissCountKey, profile_); |
(...skipping 12 matching lines...) Expand all Loading... | |
280 url, permission, kPromptDismissCountKey, profile_); | 322 url, permission, kPromptDismissCountKey, profile_); |
281 | 323 |
282 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) && | 324 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) && |
283 current_dismissal_count >= g_prompt_dismissals_before_block) { | 325 current_dismissal_count >= g_prompt_dismissals_before_block) { |
284 PlaceUnderEmbargo(url, permission, kPermissionDismissalEmbargoKey); | 326 PlaceUnderEmbargo(url, permission, kPermissionDismissalEmbargoKey); |
285 return true; | 327 return true; |
286 } | 328 } |
287 return false; | 329 return false; |
288 } | 330 } |
289 | 331 |
290 int PermissionDecisionAutoBlocker::RecordIgnore( | 332 bool PermissionDecisionAutoBlocker::RecordIgnoreAndEmbargo( |
291 const GURL& url, | 333 const GURL& url, |
292 ContentSettingsType permission) { | 334 ContentSettingsType permission) { |
293 return RecordActionInWebsiteSettings(url, permission, kPromptIgnoreCountKey, | 335 int current_ignore_count = RecordActionInWebsiteSettings( |
294 profile_); | 336 url, permission, kPromptIgnoreCountKey, profile_); |
337 | |
338 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfIgnoredOften) && | |
339 current_ignore_count >= g_prompt_ignores_before_block) { | |
340 PlaceUnderEmbargo(url, permission, kPermissionIgnoreEmbargoKey); | |
341 return true; | |
342 } | |
343 return false; | |
295 } | 344 } |
296 | 345 |
297 void PermissionDecisionAutoBlocker::RemoveCountsByUrl( | 346 void PermissionDecisionAutoBlocker::RemoveCountsByUrl( |
298 base::Callback<bool(const GURL& url)> filter) { | 347 base::Callback<bool(const GURL& url)> filter) { |
299 HostContentSettingsMap* map = | 348 HostContentSettingsMap* map = |
300 HostContentSettingsMapFactory::GetForProfile(profile_); | 349 HostContentSettingsMapFactory::GetForProfile(profile_); |
301 | 350 |
302 std::unique_ptr<ContentSettingsForOneType> settings( | 351 std::unique_ptr<ContentSettingsForOneType> settings( |
303 new ContentSettingsForOneType); | 352 new ContentSettingsForOneType); |
304 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, | 353 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, | 412 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, |
364 int timeout) { | 413 int timeout) { |
365 db_manager_ = db_manager; | 414 db_manager_ = db_manager; |
366 safe_browsing_timeout_ = timeout; | 415 safe_browsing_timeout_ = timeout; |
367 } | 416 } |
368 | 417 |
369 void PermissionDecisionAutoBlocker::SetClockForTesting( | 418 void PermissionDecisionAutoBlocker::SetClockForTesting( |
370 std::unique_ptr<base::Clock> clock) { | 419 std::unique_ptr<base::Clock> clock) { |
371 clock_ = std::move(clock); | 420 clock_ = std::move(clock); |
372 } | 421 } |
OLD | NEW |