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

Side by Side Diff: chrome/browser/permissions/permission_decision_auto_blocker.cc

Issue 2640033006: Convert AutoBlocker static class to KeyedService. (Closed)
Patch Set: Add clock, move browsing data tests, 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/time/default_clock.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 16 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
16 #include "chrome/browser/permissions/permission_blacklist_client.h" 17 #include "chrome/browser/permissions/permission_blacklist_client.h"
17 #include "chrome/browser/permissions/permission_util.h" 18 #include "chrome/browser/permissions/permission_util.h"
18 #include "chrome/browser/permissions/permission_blacklist_client.h" 19 #include "chrome/browser/profiles/incognito_helpers.h"
19 #include "chrome/browser/permissions/permission_util.h" 20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
20 #include "chrome/common/chrome_features.h" 22 #include "chrome/common/chrome_features.h"
21 #include "components/content_settings/core/browser/host_content_settings_map.h" 23 #include "components/content_settings/core/browser/host_content_settings_map.h"
24 #include "components/keyed_service/content/browser_context_dependency_manager.h"
25 #include "components/safe_browsing_db/database_manager.h"
22 #include "components/variations/variations_associated_data.h" 26 #include "components/variations/variations_associated_data.h"
23 #include "content/public/browser/permission_type.h" 27 #include "content/public/browser/permission_type.h"
24 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
25 #include "url/gurl.h" 29 #include "url/gurl.h"
26 30
27 namespace { 31 namespace {
28 32
29 // The number of times that users may explicitly dismiss a permission prompt 33 // The number of times that users may explicitly dismiss a permission prompt
30 // from an origin before it is automatically blocked. 34 // from an origin before it is automatically blocked.
31 int g_prompt_dismissals_before_block = 3; 35 int g_prompt_dismissals_before_block = 3;
32 36
33 // The number of days that an origin will stay under embargo for a requested 37 // The number of days that an origin will stay under embargo for a requested
34 // permission due to blacklisting. 38 // permission due to blacklisting.
35 int g_blacklist_embargo_days = 7; 39 int g_blacklist_embargo_days = 7;
36 40
37 // The number of days that an origin will stay under embargo for a requested 41 // The number of days that an origin will stay under embargo for a requested
38 // permission due to repeated dismissals. 42 // permission due to repeated dismissals.
39 int g_dismissal_embargo_days = 7; 43 int g_dismissal_embargo_days = 7;
40 44
45 // TODO(meredithl): Migrate to a new and more fitting type, once metrics have
46 // been gathered, and deprecate CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT.
41 std::unique_ptr<base::DictionaryValue> GetOriginDict( 47 std::unique_ptr<base::DictionaryValue> GetOriginDict(
42 HostContentSettingsMap* settings, 48 HostContentSettingsMap* settings,
43 const GURL& origin_url) { 49 const GURL& origin_url) {
44 std::unique_ptr<base::DictionaryValue> dict = 50 std::unique_ptr<base::DictionaryValue> dict =
45 base::DictionaryValue::From(settings->GetWebsiteSetting( 51 base::DictionaryValue::From(settings->GetWebsiteSetting(
46 origin_url, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, 52 origin_url, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
47 std::string(), nullptr)); 53 std::string(), nullptr));
48 if (!dict) 54 if (!dict)
49 return base::MakeUnique<base::DictionaryValue>(); 55 return base::MakeUnique<base::DictionaryValue>();
50 56
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( 103 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
98 dict.get(), PermissionUtil::GetPermissionString(permission)); 104 dict.get(), PermissionUtil::GetPermissionString(permission));
99 105
100 int current_count = 0; 106 int current_count = 0;
101 permission_dict->GetInteger(key, &current_count); 107 permission_dict->GetInteger(key, &current_count);
102 return current_count; 108 return current_count;
103 } 109 }
104 110
105 } // namespace 111 } // namespace
106 112
113 // PermissionDecisionAutoBlocker -----------------------------------------------
114
107 // static 115 // static
108 const char PermissionDecisionAutoBlocker::kPromptDismissCountKey[] = 116 const char PermissionDecisionAutoBlocker::kPromptDismissCountKey[] =
109 "dismiss_count"; 117 "dismiss_count";
110 118
111 // static 119 // static
112 const char PermissionDecisionAutoBlocker::kPromptIgnoreCountKey[] = 120 const char PermissionDecisionAutoBlocker::kPromptIgnoreCountKey[] =
113 "ignore_count"; 121 "ignore_count";
114 122
115 // static 123 // static
116 const char PermissionDecisionAutoBlocker::kPermissionBlacklistEmbargoKey[] = 124 const char PermissionDecisionAutoBlocker::kPermissionBlacklistEmbargoKey[] =
117 "blacklisting_embargo_days"; 125 "blacklisting_embargo_days";
118 126
119 // static 127 // static
120 const char PermissionDecisionAutoBlocker::kPermissionDismissalEmbargoKey[] = 128 const char PermissionDecisionAutoBlocker::kPermissionDismissalEmbargoKey[] =
121 "dismissal_embargo_days"; 129 "dismissal_embargo_days";
122 130
123 // static 131 // Maximum time in milliseconds to wait for safe browsing service to check a
132 // url for blacklisting. After this amount of time, the check will be aborted
133 // and the url will be treated as not safe.
134 // TODO(meredithl): Revisit this once UMA metrics have data about request time.
135 const int kCheckUrlTimeoutMs = 2000;
136
137 PermissionDecisionAutoBlocker::PermissionDecisionAutoBlocker(Profile* profile)
138 : profile_(profile),
139 safe_browsing_timeout_(kCheckUrlTimeoutMs),
140 clock_(new base::DefaultClock()) {
141 if (!db_manager_) {
raymes 2017/01/24 03:31:08 The db_manager_ will always be null at the start,
meredithl 2017/01/24 04:52:25 Done. But that means I still need to add a null ch
142 safe_browsing::SafeBrowsingService* sb_service =
143 g_browser_process->safe_browsing_service();
144 if (sb_service)
145 db_manager_ = sb_service->database_manager();
146 }
147 }
148
149 PermissionDecisionAutoBlocker::~PermissionDecisionAutoBlocker() {}
150
151 PermissionDecisionAutoBlocker* PermissionDecisionAutoBlocker::GetForProfile(
raymes 2017/01/24 03:31:08 nit: // static
meredithl 2017/01/24 04:52:25 Done.
152 Profile* profile) {
153 return PermissionDecisionAutoBlocker::Factory::GetForProfile(profile);
154 }
155
124 void PermissionDecisionAutoBlocker::RemoveCountsByUrl( 156 void PermissionDecisionAutoBlocker::RemoveCountsByUrl(
125 Profile* profile,
126 base::Callback<bool(const GURL& url)> filter) { 157 base::Callback<bool(const GURL& url)> filter) {
127 HostContentSettingsMap* map = 158 HostContentSettingsMap* map =
128 HostContentSettingsMapFactory::GetForProfile(profile); 159 HostContentSettingsMapFactory::GetForProfile(profile_);
129 160
130 std::unique_ptr<ContentSettingsForOneType> settings( 161 std::unique_ptr<ContentSettingsForOneType> settings(
131 new ContentSettingsForOneType); 162 new ContentSettingsForOneType);
132 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, 163 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
133 std::string(), settings.get()); 164 std::string(), settings.get());
134 165
135 for (const auto& site : *settings) { 166 for (const auto& site : *settings) {
136 GURL origin(site.primary_pattern.ToString()); 167 GURL origin(site.primary_pattern.ToString());
137 168
138 if (origin.is_valid() && filter.Run(origin)) { 169 if (origin.is_valid() && filter.Run(origin)) {
139 map->SetWebsiteSettingDefaultScope( 170 map->SetWebsiteSettingDefaultScope(
140 origin, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, 171 origin, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
141 std::string(), nullptr); 172 std::string(), nullptr);
142 } 173 }
143 } 174 }
144 } 175 }
145 176
146 // static
147 int PermissionDecisionAutoBlocker::GetDismissCount( 177 int PermissionDecisionAutoBlocker::GetDismissCount(
148 const GURL& url, 178 const GURL& url,
149 content::PermissionType permission, 179 content::PermissionType permission) {
150 Profile* profile) { 180 return GetActionCount(url, permission, kPromptDismissCountKey, profile_);
151 return GetActionCount(url, permission, kPromptDismissCountKey, profile);
152 } 181 }
153 182
154 // static
155 int PermissionDecisionAutoBlocker::GetIgnoreCount( 183 int PermissionDecisionAutoBlocker::GetIgnoreCount(
156 const GURL& url, 184 const GURL& url,
157 content::PermissionType permission, 185 content::PermissionType permission) {
158 Profile* profile) { 186 return GetActionCount(url, permission, kPromptIgnoreCountKey, profile_);
159 return GetActionCount(url, permission, kPromptIgnoreCountKey, profile);
160 } 187 }
161 188
162 // static
163 bool PermissionDecisionAutoBlocker::RecordDismissAndEmbargo( 189 bool PermissionDecisionAutoBlocker::RecordDismissAndEmbargo(
164 const GURL& url, 190 const GURL& url,
165 content::PermissionType permission, 191 content::PermissionType permission) {
166 Profile* profile,
167 base::Time current_time) {
168 int current_dismissal_count = RecordActionInWebsiteSettings( 192 int current_dismissal_count = RecordActionInWebsiteSettings(
169 url, permission, kPromptDismissCountKey, profile); 193 url, permission, kPromptDismissCountKey, profile_);
194
170 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) && 195 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) &&
171 current_dismissal_count >= g_prompt_dismissals_before_block) { 196 current_dismissal_count >= g_prompt_dismissals_before_block) {
172 HostContentSettingsMap* map = 197 PlaceUnderEmbargo(permission, url,
173 HostContentSettingsMapFactory::GetForProfile(profile); 198 HostContentSettingsMapFactory::GetForProfile(profile_),
174 PlaceUnderEmbargo(permission, url, map, current_time, 199 clock_->Now(), kPermissionDismissalEmbargoKey);
175 kPermissionDismissalEmbargoKey);
176 return true; 200 return true;
177 } 201 }
178 return false; 202 return false;
179 } 203 }
180 204
181 // static
182 int PermissionDecisionAutoBlocker::RecordIgnore( 205 int PermissionDecisionAutoBlocker::RecordIgnore(
183 const GURL& url, 206 const GURL& url,
184 content::PermissionType permission, 207 content::PermissionType permission) {
185 Profile* profile) {
186 return RecordActionInWebsiteSettings(url, permission, kPromptIgnoreCountKey, 208 return RecordActionInWebsiteSettings(url, permission, kPromptIgnoreCountKey,
187 profile); 209 profile_);
188 } 210 }
189 211
190 // static 212 // static
191 bool PermissionDecisionAutoBlocker::ShouldChangeDismissalToBlock(
192 const GURL& url,
193 content::PermissionType permission,
194 Profile* profile) {
195 int current_dismissal_count =
196 RecordDismissAndEmbargo(url, permission, profile, base::Time::Now());
197
198 if (!base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften))
199 return false;
200
201 return current_dismissal_count >= g_prompt_dismissals_before_block;
202 }
203
204 // static
205 void PermissionDecisionAutoBlocker::UpdateFromVariations() { 213 void PermissionDecisionAutoBlocker::UpdateFromVariations() {
206 int prompt_dismissals = -1; 214 int prompt_dismissals = -1;
207 int blacklist_embargo_days = -1; 215 int blacklist_embargo_days = -1;
208 int dismissal_embargo_days = -1; 216 int dismissal_embargo_days = -1;
209 std::string dismissals_value = variations::GetVariationParamValueByFeature( 217 std::string dismissals_value = variations::GetVariationParamValueByFeature(
210 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey); 218 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey);
211 std::string blacklist_embargo_value = 219 std::string blacklist_embargo_value =
212 variations::GetVariationParamValueByFeature( 220 variations::GetVariationParamValueByFeature(
213 features::kPermissionsBlacklist, kPermissionBlacklistEmbargoKey); 221 features::kPermissionsBlacklist, kPermissionBlacklistEmbargoKey);
214 std::string dismissal_embargo_value = 222 std::string dismissal_embargo_value =
215 variations::GetVariationParamValueByFeature( 223 variations::GetVariationParamValueByFeature(
216 features::kBlockPromptsIfDismissedOften, 224 features::kBlockPromptsIfDismissedOften,
217 kPermissionDismissalEmbargoKey); 225 kPermissionDismissalEmbargoKey);
218 // If converting the value fails, stick with the current value. 226 // If converting the value fails, stick with the current value.
219 if (base::StringToInt(dismissals_value, &prompt_dismissals) && 227 if (base::StringToInt(dismissals_value, &prompt_dismissals) &&
220 prompt_dismissals > 0) { 228 prompt_dismissals > 0) {
221 g_prompt_dismissals_before_block = prompt_dismissals; 229 g_prompt_dismissals_before_block = prompt_dismissals;
222 } 230 }
223 if (base::StringToInt(blacklist_embargo_value, &blacklist_embargo_days) && 231 if (base::StringToInt(blacklist_embargo_value, &blacklist_embargo_days) &&
224 blacklist_embargo_days > 0) { 232 blacklist_embargo_days > 0) {
225 g_blacklist_embargo_days = blacklist_embargo_days; 233 g_blacklist_embargo_days = blacklist_embargo_days;
226 } 234 }
227 if (base::StringToInt(dismissal_embargo_value, &dismissal_embargo_days) && 235 if (base::StringToInt(dismissal_embargo_value, &dismissal_embargo_days) &&
228 dismissal_embargo_days > 0) { 236 dismissal_embargo_days > 0) {
229 g_dismissal_embargo_days = dismissal_embargo_days; 237 g_dismissal_embargo_days = dismissal_embargo_days;
230 } 238 }
231 } 239 }
232 240
233 // static
234 // TODO(meredithl): Have PermissionDecisionAutoBlocker handle the database
235 // manager, rather than passing it in.
236 void PermissionDecisionAutoBlocker::UpdateEmbargoedStatus( 241 void PermissionDecisionAutoBlocker::UpdateEmbargoedStatus(
237 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
238 content::PermissionType permission, 242 content::PermissionType permission,
239 const GURL& request_origin, 243 const GURL& request_origin,
240 content::WebContents* web_contents, 244 content::WebContents* web_contents,
241 int timeout,
242 Profile* profile,
243 base::Time current_time,
244 base::Callback<void(bool)> callback) { 245 base::Callback<void(bool)> callback) {
245 // Check if origin is currently under embargo for the requested permission. 246 // Check if origin is currently under embargo for the requested permission.
246 if (IsUnderEmbargo(permission, profile, request_origin, current_time)) { 247 if (IsUnderEmbargo(permission, request_origin)) {
247 callback.Run(true /* permission_blocked */); 248 callback.Run(true /* permission_blocked */);
248 return; 249 return;
249 } 250 }
250 251
251 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && 252 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) &&
252 db_manager) { 253 db_manager_) {
253 PermissionBlacklistClient::CheckSafeBrowsingBlacklist( 254 PermissionBlacklistClient::CheckSafeBrowsingBlacklist(
raymes 2017/01/24 03:31:08 nit: I discussed about lifetimes with Dom. Could y
meredithl 2017/01/24 04:52:25 Done.
254 db_manager, permission, request_origin, web_contents, timeout, 255 db_manager_, permission, request_origin, web_contents,
256 safe_browsing_timeout_,
255 base::Bind(&PermissionDecisionAutoBlocker::CheckSafeBrowsingResult, 257 base::Bind(&PermissionDecisionAutoBlocker::CheckSafeBrowsingResult,
256 permission, profile, request_origin, current_time, 258 permission, profile_, request_origin, clock_->Now(),
257 callback)); 259 callback));
258 return; 260 return;
259 } 261 }
260 262
261 callback.Run(false /* permission blocked */); 263 callback.Run(false /* permission blocked */);
262 } 264 }
263 265
264 // static
265 bool PermissionDecisionAutoBlocker::IsUnderEmbargo( 266 bool PermissionDecisionAutoBlocker::IsUnderEmbargo(
266 content::PermissionType permission, 267 content::PermissionType permission,
267 Profile* profile, 268 const GURL& request_origin) {
268 const GURL& request_origin,
269 base::Time current_time) {
270 HostContentSettingsMap* map = 269 HostContentSettingsMap* map =
271 HostContentSettingsMapFactory::GetForProfile(profile); 270 HostContentSettingsMapFactory::GetForProfile(profile_);
272 std::unique_ptr<base::DictionaryValue> dict = 271 std::unique_ptr<base::DictionaryValue> dict =
273 GetOriginDict(map, request_origin); 272 GetOriginDict(map, request_origin);
274 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( 273 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
275 dict.get(), PermissionUtil::GetPermissionString(permission)); 274 dict.get(), PermissionUtil::GetPermissionString(permission));
276 double embargo_date = -1; 275 double embargo_date = -1;
277 bool is_under_dismiss_embargo = false; 276 bool is_under_dismiss_embargo = false;
278 bool is_under_blacklist_embargo = false; 277 bool is_under_blacklist_embargo = false;
278 base::Time current_time = clock_->Now();
279 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && 279 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) &&
280 permission_dict->GetDouble(kPermissionBlacklistEmbargoKey, 280 permission_dict->GetDouble(kPermissionBlacklistEmbargoKey,
281 &embargo_date)) { 281 &embargo_date)) {
282 if (current_time < 282 if (current_time <
283 base::Time::FromInternalValue(embargo_date) + 283 base::Time::FromInternalValue(embargo_date) +
284 base::TimeDelta::FromDays(g_blacklist_embargo_days)) { 284 base::TimeDelta::FromDays(g_blacklist_embargo_days)) {
285 is_under_blacklist_embargo = true; 285 is_under_blacklist_embargo = true;
286 } 286 }
287 } 287 }
288 288
289 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) && 289 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) &&
290 permission_dict->GetDouble(kPermissionDismissalEmbargoKey, 290 permission_dict->GetDouble(kPermissionDismissalEmbargoKey,
291 &embargo_date)) { 291 &embargo_date)) {
292 if (current_time < 292 if (current_time <
293 base::Time::FromInternalValue(embargo_date) + 293 base::Time::FromInternalValue(embargo_date) +
294 base::TimeDelta::FromDays(g_dismissal_embargo_days)) { 294 base::TimeDelta::FromDays(g_dismissal_embargo_days)) {
295 is_under_dismiss_embargo = true; 295 is_under_dismiss_embargo = true;
296 } 296 }
297 } 297 }
298 // If either embargoes is still in effect, return true. 298
299 // If either embargo is still in effect, return true.
299 return is_under_dismiss_embargo || is_under_blacklist_embargo; 300 return is_under_dismiss_embargo || is_under_blacklist_embargo;
300 } 301 }
301 302
302 void PermissionDecisionAutoBlocker::PlaceUnderEmbargo(
303 content::PermissionType permission,
304 const GURL& request_origin,
305 HostContentSettingsMap* map,
306 base::Time current_time,
307 const char* key) {
308 std::unique_ptr<base::DictionaryValue> dict =
309 GetOriginDict(map, request_origin);
310 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
311 dict.get(), PermissionUtil::GetPermissionString(permission));
312 permission_dict->SetDouble(key, current_time.ToInternalValue());
313 map->SetWebsiteSettingDefaultScope(
314 request_origin, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
315 std::string(), std::move(dict));
316 }
317
318 // static 303 // static
319 void PermissionDecisionAutoBlocker::CheckSafeBrowsingResult( 304 void PermissionDecisionAutoBlocker::CheckSafeBrowsingResult(
320 content::PermissionType permission, 305 content::PermissionType permission,
321 Profile* profile, 306 Profile* profile,
322 const GURL& request_origin, 307 const GURL& request_origin,
323 base::Time current_time, 308 base::Time current_time,
324 base::Callback<void(bool)> callback, 309 base::Callback<void(bool)> callback,
325 bool should_be_embargoed) { 310 bool should_be_embargoed) {
326 if (should_be_embargoed) { 311 if (should_be_embargoed) {
327 // Requesting site is blacklisted for this permission, update the content 312 // Requesting site is blacklisted for this permission, update the content
328 // setting to place it under embargo. 313 // setting to place it under embargo.
329 PlaceUnderEmbargo(permission, request_origin, 314 PlaceUnderEmbargo(permission, request_origin,
330 HostContentSettingsMapFactory::GetForProfile(profile), 315 HostContentSettingsMapFactory::GetForProfile(profile),
331 current_time, kPermissionBlacklistEmbargoKey); 316 current_time, kPermissionBlacklistEmbargoKey);
332 } 317 }
333 callback.Run(should_be_embargoed /* permission blocked */); 318 callback.Run(should_be_embargoed /* permission blocked */);
334 } 319 }
335 320
336 // static 321 // static
337 // TODO(meredithl): Have PermissionDecisionAutoBlocker handle the database
338 // manager, rather than passing it in.
339 void PermissionDecisionAutoBlocker::UpdateEmbargoedStatus(
340 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
341 content::PermissionType permission,
342 const GURL& request_origin,
343 content::WebContents* web_contents,
344 int timeout,
345 Profile* profile,
346 base::Time current_time,
347 base::Callback<void(bool)> callback) {
348 // Check if origin is currently under embargo for the requested permission.
349 if (IsUnderEmbargo(permission, profile, request_origin, current_time)) {
350 callback.Run(true /* permission_blocked */);
351 return;
352 }
353
354 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) &&
355 db_manager) {
356 PermissionBlacklistClient::CheckSafeBrowsingBlacklist(
357 db_manager, permission, request_origin, web_contents, timeout,
358 base::Bind(&PermissionDecisionAutoBlocker::CheckSafeBrowsingResult,
359 permission, profile, request_origin, current_time,
360 callback));
361 }
362
363 callback.Run(false /* permission blocked */);
364 }
365
366 // static
367 bool PermissionDecisionAutoBlocker::IsUnderEmbargo(
368 content::PermissionType permission,
369 Profile* profile,
370 const GURL& request_origin,
371 base::Time current_time) {
372 HostContentSettingsMap* map =
373 HostContentSettingsMapFactory::GetForProfile(profile);
374 std::unique_ptr<base::DictionaryValue> dict =
375 GetOriginDict(map, request_origin);
376 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
377 dict.get(), PermissionUtil::GetPermissionString(permission));
378 double embargo_date = -1;
379 bool is_under_dismiss_embargo = false;
380 bool is_under_blacklist_embargo = false;
381 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) &&
382 permission_dict->GetDouble(kPermissionBlacklistEmbargoKey,
383 &embargo_date)) {
384 if (current_time <
385 base::Time::FromInternalValue(embargo_date) +
386 base::TimeDelta::FromDays(g_blacklist_embargo_days)) {
387 is_under_blacklist_embargo = true;
388 }
389 }
390
391 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) &&
392 permission_dict->GetDouble(kPermissionDismissalEmbargoKey,
393 &embargo_date)) {
394 if (current_time <
395 base::Time::FromInternalValue(embargo_date) +
396 base::TimeDelta::FromDays(g_dismissal_embargo_days)) {
397 is_under_dismiss_embargo = true;
398 }
399 }
400 // If either embargoes is still in effect, return true.
401 return is_under_dismiss_embargo || is_under_blacklist_embargo;
402 }
403
404 void PermissionDecisionAutoBlocker::PlaceUnderEmbargo( 322 void PermissionDecisionAutoBlocker::PlaceUnderEmbargo(
405 content::PermissionType permission, 323 content::PermissionType permission,
406 const GURL& request_origin, 324 const GURL& request_origin,
407 HostContentSettingsMap* map, 325 HostContentSettingsMap* map,
408 base::Time current_time, 326 base::Time current_time,
409 const char* key) { 327 const char* key) {
410 std::unique_ptr<base::DictionaryValue> dict = 328 std::unique_ptr<base::DictionaryValue> dict =
411 GetOriginDict(map, request_origin); 329 GetOriginDict(map, request_origin);
412 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( 330 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
413 dict.get(), PermissionUtil::GetPermissionString(permission)); 331 dict.get(), PermissionUtil::GetPermissionString(permission));
414 permission_dict->SetDouble(key, current_time.ToInternalValue()); 332 permission_dict->SetDouble(key, current_time.ToInternalValue());
415 map->SetWebsiteSettingDefaultScope( 333 map->SetWebsiteSettingDefaultScope(
416 request_origin, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, 334 request_origin, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
417 std::string(), std::move(dict)); 335 std::string(), std::move(dict));
418 } 336 }
419 337
338 void PermissionDecisionAutoBlocker::
339 SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(
340 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
341 int timeout) {
342 db_manager_ = db_manager;
343 safe_browsing_timeout_ = timeout;
344 }
345
346 void PermissionDecisionAutoBlocker::SetClockForTesting(
347 std::unique_ptr<base::Clock> clock) {
348 clock_ = std::move(clock);
349 }
350
351 // PermissionDecisionAutoBlocker::Factory --------------------------------------
raymes 2017/01/24 03:31:08 nit: this section should probably move to the top
meredithl 2017/01/24 04:52:25 Done.
352
420 // static 353 // static
421 void PermissionDecisionAutoBlocker::CheckSafeBrowsingResult( 354 PermissionDecisionAutoBlocker*
422 content::PermissionType permission, 355 PermissionDecisionAutoBlocker::Factory::GetForProfile(Profile* profile) {
423 Profile* profile, 356 return static_cast<PermissionDecisionAutoBlocker*>(
424 const GURL& request_origin, 357 GetInstance()->GetServiceForBrowserContext(profile, true));
425 base::Time current_time,
426 base::Callback<void(bool)> callback,
427 bool should_be_embargoed) {
428 if (should_be_embargoed) {
429 // Requesting site is blacklisted for this permission, update the content
430 // setting to place it under embargo.
431 PlaceUnderEmbargo(permission, request_origin,
432 HostContentSettingsMapFactory::GetForProfile(profile),
433 current_time, kPermissionBlacklistEmbargoKey);
434 }
435 callback.Run(should_be_embargoed /* permission blocked */);
436 } 358 }
359
360 // static
361 PermissionDecisionAutoBlocker::Factory*
362 PermissionDecisionAutoBlocker::Factory::GetInstance() {
363 return base::Singleton<PermissionDecisionAutoBlocker::Factory>::get();
364 }
365
366 PermissionDecisionAutoBlocker::Factory::Factory()
367 : BrowserContextKeyedServiceFactory(
368 "PermissionDecisionAutoBlocker",
369 BrowserContextDependencyManager::GetInstance()) {}
370
371 PermissionDecisionAutoBlocker::Factory::~Factory() {}
372
373 KeyedService* PermissionDecisionAutoBlocker::Factory::BuildServiceInstanceFor(
374 content::BrowserContext* context) const {
375 Profile* profile = static_cast<Profile*>(context);
376 return new PermissionDecisionAutoBlocker(profile);
377 }
378
379 content::BrowserContext*
380 PermissionDecisionAutoBlocker::Factory::GetBrowserContextToUse(
381 content::BrowserContext* context) const {
382 return chrome::GetBrowserContextOwnInstanceInIncognito(context);
383 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698