Home | History | Annotate | Download | only in content_settings
      1 // Copyright (c) 2011 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/command_line.h"
     11 #include "chrome/browser/content_settings/content_settings_details.h"
     12 #include "chrome/browser/content_settings/content_settings_pattern.h"
     13 #include "chrome/browser/prefs/pref_service.h"
     14 #include "chrome/browser/prefs/scoped_user_pref_update.h"
     15 #include "chrome/browser/profiles/profile.h"
     16 #include "chrome/common/pref_names.h"
     17 #include "content/browser/browser_thread.h"
     18 #include "content/common/notification_details.h"
     19 #include "content/common/notification_service.h"
     20 #include "content/common/notification_source.h"
     21 #include "webkit/plugins/npapi/plugin_group.h"
     22 #include "webkit/plugins/npapi/plugin_list.h"
     23 
     24 namespace {
     25 
     26 // Base pref path of the prefs that contain the managed default content
     27 // settings values.
     28 const std::string kManagedSettings =
     29       "profile.managed_default_content_settings";
     30 
     31 // The preferences used to manage ContentSettingsTypes.
     32 const char* kPrefToManageType[CONTENT_SETTINGS_NUM_TYPES] = {
     33   prefs::kManagedDefaultCookiesSetting,
     34   prefs::kManagedDefaultImagesSetting,
     35   prefs::kManagedDefaultJavaScriptSetting,
     36   prefs::kManagedDefaultPluginsSetting,
     37   prefs::kManagedDefaultPopupsSetting,
     38   NULL,  // Not used for Geolocation
     39   NULL,  // Not used for Notifications
     40 };
     41 
     42 struct PrefsForManagedContentSettingsMapEntry {
     43   const char* pref_name;
     44   ContentSettingsType content_type;
     45   ContentSetting setting;
     46 };
     47 
     48 const PrefsForManagedContentSettingsMapEntry
     49     kPrefsForManagedContentSettingsMap[] = {
     50   {
     51     prefs::kManagedCookiesAllowedForUrls,
     52     CONTENT_SETTINGS_TYPE_COOKIES,
     53     CONTENT_SETTING_ALLOW
     54   }, {
     55     prefs::kManagedCookiesSessionOnlyForUrls,
     56     CONTENT_SETTINGS_TYPE_COOKIES,
     57     CONTENT_SETTING_SESSION_ONLY
     58   }, {
     59     prefs::kManagedCookiesBlockedForUrls,
     60     CONTENT_SETTINGS_TYPE_COOKIES,
     61     CONTENT_SETTING_BLOCK
     62   }, {
     63     prefs::kManagedImagesAllowedForUrls,
     64     CONTENT_SETTINGS_TYPE_IMAGES,
     65     CONTENT_SETTING_ALLOW
     66   }, {
     67     prefs::kManagedImagesBlockedForUrls,
     68     CONTENT_SETTINGS_TYPE_IMAGES,
     69     CONTENT_SETTING_BLOCK
     70   }, {
     71     prefs::kManagedJavaScriptAllowedForUrls,
     72     CONTENT_SETTINGS_TYPE_JAVASCRIPT,
     73     CONTENT_SETTING_ALLOW
     74   }, {
     75     prefs::kManagedJavaScriptBlockedForUrls,
     76     CONTENT_SETTINGS_TYPE_JAVASCRIPT,
     77     CONTENT_SETTING_BLOCK
     78   }, {
     79     prefs::kManagedPluginsAllowedForUrls,
     80     CONTENT_SETTINGS_TYPE_PLUGINS,
     81     CONTENT_SETTING_ALLOW
     82   }, {
     83     prefs::kManagedPluginsBlockedForUrls,
     84     CONTENT_SETTINGS_TYPE_PLUGINS,
     85     CONTENT_SETTING_BLOCK
     86   }, {
     87     prefs::kManagedPopupsAllowedForUrls,
     88     CONTENT_SETTINGS_TYPE_POPUPS,
     89     CONTENT_SETTING_ALLOW
     90   }, {
     91     prefs::kManagedPopupsBlockedForUrls,
     92     CONTENT_SETTINGS_TYPE_POPUPS,
     93     CONTENT_SETTING_BLOCK
     94   }
     95 };
     96 
     97 }  // namespace
     98 
     99 namespace content_settings {
    100 
    101 PolicyDefaultProvider::PolicyDefaultProvider(Profile* profile)
    102     : profile_(profile),
    103       is_off_the_record_(profile_->IsOffTheRecord()) {
    104   PrefService* prefs = profile->GetPrefs();
    105 
    106   // Read global defaults.
    107   DCHECK_EQ(arraysize(kPrefToManageType),
    108             static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
    109   ReadManagedDefaultSettings();
    110 
    111   pref_change_registrar_.Init(prefs);
    112   // The following preferences are only used to indicate if a
    113   // default-content-setting is managed and to hold the managed default-setting
    114   // value. If the value for any of the following perferences is set then the
    115   // corresponding default-content-setting is managed. These preferences exist
    116   // in parallel to the preference default-content-settings.  If a
    117   // default-content-settings-type is managed any user defined excpetions
    118   // (patterns) for this type are ignored.
    119   pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this);
    120   pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this);
    121   pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this);
    122   pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this);
    123   pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this);
    124   notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
    125                               Source<Profile>(profile_));
    126 }
    127 
    128 PolicyDefaultProvider::~PolicyDefaultProvider() {
    129   UnregisterObservers();
    130 }
    131 
    132 ContentSetting PolicyDefaultProvider::ProvideDefaultSetting(
    133     ContentSettingsType content_type) const {
    134   base::AutoLock auto_lock(lock_);
    135   return managed_default_content_settings_.settings[content_type];
    136 }
    137 
    138 void PolicyDefaultProvider::UpdateDefaultSetting(
    139     ContentSettingsType content_type,
    140     ContentSetting setting) {
    141 }
    142 
    143 bool PolicyDefaultProvider::DefaultSettingIsManaged(
    144     ContentSettingsType content_type) const {
    145   base::AutoLock lock(lock_);
    146   if (managed_default_content_settings_.settings[content_type] !=
    147       CONTENT_SETTING_DEFAULT) {
    148     return true;
    149   } else {
    150     return false;
    151   }
    152 }
    153 
    154 void PolicyDefaultProvider::ResetToDefaults() {
    155 }
    156 
    157 void PolicyDefaultProvider::Observe(NotificationType type,
    158                                     const NotificationSource& source,
    159                                     const NotificationDetails& details) {
    160   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    161 
    162   if (type == NotificationType::PREF_CHANGED) {
    163     DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
    164     std::string* name = Details<std::string>(details).ptr();
    165     if (*name == prefs::kManagedDefaultCookiesSetting) {
    166       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES);
    167     } else if (*name == prefs::kManagedDefaultImagesSetting) {
    168       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES);
    169     } else if (*name == prefs::kManagedDefaultJavaScriptSetting) {
    170       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
    171     } else if (*name == prefs::kManagedDefaultPluginsSetting) {
    172       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS);
    173     } else if (*name == prefs::kManagedDefaultPopupsSetting) {
    174       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS);
    175     } else {
    176       NOTREACHED() << "Unexpected preference observed";
    177       return;
    178     }
    179 
    180     if (!is_off_the_record_) {
    181       NotifyObservers(ContentSettingsDetails(
    182             ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, ""));
    183     }
    184   } else if (type == NotificationType::PROFILE_DESTROYED) {
    185     DCHECK_EQ(profile_, Source<Profile>(source).ptr());
    186     UnregisterObservers();
    187   } else {
    188     NOTREACHED() << "Unexpected notification";
    189   }
    190 }
    191 
    192 void PolicyDefaultProvider::UnregisterObservers() {
    193   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    194   if (!profile_)
    195     return;
    196   pref_change_registrar_.RemoveAll();
    197   notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
    198                                  Source<Profile>(profile_));
    199   profile_ = NULL;
    200 }
    201 
    202 
    203 void PolicyDefaultProvider::NotifyObservers(
    204     const ContentSettingsDetails& details) {
    205   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    206   if (profile_ == NULL)
    207     return;
    208   NotificationService::current()->Notify(
    209       NotificationType::CONTENT_SETTINGS_CHANGED,
    210       Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()),
    211       Details<const ContentSettingsDetails>(&details));
    212 }
    213 
    214 void PolicyDefaultProvider::ReadManagedDefaultSettings() {
    215   for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) {
    216     if (kPrefToManageType[type] == NULL) {
    217       continue;
    218     }
    219     UpdateManagedDefaultSetting(ContentSettingsType(type));
    220   }
    221 }
    222 
    223 void PolicyDefaultProvider::UpdateManagedDefaultSetting(
    224     ContentSettingsType type) {
    225   // If a pref to manage a default-content-setting was not set (NOTICE:
    226   // "HasPrefPath" returns false if no value was set for a registered pref) then
    227   // the default value of the preference is used. The default value of a
    228   // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
    229   // This indicates that no managed value is set. If a pref was set, than it
    230   // MUST be managed.
    231   PrefService* prefs = profile_->GetPrefs();
    232   DCHECK(!prefs->HasPrefPath(kPrefToManageType[type]) ||
    233           prefs->IsManagedPreference(kPrefToManageType[type]));
    234   base::AutoLock auto_lock(lock_);
    235   managed_default_content_settings_.settings[type] = IntToContentSetting(
    236       prefs->GetInteger(kPrefToManageType[type]));
    237 }
    238 
    239 // static
    240 void PolicyDefaultProvider::RegisterUserPrefs(PrefService* prefs) {
    241   // Preferences for default content setting policies. A policy is not set of
    242   // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
    243   prefs->RegisterIntegerPref(prefs::kManagedDefaultCookiesSetting,
    244       CONTENT_SETTING_DEFAULT);
    245   prefs->RegisterIntegerPref(prefs::kManagedDefaultImagesSetting,
    246       CONTENT_SETTING_DEFAULT);
    247   prefs->RegisterIntegerPref(prefs::kManagedDefaultJavaScriptSetting,
    248       CONTENT_SETTING_DEFAULT);
    249   prefs->RegisterIntegerPref(prefs::kManagedDefaultPluginsSetting,
    250       CONTENT_SETTING_DEFAULT);
    251   prefs->RegisterIntegerPref(prefs::kManagedDefaultPopupsSetting,
    252       CONTENT_SETTING_DEFAULT);
    253 }
    254 
    255 // ////////////////////////////////////////////////////////////////////////////
    256 // PolicyProvider
    257 
    258 // static
    259 void PolicyProvider::RegisterUserPrefs(PrefService* prefs) {
    260   prefs->RegisterListPref(prefs::kManagedCookiesAllowedForUrls);
    261   prefs->RegisterListPref(prefs::kManagedCookiesBlockedForUrls);
    262   prefs->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls);
    263   prefs->RegisterListPref(prefs::kManagedImagesAllowedForUrls);
    264   prefs->RegisterListPref(prefs::kManagedImagesBlockedForUrls);
    265   prefs->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls);
    266   prefs->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls);
    267   prefs->RegisterListPref(prefs::kManagedPluginsAllowedForUrls);
    268   prefs->RegisterListPref(prefs::kManagedPluginsBlockedForUrls);
    269   prefs->RegisterListPref(prefs::kManagedPopupsAllowedForUrls);
    270   prefs->RegisterListPref(prefs::kManagedPopupsBlockedForUrls);
    271 }
    272 
    273 PolicyProvider::PolicyProvider(Profile* profile)
    274     : BaseProvider(profile->IsOffTheRecord()),
    275       profile_(profile) {
    276   Init();
    277 }
    278 
    279 PolicyProvider::~PolicyProvider() {
    280   UnregisterObservers();
    281 }
    282 
    283 void PolicyProvider::ReadManagedContentSettingsTypes(
    284     ContentSettingsType content_type) {
    285   PrefService* prefs = profile_->GetPrefs();
    286   if (kPrefToManageType[content_type] == NULL) {
    287     content_type_is_managed_[content_type] = false;
    288   } else {
    289     content_type_is_managed_[content_type] =
    290          prefs->IsManagedPreference(kPrefToManageType[content_type]);
    291   }
    292 }
    293 
    294 void PolicyProvider::Init() {
    295   PrefService* prefs = profile_->GetPrefs();
    296 
    297   ReadManagedContentSettings(false);
    298   for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
    299     ReadManagedContentSettingsTypes(ContentSettingsType(i));
    300 
    301   pref_change_registrar_.Init(prefs);
    302   pref_change_registrar_.Add(prefs::kManagedCookiesBlockedForUrls, this);
    303   pref_change_registrar_.Add(prefs::kManagedCookiesAllowedForUrls, this);
    304   pref_change_registrar_.Add(prefs::kManagedCookiesSessionOnlyForUrls, this);
    305   pref_change_registrar_.Add(prefs::kManagedImagesBlockedForUrls, this);
    306   pref_change_registrar_.Add(prefs::kManagedImagesAllowedForUrls, this);
    307   pref_change_registrar_.Add(prefs::kManagedJavaScriptBlockedForUrls, this);
    308   pref_change_registrar_.Add(prefs::kManagedJavaScriptAllowedForUrls, this);
    309   pref_change_registrar_.Add(prefs::kManagedPluginsBlockedForUrls, this);
    310   pref_change_registrar_.Add(prefs::kManagedPluginsAllowedForUrls, this);
    311   pref_change_registrar_.Add(prefs::kManagedPopupsBlockedForUrls, this);
    312   pref_change_registrar_.Add(prefs::kManagedPopupsAllowedForUrls, this);
    313 
    314   pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this);
    315   pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this);
    316   pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this);
    317   pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this);
    318   pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this);
    319 
    320   notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
    321                               Source<Profile>(profile_));
    322 }
    323 
    324 bool PolicyProvider::ContentSettingsTypeIsManaged(
    325     ContentSettingsType content_type) {
    326   return content_type_is_managed_[content_type];
    327 }
    328 
    329 void PolicyProvider::GetContentSettingsFromPreferences(
    330     PrefService* prefs,
    331     ContentSettingsRules* rules) {
    332   for (size_t i = 0; i < arraysize(kPrefsForManagedContentSettingsMap); ++i) {
    333     const char* pref_name = kPrefsForManagedContentSettingsMap[i].pref_name;
    334     // Skip unset policies.
    335     if (!prefs->HasPrefPath(pref_name)) {
    336       VLOG(2) << "Skipping unset preference: " << pref_name;
    337       continue;
    338     }
    339 
    340     const PrefService::Preference* pref = prefs->FindPreference(pref_name);
    341     DCHECK(pref->IsManaged());
    342     DCHECK_EQ(Value::TYPE_LIST, pref->GetType());
    343 
    344     const ListValue* pattern_str_list =
    345         static_cast<const ListValue*>(pref->GetValue());
    346     for (size_t j = 0; j < pattern_str_list->GetSize(); ++j) {
    347       std::string original_pattern_str;
    348       pattern_str_list->GetString(j, &original_pattern_str);
    349       ContentSettingsPattern pattern(original_pattern_str);
    350       // Ignore invalid patterns.
    351       if (!pattern.IsValid()) {
    352         VLOG(1) << "Ignoring invalid content settings pattern: " <<
    353                    pattern.AsString();
    354         continue;
    355       }
    356       rules->push_back(MakeTuple(
    357           pattern,
    358           pattern,
    359           kPrefsForManagedContentSettingsMap[i].content_type,
    360           ProviderInterface::ResourceIdentifier(NO_RESOURCE_IDENTIFIER),
    361           kPrefsForManagedContentSettingsMap[i].setting));
    362     }
    363   }
    364 }
    365 
    366 void PolicyProvider::ReadManagedContentSettings(bool overwrite) {
    367   ContentSettingsRules rules;
    368   PrefService* prefs = profile_->GetPrefs();
    369   GetContentSettingsFromPreferences(prefs, &rules);
    370   {
    371     base::AutoLock auto_lock(lock());
    372     HostContentSettings* content_settings_map = host_content_settings();
    373     if (overwrite)
    374       content_settings_map->clear();
    375     for (ContentSettingsRules::iterator rule = rules.begin();
    376          rule != rules.end();
    377          ++rule) {
    378       DispatchToMethod(this, &PolicyProvider::UpdateContentSettingsMap, *rule);
    379     }
    380   }
    381 }
    382 
    383 // Since the PolicyProvider is a read only content settings provider, all
    384 // methodes of the ProviderInterface that set or delete any settings do nothing.
    385 void PolicyProvider::SetContentSetting(
    386     const ContentSettingsPattern& requesting_pattern,
    387     const ContentSettingsPattern& embedding_pattern,
    388     ContentSettingsType content_type,
    389     const ResourceIdentifier& resource_identifier,
    390     ContentSetting content_setting) {
    391 }
    392 
    393 ContentSetting PolicyProvider::GetContentSetting(
    394     const GURL& requesting_url,
    395     const GURL& embedding_url,
    396     ContentSettingsType content_type,
    397     const ResourceIdentifier& resource_identifier) const {
    398   return BaseProvider::GetContentSetting(
    399       requesting_url,
    400       embedding_url,
    401       content_type,
    402       NO_RESOURCE_IDENTIFIER);
    403 }
    404 
    405 void PolicyProvider::ClearAllContentSettingsRules(
    406     ContentSettingsType content_type) {
    407 }
    408 
    409 void PolicyProvider::ResetToDefaults() {
    410 }
    411 
    412 void PolicyProvider::UnregisterObservers() {
    413   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    414   if (!profile_)
    415     return;
    416   pref_change_registrar_.RemoveAll();
    417   notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
    418                                  Source<Profile>(profile_));
    419   profile_ = NULL;
    420 }
    421 
    422 void PolicyProvider::NotifyObservers(
    423     const ContentSettingsDetails& details) {
    424   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    425   if (profile_ == NULL)
    426     return;
    427   NotificationService::current()->Notify(
    428       NotificationType::CONTENT_SETTINGS_CHANGED,
    429       Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()),
    430       Details<const ContentSettingsDetails>(&details));
    431 }
    432 
    433 void PolicyProvider::Observe(NotificationType type,
    434                              const NotificationSource& source,
    435                              const NotificationDetails& details) {
    436   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    437 
    438   if (type == NotificationType::PREF_CHANGED) {
    439     DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
    440     std::string* name = Details<std::string>(details).ptr();
    441     if (*name == prefs::kManagedCookiesAllowedForUrls ||
    442         *name == prefs::kManagedCookiesBlockedForUrls ||
    443         *name == prefs::kManagedCookiesSessionOnlyForUrls ||
    444         *name == prefs::kManagedImagesAllowedForUrls ||
    445         *name == prefs::kManagedImagesBlockedForUrls ||
    446         *name == prefs::kManagedJavaScriptAllowedForUrls ||
    447         *name == prefs::kManagedJavaScriptBlockedForUrls ||
    448         *name == prefs::kManagedPluginsAllowedForUrls ||
    449         *name == prefs::kManagedPluginsBlockedForUrls ||
    450         *name == prefs::kManagedPopupsAllowedForUrls ||
    451         *name == prefs::kManagedPopupsBlockedForUrls) {
    452       ReadManagedContentSettings(true);
    453       NotifyObservers(ContentSettingsDetails(
    454           ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, ""));
    455       // We do not want to sent a notification when managed default content
    456       // settings change. The DefaultProvider will take care of that. We are
    457       // only a passive observer.
    458       // TODO(markusheintz): NOTICE: This is still work in progress and part of
    459       // a larger refactoring. The code will change and be much cleaner and
    460       // clearer in the end.
    461     } else if (*name == prefs::kManagedDefaultCookiesSetting) {
    462       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_COOKIES);
    463     } else if (*name == prefs::kManagedDefaultImagesSetting) {
    464       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_IMAGES);
    465     } else if (*name == prefs::kManagedDefaultJavaScriptSetting) {
    466       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
    467     } else if (*name == prefs::kManagedDefaultPluginsSetting) {
    468       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_PLUGINS);
    469     } else if (*name == prefs::kManagedDefaultPopupsSetting) {
    470       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_POPUPS);
    471     }
    472   } else if (type == NotificationType::PROFILE_DESTROYED) {
    473     DCHECK_EQ(profile_, Source<Profile>(source).ptr());
    474     UnregisterObservers();
    475   } else {
    476     NOTREACHED() << "Unexpected notification";
    477   }
    478 }
    479 
    480 }  // namespace content_settings
    481