OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013 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 #include "chrome/browser/managed_mode/managed_user_service.h" |
| 6 |
| 7 #include "base/memory/ref_counted.h" |
| 8 #include "base/sequenced_task_runner.h" |
| 9 #include "chrome/browser/extensions/extension_service.h" |
| 10 #include "chrome/browser/extensions/extension_system.h" |
| 11 #include "chrome/browser/managed_mode/managed_mode_site_list.h" |
| 12 #include "chrome/browser/prefs/pref_service.h" |
| 13 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| 14 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/common/chrome_notification_types.h" |
| 16 #include "chrome/common/extensions/extension_set.h" |
| 17 #include "chrome/common/pref_names.h" |
| 18 #include "content/public/browser/browser_thread.h" |
| 19 #include "grit/generated_resources.h" |
| 20 #include "ui/base/l10n/l10n_util.h" |
| 21 |
| 22 using content::BrowserThread; |
| 23 |
| 24 ManagedUserService::URLFilterContext::URLFilterContext() |
| 25 : ui_url_filter_(new ManagedModeURLFilter), |
| 26 io_url_filter_(new ManagedModeURLFilter) {} |
| 27 ManagedUserService::URLFilterContext::~URLFilterContext() {} |
| 28 |
| 29 ManagedModeURLFilter* |
| 30 ManagedUserService::URLFilterContext::ui_url_filter() const { |
| 31 return ui_url_filter_.get(); |
| 32 } |
| 33 |
| 34 ManagedModeURLFilter* |
| 35 ManagedUserService::URLFilterContext::io_url_filter() const { |
| 36 return io_url_filter_.get(); |
| 37 } |
| 38 |
| 39 void ManagedUserService::URLFilterContext::SetDefaultFilteringBehavior( |
| 40 ManagedModeURLFilter::FilteringBehavior behavior) { |
| 41 ui_url_filter_->SetDefaultFilteringBehavior(behavior); |
| 42 BrowserThread::PostTask( |
| 43 BrowserThread::IO, |
| 44 FROM_HERE, |
| 45 base::Bind(&ManagedModeURLFilter::SetDefaultFilteringBehavior, |
| 46 io_url_filter_.get(), |
| 47 behavior)); |
| 48 } |
| 49 |
| 50 void ManagedUserService::URLFilterContext::LoadWhitelists( |
| 51 ScopedVector<ManagedModeSiteList> site_lists) { |
| 52 // ManagedModeURLFilter::LoadWhitelists takes ownership of |site_lists|, |
| 53 // so we make an additional copy of it. |
| 54 /// TODO(bauerb): This is kinda ugly. |
| 55 ScopedVector<ManagedModeSiteList> site_lists_copy; |
| 56 for (ScopedVector<ManagedModeSiteList>::iterator it = site_lists.begin(); |
| 57 it != site_lists.end(); ++it) { |
| 58 site_lists_copy.push_back((*it)->Clone()); |
| 59 } |
| 60 ui_url_filter_->LoadWhitelists(site_lists.Pass()); |
| 61 BrowserThread::PostTask( |
| 62 BrowserThread::IO, |
| 63 FROM_HERE, |
| 64 base::Bind(&ManagedModeURLFilter::LoadWhitelists, |
| 65 io_url_filter_, |
| 66 base::Passed(&site_lists_copy))); |
| 67 } |
| 68 |
| 69 void ManagedUserService::URLFilterContext::SetManualLists( |
| 70 scoped_ptr<ListValue> whitelist, |
| 71 scoped_ptr<ListValue> blacklist) { |
| 72 ui_url_filter_->SetManualLists(whitelist.get(), blacklist.get()); |
| 73 BrowserThread::PostTask( |
| 74 BrowserThread::IO, |
| 75 FROM_HERE, |
| 76 base::Bind(&ManagedModeURLFilter::SetManualLists, |
| 77 io_url_filter_, |
| 78 base::Owned(whitelist.release()), |
| 79 base::Owned(blacklist.release()))); |
| 80 } |
| 81 |
| 82 void ManagedUserService::URLFilterContext::AddURLPatternToManualList( |
| 83 const bool is_whitelist, |
| 84 const std::string& url) { |
| 85 ui_url_filter_->AddURLPatternToManualList(is_whitelist, url); |
| 86 BrowserThread::PostTask( |
| 87 BrowserThread::IO, |
| 88 FROM_HERE, |
| 89 base::Bind(&ManagedModeURLFilter::AddURLPatternToManualList, |
| 90 io_url_filter_, |
| 91 is_whitelist, |
| 92 url)); |
| 93 } |
| 94 |
| 95 ManagedUserService::ManagedUserService(Profile* profile) : profile_(profile) { |
| 96 if (!ProfileIsManaged()) |
| 97 return; |
| 98 |
| 99 extensions::ExtensionSystem* extension_system = |
| 100 extensions::ExtensionSystem::Get(profile); |
| 101 extensions::ManagementPolicy* management_policy = |
| 102 extension_system->management_policy(); |
| 103 if (management_policy) |
| 104 extension_system->management_policy()->RegisterProvider(this); |
| 105 |
| 106 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| 107 content::Source<Profile>(profile_)); |
| 108 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 109 content::Source<Profile>(profile_)); |
| 110 pref_change_registrar_.Init(profile_->GetPrefs()); |
| 111 pref_change_registrar_.Add( |
| 112 prefs::kDefaultManagedModeFilteringBehavior, |
| 113 base::Bind( |
| 114 &ManagedUserService::OnDefaultFilteringBehaviorChanged, |
| 115 base::Unretained(this))); |
| 116 |
| 117 // Initialize the filter. |
| 118 OnDefaultFilteringBehaviorChanged(); |
| 119 UpdateSiteLists(); |
| 120 UpdateManualLists(); |
| 121 } |
| 122 |
| 123 ManagedUserService::~ManagedUserService() { |
| 124 } |
| 125 |
| 126 bool ManagedUserService::ProfileIsManaged() const { |
| 127 return profile_->GetPrefs()->GetBoolean(prefs::kProfileIsManaged); |
| 128 } |
| 129 |
| 130 // static |
| 131 void ManagedUserService::RegisterUserPrefs(PrefServiceSyncable* prefs) { |
| 132 prefs->RegisterListPref(prefs::kManagedModeWhitelist, |
| 133 PrefServiceSyncable::UNSYNCABLE_PREF); |
| 134 prefs->RegisterListPref(prefs::kManagedModeBlacklist, |
| 135 PrefServiceSyncable::UNSYNCABLE_PREF); |
| 136 prefs->RegisterIntegerPref(prefs::kDefaultManagedModeFilteringBehavior, |
| 137 ManagedModeURLFilter::BLOCK, |
| 138 PrefServiceSyncable::UNSYNCABLE_PREF); |
| 139 } |
| 140 |
| 141 scoped_refptr<const ManagedModeURLFilter> |
| 142 ManagedUserService::GetURLFilterForIOThread() { |
| 143 return url_filter_context_.io_url_filter(); |
| 144 } |
| 145 |
| 146 ManagedModeURLFilter* ManagedUserService::GetURLFilterForUIThread() { |
| 147 return url_filter_context_.ui_url_filter(); |
| 148 } |
| 149 |
| 150 // Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js). |
| 151 // Items on a list, but with no category, must return 0 (CATEGORY_OTHER). |
| 152 #define CATEGORY_NOT_ON_LIST -1; |
| 153 #define CATEGORY_OTHER 0; |
| 154 |
| 155 int ManagedUserService::GetCategory(const GURL& url) { |
| 156 std::vector<ManagedModeSiteList::Site*> sites; |
| 157 GetURLFilterForUIThread()->GetSites(url, &sites); |
| 158 if (sites.empty()) |
| 159 return CATEGORY_NOT_ON_LIST; |
| 160 |
| 161 return (*sites.begin())->category_id; |
| 162 } |
| 163 |
| 164 // static |
| 165 void ManagedUserService::GetCategoryNames(CategoryList* list) { |
| 166 ManagedModeSiteList::GetCategoryNames(list); |
| 167 }; |
| 168 |
| 169 void ManagedUserService::AddToManualList(bool is_whitelist, |
| 170 const base::ListValue& list) { |
| 171 ListPrefUpdate pref_update(profile_->GetPrefs(), |
| 172 is_whitelist ? prefs::kManagedModeWhitelist : |
| 173 prefs::kManagedModeBlacklist); |
| 174 ListValue* pref_list = pref_update.Get(); |
| 175 |
| 176 for (size_t i = 0; i < list.GetSize(); ++i) { |
| 177 std::string url_pattern; |
| 178 list.GetString(i, &url_pattern); |
| 179 |
| 180 if (!IsInManualList(is_whitelist, url_pattern)) { |
| 181 pref_list->AppendString(url_pattern); |
| 182 AddURLPatternToManualList(is_whitelist, url_pattern); |
| 183 } |
| 184 } |
| 185 } |
| 186 |
| 187 void ManagedUserService::RemoveFromManualList(bool is_whitelist, |
| 188 const base::ListValue& list) { |
| 189 ListPrefUpdate pref_update(profile_->GetPrefs(), |
| 190 is_whitelist ? prefs::kManagedModeWhitelist : |
| 191 prefs::kManagedModeBlacklist); |
| 192 ListValue* pref_list = pref_update.Get(); |
| 193 |
| 194 for (size_t i = 0; i < list.GetSize(); ++i) { |
| 195 std::string pattern; |
| 196 size_t out_index; |
| 197 list.GetString(i, &pattern); |
| 198 StringValue value_to_remove(pattern); |
| 199 |
| 200 pref_list->Remove(value_to_remove, &out_index); |
| 201 } |
| 202 } |
| 203 |
| 204 bool ManagedUserService::IsInManualList(bool is_whitelist, |
| 205 const std::string& url_pattern) { |
| 206 StringValue pattern(url_pattern); |
| 207 const ListValue* list = profile_->GetPrefs()->GetList( |
| 208 is_whitelist ? prefs::kManagedModeWhitelist : |
| 209 prefs::kManagedModeBlacklist); |
| 210 return list->Find(pattern) != list->end(); |
| 211 } |
| 212 |
| 213 // static |
| 214 scoped_ptr<base::ListValue> ManagedUserService::GetBlacklist() { |
| 215 return make_scoped_ptr( |
| 216 profile_->GetPrefs()->GetList(prefs::kManagedModeBlacklist)->DeepCopy()); |
| 217 } |
| 218 |
| 219 std::string ManagedUserService::GetDebugPolicyProviderName() const { |
| 220 // Save the string space in official builds. |
| 221 #ifdef NDEBUG |
| 222 NOTREACHED(); |
| 223 return std::string(); |
| 224 #else |
| 225 return "Managed User Service"; |
| 226 #endif |
| 227 } |
| 228 |
| 229 bool ManagedUserService::UserMayLoad(const extensions::Extension* extension, |
| 230 string16* error) const { |
| 231 string16 tmp_error; |
| 232 if (ExtensionManagementPolicyImpl(&tmp_error)) |
| 233 return true; |
| 234 |
| 235 // If the extension is already loaded, we allow it, otherwise we'd unload |
| 236 // all existing extensions. |
| 237 ExtensionService* extension_service = |
| 238 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 239 |
| 240 // |extension_service| can be NULL in a unit test. |
| 241 if (extension_service && |
| 242 extension_service->GetInstalledExtension(extension->id())) |
| 243 return true; |
| 244 |
| 245 if (error) |
| 246 *error = tmp_error; |
| 247 return false; |
| 248 } |
| 249 |
| 250 bool ManagedUserService::UserMayModifySettings( |
| 251 const extensions::Extension* extension, |
| 252 string16* error) const { |
| 253 return ExtensionManagementPolicyImpl(error); |
| 254 } |
| 255 |
| 256 void ManagedUserService::Observe(int type, |
| 257 const content::NotificationSource& source, |
| 258 const content::NotificationDetails& details) { |
| 259 switch (type) { |
| 260 case chrome::NOTIFICATION_EXTENSION_LOADED: |
| 261 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
| 262 if (!profile_) |
| 263 break; |
| 264 |
| 265 const extensions::Extension* extension = |
| 266 content::Details<const extensions::Extension>(details).ptr(); |
| 267 if (!extension->GetContentPackSiteList().empty()) |
| 268 UpdateSiteLists(); |
| 269 |
| 270 break; |
| 271 } |
| 272 default: |
| 273 NOTREACHED(); |
| 274 } |
| 275 } |
| 276 |
| 277 bool ManagedUserService::ExtensionManagementPolicyImpl(string16* error) const { |
| 278 if (!ProfileIsManaged()) |
| 279 return true; |
| 280 |
| 281 if (error) |
| 282 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_MODE); |
| 283 return false; |
| 284 } |
| 285 |
| 286 ScopedVector<ManagedModeSiteList> ManagedUserService::GetActiveSiteLists() { |
| 287 ExtensionService* extension_service = |
| 288 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 289 const ExtensionSet* extensions = extension_service->extensions(); |
| 290 ScopedVector<ManagedModeSiteList> site_lists; |
| 291 for (ExtensionSet::const_iterator it = extensions->begin(); |
| 292 it != extensions->end(); ++it) { |
| 293 const extensions::Extension* extension = *it; |
| 294 if (!extension_service->IsExtensionEnabled(extension->id())) |
| 295 continue; |
| 296 |
| 297 ExtensionResource site_list = extension->GetContentPackSiteList(); |
| 298 if (!site_list.empty()) |
| 299 site_lists.push_back(new ManagedModeSiteList(extension->id(), site_list)); |
| 300 } |
| 301 |
| 302 return site_lists.Pass(); |
| 303 } |
| 304 |
| 305 void ManagedUserService::OnDefaultFilteringBehaviorChanged() { |
| 306 DCHECK(ProfileIsManaged()); |
| 307 |
| 308 int behavior_value = profile_->GetPrefs()->GetInteger( |
| 309 prefs::kDefaultManagedModeFilteringBehavior); |
| 310 ManagedModeURLFilter::FilteringBehavior behavior = |
| 311 ManagedModeURLFilter::BehaviorFromInt(behavior_value); |
| 312 url_filter_context_.SetDefaultFilteringBehavior(behavior); |
| 313 } |
| 314 |
| 315 void ManagedUserService::UpdateSiteLists() { |
| 316 url_filter_context_.LoadWhitelists(GetActiveSiteLists()); |
| 317 } |
| 318 |
| 319 void ManagedUserService::UpdateManualLists() { |
| 320 url_filter_context_.SetManualLists(GetWhitelist(), GetBlacklist()); |
| 321 } |
| 322 |
| 323 scoped_ptr<base::ListValue> ManagedUserService::GetWhitelist() { |
| 324 return make_scoped_ptr( |
| 325 profile_->GetPrefs()->GetList(prefs::kManagedModeWhitelist)->DeepCopy()); |
| 326 } |
| 327 |
| 328 void ManagedUserService::AddURLPatternToManualList( |
| 329 bool is_whitelist, |
| 330 const std::string& url_pattern) { |
| 331 url_filter_context_.AddURLPatternToManualList(true, url_pattern); |
| 332 } |
OLD | NEW |