Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / content_settings / content_settings_policy_provider.cc
blob56b6c124bdd8abe6f732b0afc550d9dc936b37f6
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.
5 #include "chrome/browser/content_settings/content_settings_policy_provider.h"
7 #include <string>
8 #include <vector>
10 #include "base/json/json_reader.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/values.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/content_settings/content_settings_rule.h"
15 #include "chrome/browser/content_settings/content_settings_utils.h"
16 #include "chrome/common/content_settings_pattern.h"
17 #include "chrome/common/pref_names.h"
18 #include "components/user_prefs/pref_registry_syncable.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/notification_details.h"
21 #include "content/public/browser/notification_source.h"
23 using content::BrowserThread;
25 namespace {
27 // The preferences used to manage ContentSettingsTypes.
28 const char* kPrefToManageType[] = {
29 prefs::kManagedDefaultCookiesSetting,
30 prefs::kManagedDefaultImagesSetting,
31 prefs::kManagedDefaultJavaScriptSetting,
32 prefs::kManagedDefaultPluginsSetting,
33 prefs::kManagedDefaultPopupsSetting,
34 prefs::kManagedDefaultGeolocationSetting,
35 prefs::kManagedDefaultNotificationsSetting,
36 NULL, // No policy for default value of content type auto-select-certificate
37 NULL, // No policy for default value of fullscreen requests
38 NULL, // No policy for default value of mouse lock requests
39 NULL, // No policy for default value of mixed script blocking
40 prefs::kManagedDefaultMediaStreamSetting,
41 NULL, // No policy for default value of media stream mic
42 NULL, // No policy for default value of media stream camera
43 NULL, // No policy for default value of protocol handlers
44 NULL, // No policy for default value of PPAPI broker
45 NULL, // No policy for default value of multiple automatic downloads
46 NULL, // No policy for default value of MIDI system exclusive requests
47 #if defined(OS_WIN)
48 NULL, // No policy for default value of "switch to desktop"
49 #elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
50 NULL, // No policy for default value of protected media identifier
51 #endif
53 COMPILE_ASSERT(arraysize(kPrefToManageType) == CONTENT_SETTINGS_NUM_TYPES,
54 managed_content_settings_pref_names_array_size_incorrect);
56 struct PrefsForManagedContentSettingsMapEntry {
57 const char* pref_name;
58 ContentSettingsType content_type;
59 ContentSetting setting;
62 const PrefsForManagedContentSettingsMapEntry
63 kPrefsForManagedContentSettingsMap[] = {
65 prefs::kManagedCookiesAllowedForUrls,
66 CONTENT_SETTINGS_TYPE_COOKIES,
67 CONTENT_SETTING_ALLOW
68 }, {
69 prefs::kManagedCookiesSessionOnlyForUrls,
70 CONTENT_SETTINGS_TYPE_COOKIES,
71 CONTENT_SETTING_SESSION_ONLY
72 }, {
73 prefs::kManagedCookiesBlockedForUrls,
74 CONTENT_SETTINGS_TYPE_COOKIES,
75 CONTENT_SETTING_BLOCK
76 }, {
77 prefs::kManagedImagesAllowedForUrls,
78 CONTENT_SETTINGS_TYPE_IMAGES,
79 CONTENT_SETTING_ALLOW
80 }, {
81 prefs::kManagedImagesBlockedForUrls,
82 CONTENT_SETTINGS_TYPE_IMAGES,
83 CONTENT_SETTING_BLOCK
84 }, {
85 prefs::kManagedJavaScriptAllowedForUrls,
86 CONTENT_SETTINGS_TYPE_JAVASCRIPT,
87 CONTENT_SETTING_ALLOW
88 }, {
89 prefs::kManagedJavaScriptBlockedForUrls,
90 CONTENT_SETTINGS_TYPE_JAVASCRIPT,
91 CONTENT_SETTING_BLOCK
92 }, {
93 prefs::kManagedPluginsAllowedForUrls,
94 CONTENT_SETTINGS_TYPE_PLUGINS,
95 CONTENT_SETTING_ALLOW
96 }, {
97 prefs::kManagedPluginsBlockedForUrls,
98 CONTENT_SETTINGS_TYPE_PLUGINS,
99 CONTENT_SETTING_BLOCK
100 }, {
101 prefs::kManagedPopupsAllowedForUrls,
102 CONTENT_SETTINGS_TYPE_POPUPS,
103 CONTENT_SETTING_ALLOW
104 }, {
105 prefs::kManagedPopupsBlockedForUrls,
106 CONTENT_SETTINGS_TYPE_POPUPS,
107 CONTENT_SETTING_BLOCK
108 }, {
109 prefs::kManagedNotificationsAllowedForUrls,
110 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
111 CONTENT_SETTING_ALLOW
112 }, {
113 prefs::kManagedNotificationsBlockedForUrls,
114 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
115 CONTENT_SETTING_BLOCK
119 } // namespace
121 namespace content_settings {
123 // static
124 void PolicyProvider::RegisterProfilePrefs(
125 user_prefs::PrefRegistrySyncable* registry) {
126 registry->RegisterListPref(prefs::kManagedAutoSelectCertificateForUrls,
127 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
128 registry->RegisterListPref(prefs::kManagedCookiesAllowedForUrls,
129 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
130 registry->RegisterListPref(prefs::kManagedCookiesBlockedForUrls,
131 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
132 registry->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls,
133 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
134 registry->RegisterListPref(prefs::kManagedImagesAllowedForUrls,
135 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
136 registry->RegisterListPref(prefs::kManagedImagesBlockedForUrls,
137 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
138 registry->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls,
139 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
140 registry->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls,
141 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
142 registry->RegisterListPref(prefs::kManagedPluginsAllowedForUrls,
143 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
144 registry->RegisterListPref(prefs::kManagedPluginsBlockedForUrls,
145 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
146 registry->RegisterListPref(prefs::kManagedPopupsAllowedForUrls,
147 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
148 registry->RegisterListPref(prefs::kManagedPopupsBlockedForUrls,
149 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
150 registry->RegisterListPref(prefs::kManagedNotificationsAllowedForUrls,
151 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
152 registry->RegisterListPref(prefs::kManagedNotificationsBlockedForUrls,
153 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
154 // Preferences for default content setting policies. If a policy is not set of
155 // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
156 registry->RegisterIntegerPref(
157 prefs::kManagedDefaultCookiesSetting,
158 CONTENT_SETTING_DEFAULT,
159 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
160 registry->RegisterIntegerPref(
161 prefs::kManagedDefaultImagesSetting,
162 CONTENT_SETTING_DEFAULT,
163 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
164 registry->RegisterIntegerPref(
165 prefs::kManagedDefaultJavaScriptSetting,
166 CONTENT_SETTING_DEFAULT,
167 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
168 registry->RegisterIntegerPref(
169 prefs::kManagedDefaultPluginsSetting,
170 CONTENT_SETTING_DEFAULT,
171 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
172 registry->RegisterIntegerPref(
173 prefs::kManagedDefaultPopupsSetting,
174 CONTENT_SETTING_DEFAULT,
175 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
176 registry->RegisterIntegerPref(
177 prefs::kManagedDefaultGeolocationSetting,
178 CONTENT_SETTING_DEFAULT,
179 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
180 registry->RegisterIntegerPref(
181 prefs::kManagedDefaultNotificationsSetting,
182 CONTENT_SETTING_DEFAULT,
183 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
184 registry->RegisterIntegerPref(
185 prefs::kManagedDefaultMediaStreamSetting,
186 CONTENT_SETTING_DEFAULT,
187 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
190 PolicyProvider::PolicyProvider(PrefService* prefs) : prefs_(prefs) {
191 ReadManagedDefaultSettings();
192 ReadManagedContentSettings(false);
194 pref_change_registrar_.Init(prefs_);
195 PrefChangeRegistrar::NamedChangeCallback callback =
196 base::Bind(&PolicyProvider::OnPreferenceChanged, base::Unretained(this));
197 pref_change_registrar_.Add(
198 prefs::kManagedAutoSelectCertificateForUrls, callback);
199 pref_change_registrar_.Add(prefs::kManagedCookiesBlockedForUrls, callback);
200 pref_change_registrar_.Add(prefs::kManagedCookiesAllowedForUrls, callback);
201 pref_change_registrar_.Add(
202 prefs::kManagedCookiesSessionOnlyForUrls, callback);
203 pref_change_registrar_.Add(prefs::kManagedImagesBlockedForUrls, callback);
204 pref_change_registrar_.Add(prefs::kManagedImagesAllowedForUrls, callback);
205 pref_change_registrar_.Add(prefs::kManagedJavaScriptBlockedForUrls, callback);
206 pref_change_registrar_.Add(prefs::kManagedJavaScriptAllowedForUrls, callback);
207 pref_change_registrar_.Add(prefs::kManagedPluginsBlockedForUrls, callback);
208 pref_change_registrar_.Add(prefs::kManagedPluginsAllowedForUrls, callback);
209 pref_change_registrar_.Add(prefs::kManagedPopupsBlockedForUrls, callback);
210 pref_change_registrar_.Add(prefs::kManagedPopupsAllowedForUrls, callback);
211 pref_change_registrar_.Add(
212 prefs::kManagedNotificationsAllowedForUrls, callback);
213 pref_change_registrar_.Add(
214 prefs::kManagedNotificationsBlockedForUrls, callback);
215 // The following preferences are only used to indicate if a
216 // default content setting is managed and to hold the managed default setting
217 // value. If the value for any of the following perferences is set then the
218 // corresponding default content setting is managed. These preferences exist
219 // in parallel to the preference default content settings. If a
220 // default content settings type is managed any user defined excpetions
221 // (patterns) for this type are ignored.
222 pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, callback);
223 pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, callback);
224 pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, callback);
225 pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, callback);
226 pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, callback);
227 pref_change_registrar_.Add(
228 prefs::kManagedDefaultGeolocationSetting, callback);
229 pref_change_registrar_.Add(
230 prefs::kManagedDefaultNotificationsSetting, callback);
231 pref_change_registrar_.Add(
232 prefs::kManagedDefaultMediaStreamSetting, callback);
235 PolicyProvider::~PolicyProvider() {
236 DCHECK(!prefs_);
239 RuleIterator* PolicyProvider::GetRuleIterator(
240 ContentSettingsType content_type,
241 const ResourceIdentifier& resource_identifier,
242 bool incognito) const {
243 return value_map_.GetRuleIterator(content_type, resource_identifier, &lock_);
246 void PolicyProvider::GetContentSettingsFromPreferences(
247 OriginIdentifierValueMap* value_map) {
248 for (size_t i = 0; i < arraysize(kPrefsForManagedContentSettingsMap); ++i) {
249 const char* pref_name = kPrefsForManagedContentSettingsMap[i].pref_name;
250 // Skip unset policies.
251 if (!prefs_->HasPrefPath(pref_name)) {
252 VLOG(2) << "Skipping unset preference: " << pref_name;
253 continue;
256 const PrefService::Preference* pref = prefs_->FindPreference(pref_name);
257 DCHECK(pref);
258 DCHECK(pref->IsManaged());
260 const base::ListValue* pattern_str_list = NULL;
261 if (!pref->GetValue()->GetAsList(&pattern_str_list)) {
262 NOTREACHED();
263 return;
266 for (size_t j = 0; j < pattern_str_list->GetSize(); ++j) {
267 std::string original_pattern_str;
268 if (!pattern_str_list->GetString(j, &original_pattern_str)) {
269 NOTREACHED();
270 continue;
273 PatternPair pattern_pair = ParsePatternString(original_pattern_str);
274 // Ignore invalid patterns.
275 if (!pattern_pair.first.IsValid()) {
276 VLOG(1) << "Ignoring invalid content settings pattern: " <<
277 original_pattern_str;
278 continue;
281 ContentSettingsType content_type =
282 kPrefsForManagedContentSettingsMap[i].content_type;
283 DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE);
284 // If only one pattern was defined auto expand it to a pattern pair.
285 ContentSettingsPattern secondary_pattern =
286 !pattern_pair.second.IsValid() ? ContentSettingsPattern::Wildcard()
287 : pattern_pair.second;
288 value_map->SetValue(
289 pattern_pair.first,
290 secondary_pattern,
291 content_type,
292 NO_RESOURCE_IDENTIFIER,
293 base::Value::CreateIntegerValue(
294 kPrefsForManagedContentSettingsMap[i].setting));
299 void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences(
300 OriginIdentifierValueMap* value_map) {
301 const char* pref_name = prefs::kManagedAutoSelectCertificateForUrls;
303 if (!prefs_->HasPrefPath(pref_name)) {
304 VLOG(2) << "Skipping unset preference: " << pref_name;
305 return;
308 const PrefService::Preference* pref = prefs_->FindPreference(pref_name);
309 DCHECK(pref);
310 DCHECK(pref->IsManaged());
312 const base::ListValue* pattern_filter_str_list = NULL;
313 if (!pref->GetValue()->GetAsList(&pattern_filter_str_list)) {
314 NOTREACHED();
315 return;
318 // Parse the list of pattern filter strings. A pattern filter string has
319 // the following JSON format:
321 // {
322 // "pattern": <content settings pattern string>,
323 // "filter" : <certificate filter in JSON format>
324 // }
326 // e.g.
327 // {
328 // "pattern": "[*.]example.com",
329 // "filter": {
330 // "ISSUER": {
331 // "CN": "some name"
332 // }
333 // }
334 // }
335 for (size_t j = 0; j < pattern_filter_str_list->GetSize(); ++j) {
336 std::string pattern_filter_json;
337 if (!pattern_filter_str_list->GetString(j, &pattern_filter_json)) {
338 NOTREACHED();
339 continue;
342 scoped_ptr<base::Value> value(base::JSONReader::Read(pattern_filter_json,
343 base::JSON_ALLOW_TRAILING_COMMAS));
344 if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) {
345 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
346 " Invalid JSON object: " << pattern_filter_json;
347 continue;
350 scoped_ptr<base::DictionaryValue> pattern_filter_pair(
351 static_cast<base::DictionaryValue*>(value.release()));
352 std::string pattern_str;
353 bool pattern_read = pattern_filter_pair->GetString("pattern", &pattern_str);
354 scoped_ptr<base::Value> cert_filter;
355 bool filter_read = pattern_filter_pair->Remove("filter", &cert_filter);
356 if (!pattern_read || !filter_read ||
357 !cert_filter->IsType(base::Value::TYPE_DICTIONARY)) {
358 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
359 " Missing pattern or filter.";
360 continue;
363 ContentSettingsPattern pattern =
364 ContentSettingsPattern::FromString(pattern_str);
365 // Ignore invalid patterns.
366 if (!pattern.IsValid()) {
367 VLOG(1) << "Ignoring invalid certificate auto select setting:"
368 " Invalid content settings pattern: " << pattern;
369 continue;
372 value_map->SetValue(pattern,
373 ContentSettingsPattern::Wildcard(),
374 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
375 std::string(),
376 cert_filter.release());
380 void PolicyProvider::ReadManagedDefaultSettings() {
381 for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) {
382 if (kPrefToManageType[type] == NULL) {
383 continue;
385 UpdateManagedDefaultSetting(ContentSettingsType(type));
389 void PolicyProvider::UpdateManagedDefaultSetting(
390 ContentSettingsType content_type) {
391 // If a pref to manage a default-content-setting was not set (NOTICE:
392 // "HasPrefPath" returns false if no value was set for a registered pref) then
393 // the default value of the preference is used. The default value of a
394 // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
395 // This indicates that no managed value is set. If a pref was set, than it
396 // MUST be managed.
397 DCHECK(!prefs_->HasPrefPath(kPrefToManageType[content_type]) ||
398 prefs_->IsManagedPreference(kPrefToManageType[content_type]));
399 base::AutoLock auto_lock(lock_);
401 int setting = prefs_->GetInteger(kPrefToManageType[content_type]);
402 if (setting == CONTENT_SETTING_DEFAULT) {
403 value_map_.DeleteValue(
404 ContentSettingsPattern::Wildcard(),
405 ContentSettingsPattern::Wildcard(),
406 content_type,
407 std::string());
408 } else {
409 value_map_.SetValue(
410 ContentSettingsPattern::Wildcard(),
411 ContentSettingsPattern::Wildcard(),
412 content_type,
413 std::string(),
414 base::Value::CreateIntegerValue(setting));
419 void PolicyProvider::ReadManagedContentSettings(bool overwrite) {
420 base::AutoLock auto_lock(lock_);
421 if (overwrite)
422 value_map_.clear();
423 GetContentSettingsFromPreferences(&value_map_);
424 GetAutoSelectCertificateSettingsFromPreferences(&value_map_);
427 // Since the PolicyProvider is a read only content settings provider, all
428 // methodes of the ProviderInterface that set or delete any settings do nothing.
429 bool PolicyProvider::SetWebsiteSetting(
430 const ContentSettingsPattern& primary_pattern,
431 const ContentSettingsPattern& secondary_pattern,
432 ContentSettingsType content_type,
433 const ResourceIdentifier& resource_identifier,
434 base::Value* value) {
435 return false;
438 void PolicyProvider::ClearAllContentSettingsRules(
439 ContentSettingsType content_type) {
442 void PolicyProvider::ShutdownOnUIThread() {
443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
444 RemoveAllObservers();
445 if (!prefs_)
446 return;
447 pref_change_registrar_.RemoveAll();
448 prefs_ = NULL;
451 void PolicyProvider::OnPreferenceChanged(const std::string& name) {
452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
454 if (name == prefs::kManagedDefaultCookiesSetting) {
455 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES);
456 } else if (name == prefs::kManagedDefaultImagesSetting) {
457 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES);
458 } else if (name == prefs::kManagedDefaultJavaScriptSetting) {
459 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
460 } else if (name == prefs::kManagedDefaultPluginsSetting) {
461 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS);
462 } else if (name == prefs::kManagedDefaultPopupsSetting) {
463 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS);
464 } else if (name == prefs::kManagedDefaultGeolocationSetting) {
465 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION);
466 } else if (name == prefs::kManagedDefaultNotificationsSetting) {
467 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
468 } else if (name == prefs::kManagedDefaultMediaStreamSetting) {
469 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM);
470 } else if (name == prefs::kManagedAutoSelectCertificateForUrls ||
471 name == prefs::kManagedCookiesAllowedForUrls ||
472 name == prefs::kManagedCookiesBlockedForUrls ||
473 name == prefs::kManagedCookiesSessionOnlyForUrls ||
474 name == prefs::kManagedImagesAllowedForUrls ||
475 name == prefs::kManagedImagesBlockedForUrls ||
476 name == prefs::kManagedJavaScriptAllowedForUrls ||
477 name == prefs::kManagedJavaScriptBlockedForUrls ||
478 name == prefs::kManagedPluginsAllowedForUrls ||
479 name == prefs::kManagedPluginsBlockedForUrls ||
480 name == prefs::kManagedPopupsAllowedForUrls ||
481 name == prefs::kManagedPopupsBlockedForUrls ||
482 name == prefs::kManagedNotificationsAllowedForUrls ||
483 name == prefs::kManagedNotificationsBlockedForUrls) {
484 ReadManagedContentSettings(true);
485 ReadManagedDefaultSettings();
488 NotifyObservers(ContentSettingsPattern(),
489 ContentSettingsPattern(),
490 CONTENT_SETTINGS_TYPE_DEFAULT,
491 std::string());
494 } // namespace content_settings