Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / content_settings / content_settings_policy_provider.cc
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 #include "chrome/browser/content_settings/content_settings_policy_provider.h"
6
7 #include <string>
8 #include <vector>
9
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"
22
23 using content::BrowserThread;
24
25 namespace {
26
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
52 #if defined(OS_ANDROID)
53   NULL,  // No policy for default value of app banners
54 #endif
55 };
56 COMPILE_ASSERT(arraysize(kPrefToManageType) == CONTENT_SETTINGS_NUM_TYPES,
57                managed_content_settings_pref_names_array_size_incorrect);
58
59 struct PrefsForManagedContentSettingsMapEntry {
60   const char* pref_name;
61   ContentSettingsType content_type;
62   ContentSetting setting;
63 };
64
65 const PrefsForManagedContentSettingsMapEntry
66     kPrefsForManagedContentSettingsMap[] = {
67   {
68     prefs::kManagedCookiesAllowedForUrls,
69     CONTENT_SETTINGS_TYPE_COOKIES,
70     CONTENT_SETTING_ALLOW
71   }, {
72     prefs::kManagedCookiesSessionOnlyForUrls,
73     CONTENT_SETTINGS_TYPE_COOKIES,
74     CONTENT_SETTING_SESSION_ONLY
75   }, {
76     prefs::kManagedCookiesBlockedForUrls,
77     CONTENT_SETTINGS_TYPE_COOKIES,
78     CONTENT_SETTING_BLOCK
79   }, {
80     prefs::kManagedImagesAllowedForUrls,
81     CONTENT_SETTINGS_TYPE_IMAGES,
82     CONTENT_SETTING_ALLOW
83   }, {
84     prefs::kManagedImagesBlockedForUrls,
85     CONTENT_SETTINGS_TYPE_IMAGES,
86     CONTENT_SETTING_BLOCK
87   }, {
88     prefs::kManagedJavaScriptAllowedForUrls,
89     CONTENT_SETTINGS_TYPE_JAVASCRIPT,
90     CONTENT_SETTING_ALLOW
91   }, {
92     prefs::kManagedJavaScriptBlockedForUrls,
93     CONTENT_SETTINGS_TYPE_JAVASCRIPT,
94     CONTENT_SETTING_BLOCK
95   }, {
96     prefs::kManagedPluginsAllowedForUrls,
97     CONTENT_SETTINGS_TYPE_PLUGINS,
98     CONTENT_SETTING_ALLOW
99   }, {
100     prefs::kManagedPluginsBlockedForUrls,
101     CONTENT_SETTINGS_TYPE_PLUGINS,
102     CONTENT_SETTING_BLOCK
103   }, {
104     prefs::kManagedPopupsAllowedForUrls,
105     CONTENT_SETTINGS_TYPE_POPUPS,
106     CONTENT_SETTING_ALLOW
107   }, {
108     prefs::kManagedPopupsBlockedForUrls,
109     CONTENT_SETTINGS_TYPE_POPUPS,
110     CONTENT_SETTING_BLOCK
111   }, {
112     prefs::kManagedNotificationsAllowedForUrls,
113     CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
114     CONTENT_SETTING_ALLOW
115   }, {
116     prefs::kManagedNotificationsBlockedForUrls,
117     CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
118     CONTENT_SETTING_BLOCK
119   }
120 };
121
122 }  // namespace
123
124 namespace content_settings {
125
126 // static
127 void PolicyProvider::RegisterProfilePrefs(
128     user_prefs::PrefRegistrySyncable* registry) {
129   registry->RegisterListPref(prefs::kManagedAutoSelectCertificateForUrls,
130                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
131   registry->RegisterListPref(prefs::kManagedCookiesAllowedForUrls,
132                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
133   registry->RegisterListPref(prefs::kManagedCookiesBlockedForUrls,
134                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
135   registry->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls,
136                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
137   registry->RegisterListPref(prefs::kManagedImagesAllowedForUrls,
138                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
139   registry->RegisterListPref(prefs::kManagedImagesBlockedForUrls,
140                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
141   registry->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls,
142                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
143   registry->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls,
144                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
145   registry->RegisterListPref(prefs::kManagedPluginsAllowedForUrls,
146                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
147   registry->RegisterListPref(prefs::kManagedPluginsBlockedForUrls,
148                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
149   registry->RegisterListPref(prefs::kManagedPopupsAllowedForUrls,
150                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
151   registry->RegisterListPref(prefs::kManagedPopupsBlockedForUrls,
152                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
153   registry->RegisterListPref(prefs::kManagedNotificationsAllowedForUrls,
154                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
155   registry->RegisterListPref(prefs::kManagedNotificationsBlockedForUrls,
156                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
157   // Preferences for default content setting policies. If a policy is not set of
158   // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
159   registry->RegisterIntegerPref(
160       prefs::kManagedDefaultCookiesSetting,
161       CONTENT_SETTING_DEFAULT,
162       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
163   registry->RegisterIntegerPref(
164       prefs::kManagedDefaultImagesSetting,
165       CONTENT_SETTING_DEFAULT,
166       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
167   registry->RegisterIntegerPref(
168       prefs::kManagedDefaultJavaScriptSetting,
169       CONTENT_SETTING_DEFAULT,
170       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
171   registry->RegisterIntegerPref(
172       prefs::kManagedDefaultPluginsSetting,
173       CONTENT_SETTING_DEFAULT,
174       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
175   registry->RegisterIntegerPref(
176       prefs::kManagedDefaultPopupsSetting,
177       CONTENT_SETTING_DEFAULT,
178       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
179   registry->RegisterIntegerPref(
180       prefs::kManagedDefaultGeolocationSetting,
181       CONTENT_SETTING_DEFAULT,
182       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
183   registry->RegisterIntegerPref(
184       prefs::kManagedDefaultNotificationsSetting,
185       CONTENT_SETTING_DEFAULT,
186       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
187   registry->RegisterIntegerPref(
188       prefs::kManagedDefaultMediaStreamSetting,
189       CONTENT_SETTING_DEFAULT,
190       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
191 }
192
193 PolicyProvider::PolicyProvider(PrefService* prefs) : prefs_(prefs) {
194   ReadManagedDefaultSettings();
195   ReadManagedContentSettings(false);
196
197   pref_change_registrar_.Init(prefs_);
198   PrefChangeRegistrar::NamedChangeCallback callback =
199       base::Bind(&PolicyProvider::OnPreferenceChanged, base::Unretained(this));
200   pref_change_registrar_.Add(
201       prefs::kManagedAutoSelectCertificateForUrls, callback);
202   pref_change_registrar_.Add(prefs::kManagedCookiesBlockedForUrls, callback);
203   pref_change_registrar_.Add(prefs::kManagedCookiesAllowedForUrls, callback);
204   pref_change_registrar_.Add(
205       prefs::kManagedCookiesSessionOnlyForUrls, callback);
206   pref_change_registrar_.Add(prefs::kManagedImagesBlockedForUrls, callback);
207   pref_change_registrar_.Add(prefs::kManagedImagesAllowedForUrls, callback);
208   pref_change_registrar_.Add(prefs::kManagedJavaScriptBlockedForUrls, callback);
209   pref_change_registrar_.Add(prefs::kManagedJavaScriptAllowedForUrls, callback);
210   pref_change_registrar_.Add(prefs::kManagedPluginsBlockedForUrls, callback);
211   pref_change_registrar_.Add(prefs::kManagedPluginsAllowedForUrls, callback);
212   pref_change_registrar_.Add(prefs::kManagedPopupsBlockedForUrls, callback);
213   pref_change_registrar_.Add(prefs::kManagedPopupsAllowedForUrls, callback);
214   pref_change_registrar_.Add(
215       prefs::kManagedNotificationsAllowedForUrls, callback);
216   pref_change_registrar_.Add(
217       prefs::kManagedNotificationsBlockedForUrls, callback);
218   // The following preferences are only used to indicate if a
219   // default content setting is managed and to hold the managed default setting
220   // value. If the value for any of the following perferences is set then the
221   // corresponding default content setting is managed. These preferences exist
222   // in parallel to the preference default content settings.  If a
223   // default content settings type is managed any user defined excpetions
224   // (patterns) for this type are ignored.
225   pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, callback);
226   pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, callback);
227   pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, callback);
228   pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, callback);
229   pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, callback);
230   pref_change_registrar_.Add(
231       prefs::kManagedDefaultGeolocationSetting, callback);
232   pref_change_registrar_.Add(
233       prefs::kManagedDefaultNotificationsSetting, callback);
234   pref_change_registrar_.Add(
235       prefs::kManagedDefaultMediaStreamSetting, callback);
236 }
237
238 PolicyProvider::~PolicyProvider() {
239   DCHECK(!prefs_);
240 }
241
242 RuleIterator* PolicyProvider::GetRuleIterator(
243     ContentSettingsType content_type,
244     const ResourceIdentifier& resource_identifier,
245     bool incognito) const {
246   return value_map_.GetRuleIterator(content_type, resource_identifier, &lock_);
247 }
248
249 void PolicyProvider::GetContentSettingsFromPreferences(
250     OriginIdentifierValueMap* value_map) {
251   for (size_t i = 0; i < arraysize(kPrefsForManagedContentSettingsMap); ++i) {
252     const char* pref_name = kPrefsForManagedContentSettingsMap[i].pref_name;
253     // Skip unset policies.
254     if (!prefs_->HasPrefPath(pref_name)) {
255       VLOG(2) << "Skipping unset preference: " << pref_name;
256       continue;
257     }
258
259     const PrefService::Preference* pref = prefs_->FindPreference(pref_name);
260     DCHECK(pref);
261     DCHECK(pref->IsManaged());
262
263     const base::ListValue* pattern_str_list = NULL;
264     if (!pref->GetValue()->GetAsList(&pattern_str_list)) {
265       NOTREACHED();
266       return;
267     }
268
269     for (size_t j = 0; j < pattern_str_list->GetSize(); ++j) {
270       std::string original_pattern_str;
271       if (!pattern_str_list->GetString(j, &original_pattern_str)) {
272         NOTREACHED();
273         continue;
274       }
275
276       PatternPair pattern_pair = ParsePatternString(original_pattern_str);
277       // Ignore invalid patterns.
278       if (!pattern_pair.first.IsValid()) {
279         VLOG(1) << "Ignoring invalid content settings pattern: " <<
280                    original_pattern_str;
281         continue;
282       }
283
284       ContentSettingsType content_type =
285           kPrefsForManagedContentSettingsMap[i].content_type;
286       DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE);
287       // If only one pattern was defined auto expand it to a pattern pair.
288       ContentSettingsPattern secondary_pattern =
289           !pattern_pair.second.IsValid() ? ContentSettingsPattern::Wildcard()
290                                          : pattern_pair.second;
291       value_map->SetValue(
292           pattern_pair.first,
293           secondary_pattern,
294           content_type,
295           NO_RESOURCE_IDENTIFIER,
296           base::Value::CreateIntegerValue(
297               kPrefsForManagedContentSettingsMap[i].setting));
298     }
299   }
300 }
301
302 void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences(
303     OriginIdentifierValueMap* value_map) {
304   const char* pref_name = prefs::kManagedAutoSelectCertificateForUrls;
305
306   if (!prefs_->HasPrefPath(pref_name)) {
307     VLOG(2) << "Skipping unset preference: " << pref_name;
308     return;
309   }
310
311   const PrefService::Preference* pref = prefs_->FindPreference(pref_name);
312   DCHECK(pref);
313   DCHECK(pref->IsManaged());
314
315   const base::ListValue* pattern_filter_str_list = NULL;
316   if (!pref->GetValue()->GetAsList(&pattern_filter_str_list)) {
317     NOTREACHED();
318     return;
319   }
320
321   // Parse the list of pattern filter strings. A pattern filter string has
322   // the following JSON format:
323   //
324   // {
325   //   "pattern": <content settings pattern string>,
326   //   "filter" : <certificate filter in JSON format>
327   // }
328   //
329   // e.g.
330   // {
331   //   "pattern": "[*.]example.com",
332   //   "filter": {
333   //      "ISSUER": {
334   //        "CN": "some name"
335   //      }
336   //   }
337   // }
338   for (size_t j = 0; j < pattern_filter_str_list->GetSize(); ++j) {
339     std::string pattern_filter_json;
340     if (!pattern_filter_str_list->GetString(j, &pattern_filter_json)) {
341       NOTREACHED();
342       continue;
343     }
344
345     scoped_ptr<base::Value> value(base::JSONReader::Read(pattern_filter_json,
346         base::JSON_ALLOW_TRAILING_COMMAS));
347     if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) {
348       VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
349                  " Invalid JSON object: " << pattern_filter_json;
350       continue;
351     }
352
353     scoped_ptr<base::DictionaryValue> pattern_filter_pair(
354         static_cast<base::DictionaryValue*>(value.release()));
355     std::string pattern_str;
356     bool pattern_read = pattern_filter_pair->GetString("pattern", &pattern_str);
357     scoped_ptr<base::Value> cert_filter;
358     bool filter_read = pattern_filter_pair->Remove("filter", &cert_filter);
359     if (!pattern_read || !filter_read ||
360         !cert_filter->IsType(base::Value::TYPE_DICTIONARY)) {
361       VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
362                  " Missing pattern or filter.";
363       continue;
364     }
365
366     ContentSettingsPattern pattern =
367         ContentSettingsPattern::FromString(pattern_str);
368     // Ignore invalid patterns.
369     if (!pattern.IsValid()) {
370       VLOG(1) << "Ignoring invalid certificate auto select setting:"
371                  " Invalid content settings pattern: " << pattern;
372       continue;
373     }
374
375     value_map->SetValue(pattern,
376                         ContentSettingsPattern::Wildcard(),
377                         CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
378                         std::string(),
379                         cert_filter.release());
380   }
381 }
382
383 void PolicyProvider::ReadManagedDefaultSettings() {
384   for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) {
385     if (kPrefToManageType[type] == NULL) {
386       continue;
387     }
388     UpdateManagedDefaultSetting(ContentSettingsType(type));
389   }
390 }
391
392 void PolicyProvider::UpdateManagedDefaultSetting(
393     ContentSettingsType content_type) {
394   // If a pref to manage a default-content-setting was not set (NOTICE:
395   // "HasPrefPath" returns false if no value was set for a registered pref) then
396   // the default value of the preference is used. The default value of a
397   // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
398   // This indicates that no managed value is set. If a pref was set, than it
399   // MUST be managed.
400   DCHECK(!prefs_->HasPrefPath(kPrefToManageType[content_type]) ||
401           prefs_->IsManagedPreference(kPrefToManageType[content_type]));
402   base::AutoLock auto_lock(lock_);
403
404   int setting = prefs_->GetInteger(kPrefToManageType[content_type]);
405   if (setting == CONTENT_SETTING_DEFAULT) {
406     value_map_.DeleteValue(
407         ContentSettingsPattern::Wildcard(),
408         ContentSettingsPattern::Wildcard(),
409         content_type,
410         std::string());
411   } else {
412     value_map_.SetValue(
413         ContentSettingsPattern::Wildcard(),
414         ContentSettingsPattern::Wildcard(),
415         content_type,
416         std::string(),
417         base::Value::CreateIntegerValue(setting));
418   }
419 }
420
421
422 void PolicyProvider::ReadManagedContentSettings(bool overwrite) {
423   base::AutoLock auto_lock(lock_);
424   if (overwrite)
425     value_map_.clear();
426   GetContentSettingsFromPreferences(&value_map_);
427   GetAutoSelectCertificateSettingsFromPreferences(&value_map_);
428 }
429
430 // Since the PolicyProvider is a read only content settings provider, all
431 // methodes of the ProviderInterface that set or delete any settings do nothing.
432 bool PolicyProvider::SetWebsiteSetting(
433     const ContentSettingsPattern& primary_pattern,
434     const ContentSettingsPattern& secondary_pattern,
435     ContentSettingsType content_type,
436     const ResourceIdentifier& resource_identifier,
437     base::Value* value) {
438   return false;
439 }
440
441 void PolicyProvider::ClearAllContentSettingsRules(
442     ContentSettingsType content_type) {
443 }
444
445 void PolicyProvider::ShutdownOnUIThread() {
446   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
447   RemoveAllObservers();
448   if (!prefs_)
449     return;
450   pref_change_registrar_.RemoveAll();
451   prefs_ = NULL;
452 }
453
454 void PolicyProvider::OnPreferenceChanged(const std::string& name) {
455   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
456
457   if (name == prefs::kManagedDefaultCookiesSetting) {
458     UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES);
459   } else if (name == prefs::kManagedDefaultImagesSetting) {
460     UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES);
461   } else if (name == prefs::kManagedDefaultJavaScriptSetting) {
462     UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
463   } else if (name == prefs::kManagedDefaultPluginsSetting) {
464     UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS);
465   } else if (name == prefs::kManagedDefaultPopupsSetting) {
466     UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS);
467   } else if (name == prefs::kManagedDefaultGeolocationSetting) {
468     UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION);
469   } else if (name == prefs::kManagedDefaultNotificationsSetting) {
470     UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
471   } else if (name == prefs::kManagedDefaultMediaStreamSetting) {
472     UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM);
473   } else if (name == prefs::kManagedAutoSelectCertificateForUrls ||
474              name == prefs::kManagedCookiesAllowedForUrls ||
475              name == prefs::kManagedCookiesBlockedForUrls ||
476              name == prefs::kManagedCookiesSessionOnlyForUrls ||
477              name == prefs::kManagedImagesAllowedForUrls ||
478              name == prefs::kManagedImagesBlockedForUrls ||
479              name == prefs::kManagedJavaScriptAllowedForUrls ||
480              name == prefs::kManagedJavaScriptBlockedForUrls ||
481              name == prefs::kManagedPluginsAllowedForUrls ||
482              name == prefs::kManagedPluginsBlockedForUrls ||
483              name == prefs::kManagedPopupsAllowedForUrls ||
484              name == prefs::kManagedPopupsBlockedForUrls ||
485              name == prefs::kManagedNotificationsAllowedForUrls ||
486              name == prefs::kManagedNotificationsBlockedForUrls) {
487     ReadManagedContentSettings(true);
488     ReadManagedDefaultSettings();
489   }
490
491   NotifyObservers(ContentSettingsPattern(),
492                   ContentSettingsPattern(),
493                   CONTENT_SETTINGS_TYPE_DEFAULT,
494                   std::string());
495 }
496
497 }  // namespace content_settings