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

Side by Side Diff: chrome/browser/policy/url_blacklist_manager.cc

Issue 110643005: Refactored the URLBlacklistManager to avoid chrome/ and content/ dependencies. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/policy/url_blacklist_manager.h" 5 #include "chrome/browser/policy/url_blacklist_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/location.h"
10 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
11 #include "base/stl_util.h" 12 #include "base/stl_util.h"
12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/threading/worker_pool.h"
13 #include "base/values.h" 15 #include "base/values.h"
14 #include "chrome/browser/chrome_notification_types.h" 16 #include "components/policy/core/common/policy_pref_names.h"
15 #include "chrome/common/net/url_fixer_upper.h"
16 #include "chrome/common/pref_names.h"
17 #include "components/user_prefs/pref_registry_syncable.h" 17 #include "components/user_prefs/pref_registry_syncable.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/notification_details.h"
20 #include "content/public/browser/notification_source.h"
21 #include "content/public/common/url_constants.h"
22 #include "google_apis/gaia/gaia_urls.h"
23 #include "net/base/load_flags.h" 18 #include "net/base/load_flags.h"
24 #include "net/base/net_util.h" 19 #include "net/base/net_util.h"
25 #include "net/url_request/url_request.h" 20 #include "net/url_request/url_request.h"
26 #include "url/gurl.h"
27 21
28 #if !defined(OS_CHROMEOS)
29 #include "chrome/browser/signin/signin_manager.h"
30 #endif
31
32 using content::BrowserThread;
33 using url_matcher::URLMatcher; 22 using url_matcher::URLMatcher;
34 using url_matcher::URLMatcherCondition; 23 using url_matcher::URLMatcherCondition;
35 using url_matcher::URLMatcherConditionFactory; 24 using url_matcher::URLMatcherConditionFactory;
36 using url_matcher::URLMatcherConditionSet; 25 using url_matcher::URLMatcherConditionSet;
37 using url_matcher::URLMatcherPortFilter; 26 using url_matcher::URLMatcherPortFilter;
38 using url_matcher::URLMatcherSchemeFilter; 27 using url_matcher::URLMatcherSchemeFilter;
39 28
40 namespace policy { 29 namespace policy {
41 30
42 namespace { 31 namespace {
43 32
33 const char kFileScheme[] = "file";
34
44 // Maximum filters per policy. Filters over this index are ignored. 35 // Maximum filters per policy. Filters over this index are ignored.
45 const size_t kMaxFiltersPerPolicy = 1000; 36 const size_t kMaxFiltersPerPolicy = 1000;
46 37
47 #if !defined(OS_CHROMEOS) 38 // A task that builds the blacklist on a background thread.
48 39 void BuildBlacklist(scoped_ptr<base::ListValue> block,
49 const char kServiceLoginAuth[] = "/ServiceLoginAuth"; 40 scoped_ptr<base::ListValue> allow,
50 41 URLBlacklist* blacklist) {
51 bool IsSigninFlowURL(const GURL& url) {
52 // Whitelist all the signin flow URLs flagged by the SigninManager.
53 if (SigninManager::IsWebBasedSigninFlowURL(url))
54 return true;
55
56 // Additionally whitelist /ServiceLoginAuth.
57 if (url.GetOrigin() != GaiaUrls::GetInstance()->gaia_url().GetOrigin())
58 return false;
59 return url.path() == kServiceLoginAuth;
60 }
61
62 #endif // !defined(OS_CHROMEOS)
63
64 // A task that builds the blacklist on the FILE thread.
65 scoped_ptr<URLBlacklist> BuildBlacklist(scoped_ptr<base::ListValue> block,
66 scoped_ptr<base::ListValue> allow) {
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
68
69 scoped_ptr<URLBlacklist> blacklist(new URLBlacklist);
70 blacklist->Block(block.get()); 42 blacklist->Block(block.get());
71 blacklist->Allow(allow.get()); 43 blacklist->Allow(allow.get());
72 return blacklist.Pass();
73 } 44 }
74 45
75 } // namespace 46 } // namespace
76 47
77 struct URLBlacklist::FilterComponents { 48 struct URLBlacklist::FilterComponents {
78 FilterComponents() : port(0), match_subdomains(true), allow(true) {} 49 FilterComponents() : port(0), match_subdomains(true), allow(true) {}
79 ~FilterComponents() {} 50 ~FilterComponents() {}
80 51
81 std::string scheme; 52 std::string scheme;
82 std::string host; 53 std::string host;
83 uint16 port; 54 uint16 port;
84 std::string path; 55 std::string path;
85 bool match_subdomains; 56 bool match_subdomains;
86 bool allow; 57 bool allow;
87 }; 58 };
88 59
89 URLBlacklist::URLBlacklist() : id_(0), 60 URLBlacklist::URLBlacklist(SegmentURLCallback segment_url)
90 url_matcher_(new URLMatcher) { 61 : segment_url_(segment_url), id_(0), url_matcher_(new URLMatcher) {}
91 }
92 62
93 URLBlacklist::~URLBlacklist() { 63 URLBlacklist::~URLBlacklist() {
94 } 64 }
95 65
96 void URLBlacklist::AddFilters(bool allow, 66 void URLBlacklist::AddFilters(bool allow,
97 const base::ListValue* list) { 67 const base::ListValue* list) {
98 URLMatcherConditionSet::Vector all_conditions; 68 URLMatcherConditionSet::Vector all_conditions;
99 size_t size = std::min(kMaxFiltersPerPolicy, list->GetSize()); 69 size_t size = std::min(kMaxFiltersPerPolicy, list->GetSize());
100 for (size_t i = 0; i < size; ++i) { 70 for (size_t i = 0; i < size; ++i) {
101 std::string pattern; 71 std::string pattern;
102 bool success = list->GetString(i, &pattern); 72 bool success = list->GetString(i, &pattern);
103 DCHECK(success); 73 DCHECK(success);
104 FilterComponents components; 74 FilterComponents components;
105 components.allow = allow; 75 components.allow = allow;
106 if (!FilterToComponents(pattern, &components.scheme, &components.host, 76 if (!FilterToComponents(segment_url_, pattern, &components.scheme,
107 &components.match_subdomains, &components.port, 77 &components.host, &components.match_subdomains,
108 &components.path)) { 78 &components.port, &components.path)) {
109 LOG(ERROR) << "Invalid pattern " << pattern; 79 LOG(ERROR) << "Invalid pattern " << pattern;
110 continue; 80 continue;
111 } 81 }
112 82
113 all_conditions.push_back( 83 all_conditions.push_back(
114 CreateConditionSet(url_matcher_.get(), ++id_, components.scheme, 84 CreateConditionSet(url_matcher_.get(), ++id_, components.scheme,
115 components.host, components.match_subdomains, 85 components.host, components.match_subdomains,
116 components.port, components.path)); 86 components.port, components.path));
117 filters_[id_] = components; 87 filters_[id_] = components;
118 } 88 }
(...skipping 27 matching lines...) Expand all
146 return false; 116 return false;
147 117
148 return !max->allow; 118 return !max->allow;
149 } 119 }
150 120
151 size_t URLBlacklist::Size() const { 121 size_t URLBlacklist::Size() const {
152 return filters_.size(); 122 return filters_.size();
153 } 123 }
154 124
155 // static 125 // static
156 bool URLBlacklist::FilterToComponents(const std::string& filter, 126 bool URLBlacklist::FilterToComponents(SegmentURLCallback segment_url,
127 const std::string& filter,
157 std::string* scheme, 128 std::string* scheme,
158 std::string* host, 129 std::string* host,
159 bool* match_subdomains, 130 bool* match_subdomains,
160 uint16* port, 131 uint16* port,
161 std::string* path) { 132 std::string* path) {
162 url_parse::Parsed parsed; 133 url_parse::Parsed parsed;
163 134
164 if (URLFixerUpper::SegmentURL(filter, &parsed) == chrome::kFileScheme) { 135 if (segment_url(filter, &parsed) == kFileScheme) {
165 base::FilePath file_path; 136 base::FilePath file_path;
166 if (!net::FileURLToFilePath(GURL(filter), &file_path)) 137 if (!net::FileURLToFilePath(GURL(filter), &file_path))
167 return false; 138 return false;
168 139
169 *scheme = chrome::kFileScheme; 140 *scheme = kFileScheme;
170 host->clear(); 141 host->clear();
171 *match_subdomains = true; 142 *match_subdomains = true;
172 *port = 0; 143 *port = 0;
173 // Special path when the |filter| is 'file://*'. 144 // Special path when the |filter| is 'file://*'.
174 *path = (filter == "file://*") ? "" : file_path.AsUTF8Unsafe(); 145 *path = (filter == "file://*") ? "" : file_path.AsUTF8Unsafe();
175 #if defined(FILE_PATH_USES_WIN_SEPARATORS) 146 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
176 // Separators have to be canonicalized on Windows. 147 // Separators have to be canonicalized on Windows.
177 std::replace(path->begin(), path->end(), '\\', '/'); 148 std::replace(path->begin(), path->end(), '\\', '/');
178 *path = "/" + *path; 149 *path = "/" + *path;
179 #endif 150 #endif
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 size_t other_path_length = rhs.path.length(); 254 size_t other_path_length = rhs.path.length();
284 if (path_length != other_path_length) 255 if (path_length != other_path_length)
285 return path_length > other_path_length; 256 return path_length > other_path_length;
286 257
287 if (lhs.allow && !rhs.allow) 258 if (lhs.allow && !rhs.allow)
288 return true; 259 return true;
289 260
290 return false; 261 return false;
291 } 262 }
292 263
293 URLBlacklistManager::URLBlacklistManager(PrefService* pref_service) 264 URLBlacklistManager::URLBlacklistManager(
265 PrefService* pref_service,
266 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner,
267 URLBlacklist::SegmentURLCallback segment_url,
268 SkipBlacklistCallback skip_blacklist)
294 : ui_weak_ptr_factory_(this), 269 : ui_weak_ptr_factory_(this),
295 pref_service_(pref_service), 270 pref_service_(pref_service),
271 io_task_runner_(io_task_runner),
272 segment_url_(segment_url),
273 skip_blacklist_(skip_blacklist),
296 io_weak_ptr_factory_(this), 274 io_weak_ptr_factory_(this),
297 blacklist_(new URLBlacklist) { 275 ui_task_runner_(base::MessageLoopProxy::current()),
298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 276 blacklist_(new URLBlacklist(segment_url)) {
299
300 pref_change_registrar_.Init(pref_service_); 277 pref_change_registrar_.Init(pref_service_);
301 base::Closure callback = base::Bind(&URLBlacklistManager::ScheduleUpdate, 278 base::Closure callback = base::Bind(&URLBlacklistManager::ScheduleUpdate,
302 base::Unretained(this)); 279 base::Unretained(this));
303 pref_change_registrar_.Add(prefs::kUrlBlacklist, callback); 280 pref_change_registrar_.Add(policy_prefs::kUrlBlacklist, callback);
304 pref_change_registrar_.Add(prefs::kUrlWhitelist, callback); 281 pref_change_registrar_.Add(policy_prefs::kUrlWhitelist, callback);
305 282
306 // Start enforcing the policies without a delay when they are present at 283 // Start enforcing the policies without a delay when they are present at
307 // startup. 284 // startup.
308 if (pref_service_->HasPrefPath(prefs::kUrlBlacklist)) 285 if (pref_service_->HasPrefPath(policy_prefs::kUrlBlacklist))
309 Update(); 286 Update();
310 } 287 }
311 288
312 void URLBlacklistManager::ShutdownOnUIThread() { 289 void URLBlacklistManager::ShutdownOnUIThread() {
313 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 290 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
314 // Cancel any pending updates, and stop listening for pref change updates. 291 // Cancel any pending updates, and stop listening for pref change updates.
315 ui_weak_ptr_factory_.InvalidateWeakPtrs(); 292 ui_weak_ptr_factory_.InvalidateWeakPtrs();
316 pref_change_registrar_.RemoveAll(); 293 pref_change_registrar_.RemoveAll();
317 } 294 }
318 295
319 URLBlacklistManager::~URLBlacklistManager() { 296 URLBlacklistManager::~URLBlacklistManager() {
320 } 297 }
321 298
322 void URLBlacklistManager::ScheduleUpdate() { 299 void URLBlacklistManager::ScheduleUpdate() {
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 300 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
324 // Cancel pending updates, if any. This can happen if two preferences that 301 // Cancel pending updates, if any. This can happen if two preferences that
325 // change the blacklist are updated in one message loop cycle. In those cases, 302 // change the blacklist are updated in one message loop cycle. In those cases,
326 // only rebuild the blacklist after all the preference updates are processed. 303 // only rebuild the blacklist after all the preference updates are processed.
327 ui_weak_ptr_factory_.InvalidateWeakPtrs(); 304 ui_weak_ptr_factory_.InvalidateWeakPtrs();
328 base::MessageLoop::current()->PostTask( 305 ui_task_runner_->PostTask(
329 FROM_HERE, 306 FROM_HERE,
330 base::Bind(&URLBlacklistManager::Update, 307 base::Bind(&URLBlacklistManager::Update,
331 ui_weak_ptr_factory_.GetWeakPtr())); 308 ui_weak_ptr_factory_.GetWeakPtr()));
332 } 309 }
333 310
334 void URLBlacklistManager::Update() { 311 void URLBlacklistManager::Update() {
335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 312 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
336 313
337 // The preferences can only be read on the UI thread. 314 // The preferences can only be read on the UI thread.
338 scoped_ptr<base::ListValue> block( 315 scoped_ptr<base::ListValue> block(
339 pref_service_->GetList(prefs::kUrlBlacklist)->DeepCopy()); 316 pref_service_->GetList(policy_prefs::kUrlBlacklist)->DeepCopy());
340 scoped_ptr<base::ListValue> allow( 317 scoped_ptr<base::ListValue> allow(
341 pref_service_->GetList(prefs::kUrlWhitelist)->DeepCopy()); 318 pref_service_->GetList(policy_prefs::kUrlWhitelist)->DeepCopy());
342 319
343 // Go through the IO thread to grab a WeakPtr to |this|. This is safe from 320 // Go through the IO thread to grab a WeakPtr to |this|. This is safe from
344 // here, since this task will always execute before a potential deletion of 321 // here, since this task will always execute before a potential deletion of
345 // ProfileIOData on IO. 322 // ProfileIOData on IO.
346 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 323 io_task_runner_->PostTask(FROM_HERE,
347 base::Bind(&URLBlacklistManager::UpdateOnIO, 324 base::Bind(&URLBlacklistManager::UpdateOnIO,
348 base::Unretained(this), 325 base::Unretained(this),
349 base::Passed(&block), 326 base::Passed(&block),
350 base::Passed(&allow))); 327 base::Passed(&allow)));
351 } 328 }
352 329
353 void URLBlacklistManager::UpdateOnIO(scoped_ptr<base::ListValue> block, 330 void URLBlacklistManager::UpdateOnIO(scoped_ptr<base::ListValue> block,
354 scoped_ptr<base::ListValue> allow) { 331 scoped_ptr<base::ListValue> allow) {
355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 332 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
356 // The URLBlacklist is built on the FILE thread. Once it's ready, it is passed 333 // The URLBlacklist is built on the FILE thread. Once it's ready, it is passed
357 // to the URLBlacklistManager on IO. 334 // to the URLBlacklistManager on IO.
358 BrowserThread::PostTaskAndReplyWithResult( 335 scoped_ptr<URLBlacklist> blacklist(new URLBlacklist(segment_url_));
359 BrowserThread::FILE, FROM_HERE, 336 URLBlacklist* raw_blacklist = blacklist.get();
337 const bool task_is_slow = false;
338 base::WorkerPool::PostTaskAndReply(
339 FROM_HERE,
360 base::Bind(&BuildBlacklist, 340 base::Bind(&BuildBlacklist,
361 base::Passed(&block), 341 base::Passed(&block),
362 base::Passed(&allow)), 342 base::Passed(&allow),
343 base::Unretained(raw_blacklist)),
363 base::Bind(&URLBlacklistManager::SetBlacklist, 344 base::Bind(&URLBlacklistManager::SetBlacklist,
364 io_weak_ptr_factory_.GetWeakPtr())); 345 io_weak_ptr_factory_.GetWeakPtr(),
346 base::Passed(&blacklist)),
347 task_is_slow);
365 } 348 }
366 349
367 void URLBlacklistManager::SetBlacklist(scoped_ptr<URLBlacklist> blacklist) { 350 void URLBlacklistManager::SetBlacklist(scoped_ptr<URLBlacklist> blacklist) {
368 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 351 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
369 blacklist_ = blacklist.Pass(); 352 blacklist_ = blacklist.Pass();
370 } 353 }
371 354
372 bool URLBlacklistManager::IsURLBlocked(const GURL& url) const { 355 bool URLBlacklistManager::IsURLBlocked(const GURL& url) const {
373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 356 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
374 return blacklist_->IsURLBlocked(url); 357 return blacklist_->IsURLBlocked(url);
375 } 358 }
376 359
377 bool URLBlacklistManager::IsRequestBlocked( 360 bool URLBlacklistManager::IsRequestBlocked(
378 const net::URLRequest& request) const { 361 const net::URLRequest& request) const {
379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 362 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
380 int filter_flags = net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME; 363 int filter_flags = net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME;
381 if ((request.load_flags() & filter_flags) == 0) 364 if ((request.load_flags() & filter_flags) == 0)
382 return false; 365 return false;
383 366
384 #if !defined(OS_CHROMEOS) 367 if (skip_blacklist_(request.url()))
385 if (IsSigninFlowURL(request.url()))
386 return false; 368 return false;
387 #endif
388 369
389 return IsURLBlocked(request.url()); 370 return IsURLBlocked(request.url());
390 } 371 }
391 372
392 // static 373 // static
393 void URLBlacklistManager::RegisterProfilePrefs( 374 void URLBlacklistManager::RegisterProfilePrefs(
394 user_prefs::PrefRegistrySyncable* registry) { 375 user_prefs::PrefRegistrySyncable* registry) {
395 registry->RegisterListPref(prefs::kUrlBlacklist, 376 registry->RegisterListPref(policy_prefs::kUrlBlacklist,
396 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 377 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
397 registry->RegisterListPref(prefs::kUrlWhitelist, 378 registry->RegisterListPref(policy_prefs::kUrlWhitelist,
398 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 379 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
399 } 380 }
400 381
401 } // namespace policy 382 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/url_blacklist_manager.h ('k') | chrome/browser/policy/url_blacklist_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698