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 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_POLICY_URL_BLACKLIST_MANAGER_H_ 6#define CHROME_BROWSER_POLICY_URL_BLACKLIST_MANAGER_H_ 7 8#include <map> 9#include <string> 10 11#include "base/basictypes.h" 12#include "base/callback_forward.h" 13#include "base/compiler_specific.h" 14#include "base/containers/hash_tables.h" 15#include "base/memory/scoped_ptr.h" 16#include "base/memory/weak_ptr.h" 17#include "base/prefs/pref_change_registrar.h" 18#include "components/url_matcher/url_matcher.h" 19 20class GURL; 21class PrefService; 22 23namespace base { 24class ListValue; 25} 26 27namespace net { 28class URLRequest; 29} 30 31namespace user_prefs { 32class PrefRegistrySyncable; 33} 34 35namespace policy { 36 37// Contains a set of filters to block and allow certain URLs, and matches GURLs 38// against this set. The filters are currently kept in memory. 39class URLBlacklist { 40 public: 41 URLBlacklist(); 42 virtual ~URLBlacklist(); 43 44 // Allows or blocks URLs matching one of the filters, depending on |allow|. 45 void AddFilters(bool allow, const base::ListValue* filters); 46 47 // URLs matching one of the |filters| will be blocked. The filter format is 48 // documented at 49 // http://www.chromium.org/administrators/url-blacklist-filter-format. 50 void Block(const base::ListValue* filters); 51 52 // URLs matching one of the |filters| will be allowed. If a URL is both 53 // Blocked and Allowed, Allow takes precedence. 54 void Allow(const base::ListValue* filters); 55 56 // Returns true if the URL is blocked. 57 bool IsURLBlocked(const GURL& url) const; 58 59 // Returns the number of items in the list. 60 size_t Size() const; 61 62 // Splits a URL filter into its components. A GURL isn't used because these 63 // can be invalid URLs e.g. "google.com". 64 // Returns false if the URL couldn't be parsed. 65 // The |host| is preprocessed so it can be passed to URLMatcher for the 66 // appropriate condition. 67 // The optional username and password are ignored. 68 // |match_subdomains| specifies whether the filter should include subdomains 69 // of the hostname (if it is one.) 70 // |port| is 0 if none is explicitly defined. 71 // |path| does not include query parameters. 72 static bool FilterToComponents(const std::string& filter, 73 std::string* scheme, 74 std::string* host, 75 bool* match_subdomains, 76 uint16* port, 77 std::string* path); 78 79 // Creates a condition set that can be used with the |url_matcher|. |id| needs 80 // to be a unique number that will be returned by the |url_matcher| if the URL 81 // matches that condition set. 82 static scoped_refptr<url_matcher::URLMatcherConditionSet> CreateConditionSet( 83 url_matcher::URLMatcher* url_matcher, 84 url_matcher::URLMatcherConditionSet::ID id, 85 const std::string& scheme, 86 const std::string& host, 87 bool match_subdomains, 88 uint16 port, 89 const std::string& path); 90 91 private: 92 struct FilterComponents; 93 94 // Returns true if |lhs| takes precedence over |rhs|. 95 static bool FilterTakesPrecedence(const FilterComponents& lhs, 96 const FilterComponents& rhs); 97 98 url_matcher::URLMatcherConditionSet::ID id_; 99 std::map<url_matcher::URLMatcherConditionSet::ID, FilterComponents> filters_; 100 scoped_ptr<url_matcher::URLMatcher> url_matcher_; 101 102 DISALLOW_COPY_AND_ASSIGN(URLBlacklist); 103}; 104 105// Tracks the blacklist policies for a given profile, and updates it on changes. 106// 107// This class interacts with both the UI thread, where notifications of pref 108// changes are received from, and the IO thread, which owns it (in the 109// ProfileIOData) and checks for blacklisted URLs (from ChromeNetworkDelegate). 110// 111// It must be constructed on the UI thread, to set up |ui_weak_ptr_factory_| and 112// the prefs listeners. 113// 114// ShutdownOnUIThread must be called from UI before destruction, to release 115// the prefs listeners on the UI thread. This is done from ProfileIOData. 116// 117// Update tasks from the UI thread can post safely to the IO thread, since the 118// destruction order of Profile and ProfileIOData guarantees that if this 119// exists in UI, then a potential destruction on IO will come after any task 120// posted to IO from that method on UI. This is used to go through IO before 121// the actual update starts, and grab a WeakPtr. 122class URLBlacklistManager { 123 public: 124 // Must be constructed on the UI thread. 125 explicit URLBlacklistManager(PrefService* pref_service); 126 virtual ~URLBlacklistManager(); 127 128 // Must be called on the UI thread, before destruction. 129 void ShutdownOnUIThread(); 130 131 // Returns true if |url| is blocked by the current blacklist. Must be called 132 // from the IO thread. 133 bool IsURLBlocked(const GURL& url) const; 134 135 // Returns true if |request| is blocked by the current blacklist. 136 // Only main frame and sub frame requests may be blocked; other sub resources 137 // or background downloads (e.g. extensions updates, sync, etc) are not 138 // filtered. The sync signin page is also not filtered. 139 // Must be called from the IO thread. 140 bool IsRequestBlocked(const net::URLRequest& request) const; 141 142 // Replaces the current blacklist. Must be called on the IO thread. 143 // Virtual for testing. 144 virtual void SetBlacklist(scoped_ptr<URLBlacklist> blacklist); 145 146 // Registers the preferences related to blacklisting in the given PrefService. 147 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 148 149 protected: 150 // Used to delay updating the blacklist while the preferences are 151 // changing, and execute only one update per simultaneous prefs changes. 152 void ScheduleUpdate(); 153 154 // Updates the blacklist using the current preference values. 155 // Virtual for testing. 156 virtual void Update(); 157 158 // Starts the blacklist update on the IO thread, using the filters in 159 // |block| and |allow|. Protected for testing. 160 void UpdateOnIO(scoped_ptr<base::ListValue> block, 161 scoped_ptr<base::ListValue> allow); 162 163 private: 164 // --------- 165 // UI thread 166 // --------- 167 168 // Used to post update tasks to the UI thread. 169 base::WeakPtrFactory<URLBlacklistManager> ui_weak_ptr_factory_; 170 171 // Used to track the policies and update the blacklist on changes. 172 PrefChangeRegistrar pref_change_registrar_; 173 PrefService* pref_service_; // Weak. 174 175 // --------- 176 // IO thread 177 // --------- 178 179 // Used to get |weak_ptr_| to self on the IO thread. 180 base::WeakPtrFactory<URLBlacklistManager> io_weak_ptr_factory_; 181 182 // The current blacklist. 183 scoped_ptr<URLBlacklist> blacklist_; 184 185 DISALLOW_COPY_AND_ASSIGN(URLBlacklistManager); 186}; 187 188} // namespace policy 189 190#endif // CHROME_BROWSER_POLICY_URL_BLACKLIST_MANAGER_H_ 191