diff options
author | markusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 17:20:03 +0000 |
---|---|---|
committer | markusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 17:20:03 +0000 |
commit | cdfe882d3c447b10e0b107661f0c3a5320ceb594 (patch) | |
tree | 3738ddd9ab9bd836b401eee81bbb4bb5cbbb6c82 /chrome/browser | |
parent | fb6d25db25d9c2d290e03d111e0df0b366f595f9 (diff) | |
download | chromium_src-cdfe882d3c447b10e0b107661f0c3a5320ceb594.zip chromium_src-cdfe882d3c447b10e0b107661f0c3a5320ceb594.tar.gz chromium_src-cdfe882d3c447b10e0b107661f0c3a5320ceb594.tar.bz2 |
Add content_settings::PolicyProvider and a set of new policies to managed content settings.
BUG=63656,63182
TEST=content_settings_policy_provider_unittest.cc,host_content_settings_map_unittests.cc
Review URL: http://codereview.chromium.org/6542048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76224 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
11 files changed, 584 insertions, 35 deletions
diff --git a/chrome/browser/content_settings/content_settings_base_provider.cc b/chrome/browser/content_settings/content_settings_base_provider.cc index 6bc3d66..b0e7ced 100644 --- a/chrome/browser/content_settings/content_settings_base_provider.cc +++ b/chrome/browser/content_settings/content_settings_base_provider.cc @@ -72,18 +72,10 @@ ContentSetting BaseProvider::GetContentSetting( // Support for embedding_patterns is not implemented yet. DCHECK(requesting_url == embedding_url); - if (!RequiresResourceIdentifier(content_type)) + if (!RequiresResourceIdentifier(content_type) || + (RequiresResourceIdentifier(content_type) && resource_identifier.empty())) return GetNonDefaultContentSettings(requesting_url).settings[content_type]; - if (RequiresResourceIdentifier(content_type) && resource_identifier.empty()) - return CONTENT_SETTING_DEFAULT; - - // TODO(markusheintz) Remove this DCHECK. - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableResourceContentSettings)) { - DCHECK(!resource_identifier.empty()); - } - // Resolve content settings with resource identifier. // 1. Check for pattern that exactly match the url/host // 1.1 In the content-settings-map @@ -150,8 +142,6 @@ void BaseProvider::GetAllContentSettingsRules( ContentSettingsType content_type, const ResourceIdentifier& resource_identifier, Rules* content_setting_rules) const { - DCHECK(RequiresResourceIdentifier(content_type) != - resource_identifier.empty()); DCHECK(content_setting_rules); content_setting_rules->clear(); @@ -237,6 +227,19 @@ ContentSettings BaseProvider::GetNonDefaultContentSettings( return output; } +void BaseProvider::UpdateContentSettingsMap( + const ContentSettingsPattern& requesting_pattern, + const ContentSettingsPattern& embedding_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + ContentSetting content_setting) { + std::string pattern_str(requesting_pattern.CanonicalizePattern()); + HostContentSettings* content_settings_map = host_content_settings(); + ExtendedContentSettings& extended_settings = + (*content_settings_map)[pattern_str]; + extended_settings.content_settings.settings[content_type] = content_setting; +} + // static ContentSetting BaseProvider::ClickToPlayFixup(ContentSettingsType content_type, ContentSetting setting) { diff --git a/chrome/browser/content_settings/content_settings_base_provider.h b/chrome/browser/content_settings/content_settings_base_provider.h index d415e82..1e6c9e4 100644 --- a/chrome/browser/content_settings/content_settings_base_provider.h +++ b/chrome/browser/content_settings/content_settings_base_provider.h @@ -84,6 +84,13 @@ class BaseProvider : public ProviderInterface { // CONTENT_SETTING_DEFAULT values. bool AllDefault(const ExtendedContentSettings& settings) const; + void UpdateContentSettingsMap( + const ContentSettingsPattern& requesting_pattern, + const ContentSettingsPattern& embedding_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + ContentSetting content_setting); + // TODO(markusheintz): LEGACY method. Will be removed in a future re-factoring // step. ContentSettings GetNonDefaultContentSettings(const GURL& url) const; diff --git a/chrome/browser/content_settings/content_settings_mock_provider.cc b/chrome/browser/content_settings/content_settings_mock_provider.cc index 4b0c077..c166dd6 100644 --- a/chrome/browser/content_settings/content_settings_mock_provider.cc +++ b/chrome/browser/content_settings/content_settings_mock_provider.cc @@ -46,20 +46,23 @@ MockProvider::MockProvider() content_type_(CONTENT_SETTINGS_TYPE_COOKIES), resource_identifier_(""), setting_(CONTENT_SETTING_DEFAULT), - read_only_(false) {} + read_only_(false), + is_managed_(false) {} MockProvider::MockProvider(ContentSettingsPattern requesting_url_pattern, ContentSettingsPattern embedding_url_pattern, ContentSettingsType content_type, ResourceIdentifier resource_identifier, ContentSetting setting, - bool read_only) + bool read_only, + bool is_managed) : requesting_url_pattern_(requesting_url_pattern), embedding_url_pattern_(embedding_url_pattern), content_type_(content_type), resource_identifier_(resource_identifier), setting_(setting), - read_only_(read_only) {} + read_only_(read_only), + is_managed_(is_managed) {} MockProvider::~MockProvider() {} @@ -91,4 +94,11 @@ void MockProvider::SetContentSetting( setting_ = content_setting; } +bool MockProvider::ContentSettingsTypeIsManaged(ContentSettingsType type) { + if (type == content_type_) { + return is_managed_; + } + return false; +} + } // namespace content_settings diff --git a/chrome/browser/content_settings/content_settings_mock_provider.h b/chrome/browser/content_settings/content_settings_mock_provider.h index a71a574..17ced25 100644 --- a/chrome/browser/content_settings/content_settings_mock_provider.h +++ b/chrome/browser/content_settings/content_settings_mock_provider.h @@ -49,9 +49,12 @@ class MockProvider : public ProviderInterface { ContentSettingsType content_type, ResourceIdentifier resource_identifier, ContentSetting setting, - bool read_only); + bool read_only, + bool is_managed); virtual ~MockProvider(); + virtual bool ContentSettingsTypeIsManaged(ContentSettingsType type); + // ProviderInterface implementation virtual ContentSetting GetContentSetting( const GURL& requesting_url, @@ -83,7 +86,7 @@ class MockProvider : public ProviderInterface { requesting_url_pattern_ = pattern; } - ContentSettingsPattern requesting_url_pattern() { + ContentSettingsPattern requesting_url_pattern() const { return requesting_url_pattern_; } @@ -91,7 +94,7 @@ class MockProvider : public ProviderInterface { embedding_url_pattern_ = pattern; } - ContentSettingsPattern embedding_url_pattern() { + ContentSettingsPattern embedding_url_pattern() const { return embedding_url_pattern_; } @@ -99,7 +102,7 @@ class MockProvider : public ProviderInterface { content_type_ = content_type; } - ContentSettingsType content_type() { + ContentSettingsType content_type() const { return content_type_; } @@ -107,7 +110,7 @@ class MockProvider : public ProviderInterface { resource_identifier_ = resource_identifier; } - ResourceIdentifier resource_identifier() { + ResourceIdentifier resource_identifier() const { return resource_identifier_; } @@ -115,7 +118,7 @@ class MockProvider : public ProviderInterface { setting_ = setting; } - ContentSetting setting() { + ContentSetting setting() const { return setting_; } @@ -123,10 +126,18 @@ class MockProvider : public ProviderInterface { read_only_ = read_only; } - bool read_only() { + bool read_only() const { return read_only_; } + void set_is_managed(bool is_managed) { + is_managed_ = is_managed; + } + + bool is_managed() const { + return is_managed_; + } + private: ContentSettingsPattern requesting_url_pattern_; ContentSettingsPattern embedding_url_pattern_; @@ -134,6 +145,7 @@ class MockProvider : public ProviderInterface { ResourceIdentifier resource_identifier_; ContentSetting setting_; bool read_only_; + bool is_managed_; DISALLOW_COPY_AND_ASSIGN(MockProvider); }; diff --git a/chrome/browser/content_settings/content_settings_policy_provider.cc b/chrome/browser/content_settings/content_settings_policy_provider.cc index 1055cee..6c1feb1 100644 --- a/chrome/browser/content_settings/content_settings_policy_provider.cc +++ b/chrome/browser/content_settings/content_settings_policy_provider.cc @@ -5,6 +5,7 @@ #include "chrome/browser/content_settings/content_settings_policy_provider.h" #include <string> +#include <vector> #include "base/command_line.h" #include "chrome/browser/browser_thread.h" @@ -18,6 +19,9 @@ #include "chrome/common/notification_source.h" #include "chrome/common/pref_names.h" +#include "webkit/plugins/npapi/plugin_group.h" +#include "webkit/plugins/npapi/plugin_list.h" + namespace { // Base pref path of the prefs that contain the managed default content @@ -36,6 +40,63 @@ const char* kPrefToManageType[CONTENT_SETTINGS_NUM_TYPES] = { NULL, // Not used for Notifications }; +struct PrefsForManagedContentSettingsMapEntry { + const char* pref_name; + ContentSettingsType content_type; + ContentSetting setting; +}; + +const PrefsForManagedContentSettingsMapEntry + kPrefsForManagedContentSettingsMap[] = { + { + prefs::kManagedCookiesAllowedForUrls, + CONTENT_SETTINGS_TYPE_COOKIES, + CONTENT_SETTING_ALLOW + }, { + prefs::kManagedCookiesSessionOnlyForUrls, + CONTENT_SETTINGS_TYPE_COOKIES, + CONTENT_SETTING_SESSION_ONLY + }, { + prefs::kManagedCookiesBlockedForUrls, + CONTENT_SETTINGS_TYPE_COOKIES, + CONTENT_SETTING_BLOCK + }, { + prefs::kManagedImagesAllowedForUrls, + CONTENT_SETTINGS_TYPE_IMAGES, + CONTENT_SETTING_ALLOW + }, { + prefs::kManagedImagesBlockedForUrls, + CONTENT_SETTINGS_TYPE_IMAGES, + CONTENT_SETTING_BLOCK + }, { + prefs::kManagedJavaScriptAllowedForUrls, + CONTENT_SETTINGS_TYPE_JAVASCRIPT, + CONTENT_SETTING_ALLOW + }, { + prefs::kManagedJavaScriptBlockedForUrls, + CONTENT_SETTINGS_TYPE_JAVASCRIPT, + CONTENT_SETTING_BLOCK + }, { + prefs::kManagedPluginsAllowedForUrls, + CONTENT_SETTINGS_TYPE_PLUGINS, + CONTENT_SETTING_ALLOW + }, { + prefs::kManagedPluginsBlockedForUrls, + CONTENT_SETTINGS_TYPE_PLUGINS, + CONTENT_SETTING_BLOCK + }, { + prefs::kManagedPopupsAllowedForUrls, + CONTENT_SETTINGS_TYPE_POPUPS, + CONTENT_SETTING_ALLOW + }, { + prefs::kManagedPopupsBlockedForUrls, + CONTENT_SETTINGS_TYPE_POPUPS, + CONTENT_SETTING_BLOCK + } +}; + +const std::string NO_IDENTIFIER = ""; + } // namespace namespace content_settings { @@ -156,7 +217,6 @@ void PolicyDefaultProvider::NotifyObservers( void PolicyDefaultProvider::ReadManagedDefaultSettings() { for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) { if (kPrefToManageType[type] == NULL) { - // TODO(markusheintz): Handle Geolocation and notification separately. continue; } UpdateManagedDefaultSetting(ContentSettingsType(type)); @@ -195,4 +255,229 @@ void PolicyDefaultProvider::RegisterUserPrefs(PrefService* prefs) { CONTENT_SETTING_DEFAULT); } +// //////////////////////////////////////////////////////////////////////////// +// PolicyProvider + +// static +void PolicyProvider::RegisterUserPrefs(PrefService* prefs) { + prefs->RegisterListPref(prefs::kManagedCookiesAllowedForUrls); + prefs->RegisterListPref(prefs::kManagedCookiesBlockedForUrls); + prefs->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls); + prefs->RegisterListPref(prefs::kManagedImagesAllowedForUrls); + prefs->RegisterListPref(prefs::kManagedImagesBlockedForUrls); + prefs->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls); + prefs->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls); + prefs->RegisterListPref(prefs::kManagedPluginsAllowedForUrls); + prefs->RegisterListPref(prefs::kManagedPluginsBlockedForUrls); + prefs->RegisterListPref(prefs::kManagedPopupsAllowedForUrls); + prefs->RegisterListPref(prefs::kManagedPopupsBlockedForUrls); +} + +PolicyProvider::PolicyProvider(Profile* profile) + : BaseProvider(profile->IsOffTheRecord()), + profile_(profile) { + Init(); +} + +PolicyProvider::~PolicyProvider() { + UnregisterObservers(); +} + +void PolicyProvider::ReadManagedContentSettingsTypes( + ContentSettingsType content_type) { + PrefService* prefs = profile_->GetPrefs(); + if (kPrefToManageType[content_type] == NULL) { + content_type_is_managed_[content_type] = false; + } else { + content_type_is_managed_[content_type] = + prefs->IsManagedPreference(kPrefToManageType[content_type]); + } +} + +void PolicyProvider::Init() { + PrefService* prefs = profile_->GetPrefs(); + + ReadManagedContentSettings(false); + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) + ReadManagedContentSettingsTypes(ContentSettingsType(i)); + + pref_change_registrar_.Init(prefs); + pref_change_registrar_.Add(prefs::kManagedCookiesBlockedForUrls, this); + pref_change_registrar_.Add(prefs::kManagedCookiesAllowedForUrls, this); + pref_change_registrar_.Add(prefs::kManagedCookiesSessionOnlyForUrls, this); + pref_change_registrar_.Add(prefs::kManagedImagesBlockedForUrls, this); + pref_change_registrar_.Add(prefs::kManagedImagesAllowedForUrls, this); + pref_change_registrar_.Add(prefs::kManagedJavaScriptBlockedForUrls, this); + pref_change_registrar_.Add(prefs::kManagedJavaScriptAllowedForUrls, this); + pref_change_registrar_.Add(prefs::kManagedPluginsBlockedForUrls, this); + pref_change_registrar_.Add(prefs::kManagedPluginsAllowedForUrls, this); + pref_change_registrar_.Add(prefs::kManagedPopupsBlockedForUrls, this); + pref_change_registrar_.Add(prefs::kManagedPopupsAllowedForUrls, this); + + pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this); + pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this); + pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this); + pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this); + pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this); + + notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED, + Source<Profile>(profile_)); +} + +bool PolicyProvider::ContentSettingsTypeIsManaged( + ContentSettingsType content_type) { + return content_type_is_managed_[content_type]; +} + +void PolicyProvider::GetContentSettingsFromPreferences( + PrefService* prefs, + ContentSettingsRules* rules) { + for (size_t i = 0; i < arraysize(kPrefsForManagedContentSettingsMap); ++i) { + const char* pref_name = kPrefsForManagedContentSettingsMap[i].pref_name; + // Skip unset policies. + if (!prefs->HasPrefPath(pref_name)) { + LOG(INFO) << "Skiping unset preference: " << pref_name; + continue; + } + + const PrefService::Preference* pref = prefs->FindPreference(pref_name); + DCHECK(pref->IsManaged()); + DCHECK_EQ(Value::TYPE_LIST, pref->GetType()); + + const ListValue* pattern_str_list = + static_cast<const ListValue*>(pref->GetValue()); + for (size_t j = 0; j < pattern_str_list->GetSize(); ++j) { + std::string original_pattern_str; + pattern_str_list->GetString(j, &original_pattern_str); + ContentSettingsPattern pattern(original_pattern_str); + if (!pattern.IsValid()) { + // Ignore invalid patterns + continue; + LOG(WARNING) << "Ignoring invalid content settings pattern: " + << pattern.AsString(); + } + rules->push_back(MakeTuple( + pattern, + pattern, + kPrefsForManagedContentSettingsMap[i].content_type, + NO_IDENTIFIER, + kPrefsForManagedContentSettingsMap[i].setting)); + } + } +} + +void PolicyProvider::ReadManagedContentSettings(bool overwrite) { + ContentSettingsRules rules; + PrefService* prefs = profile_->GetPrefs(); + GetContentSettingsFromPreferences(prefs, &rules); + { + base::AutoLock auto_lock(lock()); + HostContentSettings* content_settings_map = host_content_settings(); + if (overwrite) + content_settings_map->clear(); + for (ContentSettingsRules::iterator rule = rules.begin(); + rule != rules.end(); + ++rule) { + DispatchToMethod(this, &PolicyProvider::UpdateContentSettingsMap, *rule); + } + } +} + +// Since the PolicyProvider is a read only content settings provider, all +// methodes of the ProviderInterface that set or delete any settings do nothing. +void PolicyProvider::SetContentSetting( + const ContentSettingsPattern& requesting_pattern, + const ContentSettingsPattern& embedding_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + ContentSetting content_setting) { +} + +ContentSetting PolicyProvider::GetContentSetting( + const GURL& requesting_url, + const GURL& embedding_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const { + return BaseProvider::GetContentSetting( + requesting_url, + embedding_url, + content_type, + NO_IDENTIFIER); +} + +void PolicyProvider::ClearAllContentSettingsRules( + ContentSettingsType content_type) { +} + +void PolicyProvider::ResetToDefaults() { +} + +void PolicyProvider::UnregisterObservers() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (!profile_) + return; + pref_change_registrar_.RemoveAll(); + notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED, + Source<Profile>(profile_)); + profile_ = NULL; +} + +void PolicyProvider::NotifyObservers( + const ContentSettingsDetails& details) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (profile_ == NULL) + return; + NotificationService::current()->Notify( + NotificationType::CONTENT_SETTINGS_CHANGED, + Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()), + Details<const ContentSettingsDetails>(&details)); +} + +void PolicyProvider::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + if (type == NotificationType::PREF_CHANGED) { + DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr()); + std::string* name = Details<std::string>(details).ptr(); + if (*name == prefs::kManagedCookiesAllowedForUrls || + *name == prefs::kManagedCookiesBlockedForUrls || + *name == prefs::kManagedCookiesSessionOnlyForUrls || + *name == prefs::kManagedImagesAllowedForUrls || + *name == prefs::kManagedImagesBlockedForUrls || + *name == prefs::kManagedJavaScriptAllowedForUrls || + *name == prefs::kManagedJavaScriptBlockedForUrls || + *name == prefs::kManagedPluginsAllowedForUrls || + *name == prefs::kManagedPluginsBlockedForUrls || + *name == prefs::kManagedPopupsAllowedForUrls || + *name == prefs::kManagedPopupsBlockedForUrls) { + ReadManagedContentSettings(true); + NotifyObservers(ContentSettingsDetails( + ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, "")); + // We do not want to sent a notification when managed default content + // settings change. The DefaultProvider will take care of that. We are + // only a passive observer. + // TODO(markusheintz): NOTICE: This is still work in progress and part of + // a larger refactoring. The code will change and be much cleaner and + // clearer in the end. + } else if (*name == prefs::kManagedDefaultCookiesSetting) { + ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_COOKIES); + } else if (*name == prefs::kManagedDefaultImagesSetting) { + ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_IMAGES); + } else if (*name == prefs::kManagedDefaultJavaScriptSetting) { + ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_JAVASCRIPT); + } else if (*name == prefs::kManagedDefaultPluginsSetting) { + ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_PLUGINS); + } else if (*name == prefs::kManagedDefaultPopupsSetting) { + ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_POPUPS); + } + } else if (type == NotificationType::PROFILE_DESTROYED) { + DCHECK_EQ(profile_, Source<Profile>(source).ptr()); + UnregisterObservers(); + } else { + NOTREACHED() << "Unexpected notification"; + } +} + } // namespace content_settings diff --git a/chrome/browser/content_settings/content_settings_policy_provider.h b/chrome/browser/content_settings/content_settings_policy_provider.h index 82aaf26..96dd115 100644 --- a/chrome/browser/content_settings/content_settings_policy_provider.h +++ b/chrome/browser/content_settings/content_settings_policy_provider.h @@ -8,9 +8,13 @@ // A content settings provider that takes its settings out of policies. +#include <vector> + #include "base/basictypes.h" #include "base/synchronization/lock.h" +#include "base/tuple.h" #include "chrome/browser/content_settings/content_settings_provider.h" +#include "chrome/browser/content_settings/content_settings_base_provider.h" #include "chrome/browser/prefs/pref_change_registrar.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" @@ -76,6 +80,75 @@ class PolicyDefaultProvider : public DefaultProviderInterface, DISALLOW_COPY_AND_ASSIGN(PolicyDefaultProvider); }; +// PolicyProvider that provider managed content-settings. +class PolicyProvider : public BaseProvider, + public NotificationObserver { + public: + explicit PolicyProvider(Profile* profile); + ~PolicyProvider(); + static void RegisterUserPrefs(PrefService* prefs); + + // BaseProvider Implementation + virtual void Init(); + + // ProviderInterface Implementation + virtual bool ContentSettingsTypeIsManaged( + ContentSettingsType content_type); + + virtual void SetContentSetting( + const ContentSettingsPattern& requesting_pattern, + const ContentSettingsPattern& embedding_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + ContentSetting content_setting); + + virtual ContentSetting GetContentSetting( + const GURL& requesting_url, + const GURL& embedding_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const; + + virtual void ClearAllContentSettingsRules( + ContentSettingsType content_type); + + virtual void ResetToDefaults(); + + // NotificationObserver implementation. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + private: + typedef Tuple5< + ContentSettingsPattern, + ContentSettingsPattern, + ContentSettingsType, + content_settings::ProviderInterface::ResourceIdentifier, + ContentSetting> ContentSettingsRule; + + typedef std::vector<ContentSettingsRule> ContentSettingsRules; + + void ReadManagedContentSettings(bool overwrite); + + void GetContentSettingsFromPreferences(PrefService* prefs, + ContentSettingsRules* rules); + + void ReadManagedContentSettingsTypes( + ContentSettingsType content_type); + + void NotifyObservers(const ContentSettingsDetails& details); + + void UnregisterObservers(); + + Profile* profile_; + + bool content_type_is_managed_[CONTENT_SETTINGS_NUM_TYPES]; + + PrefChangeRegistrar pref_change_registrar_; + NotificationRegistrar notification_registrar_; + + DISALLOW_COPY_AND_ASSIGN(PolicyProvider); +}; + } // namespace content_settings #endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_POLICY_PROVIDER_H_ diff --git a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc index e9cc6cc..49d23be 100644 --- a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc @@ -4,16 +4,19 @@ #include "chrome/browser/content_settings/content_settings_policy_provider.h" +#include "base/auto_reset.h" +#include "base/command_line.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/content_settings/stub_settings_observer.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/test/testing_browser_process_test.h" #include "chrome/test/testing_pref_service.h" #include "chrome/test/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h" - +#include "googleurl/src/gurl.h" namespace content_settings { @@ -81,4 +84,102 @@ TEST_F(PolicyDefaultProviderTest, ObserveManagedSettingsChange) { EXPECT_EQ(2, observer.counter); } +class PolicyProviderTest : public testing::Test { + public: + PolicyProviderTest() + : ui_thread_(BrowserThread::UI, &message_loop_) { + } + + protected: + // TODO(markusheintz): Check if it's possible to derive the provider class + // from NonThreadSafe and to use native thread identifiers instead of + // BrowserThread IDs. Then we could get rid of the message_loop and ui_thread + // fields. + MessageLoop message_loop_; + BrowserThread ui_thread_; +}; + +TEST_F(PolicyProviderTest, Default) { + TestingProfile profile; + TestingPrefService* prefs = profile.GetTestingPrefService(); + + ListValue* value = new ListValue(); + value->Append(Value::CreateStringValue("[*.]google.com")); + prefs->SetManagedPref(prefs::kManagedImagesBlockedForUrls, + value); + + PolicyProvider provider(static_cast<Profile*>(&profile)); + + ContentSettingsPattern yt_url_pattern("www.youtube.com"); + GURL youtube_url("http://www.youtube.com"); + GURL google_url("http://mail.google.com"); + + EXPECT_EQ(CONTENT_SETTING_DEFAULT, + provider.GetContentSetting( + youtube_url, youtube_url, CONTENT_SETTINGS_TYPE_COOKIES, "")); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + provider.GetContentSetting( + google_url, google_url, CONTENT_SETTINGS_TYPE_IMAGES, "")); + + provider.SetContentSetting( + yt_url_pattern, + yt_url_pattern, + CONTENT_SETTINGS_TYPE_COOKIES, + "", + CONTENT_SETTING_BLOCK); + EXPECT_EQ(CONTENT_SETTING_DEFAULT, + provider.GetContentSetting( + youtube_url, youtube_url, CONTENT_SETTINGS_TYPE_COOKIES, "")); +} + +TEST_F(PolicyProviderTest, ResourceIdentifier) { + CommandLine* cmd = CommandLine::ForCurrentProcess(); + AutoReset<CommandLine> auto_reset(cmd, *cmd); + cmd->AppendSwitch(switches::kEnableResourceContentSettings); + + TestingProfile profile; + TestingPrefService* prefs = profile.GetTestingPrefService(); + + ListValue* value = new ListValue(); + value->Append(Value::CreateStringValue("[*.]google.com")); + prefs->SetManagedPref(prefs::kManagedPluginsAllowedForUrls, + value); + + PolicyProvider provider(static_cast<Profile*>(&profile)); + + GURL youtube_url("http://www.youtube.com"); + GURL google_url("http://mail.google.com"); + + EXPECT_EQ(CONTENT_SETTING_DEFAULT, + provider.GetContentSetting( + youtube_url, + youtube_url, + CONTENT_SETTINGS_TYPE_PLUGINS, + "someplugin")); + + // There is no policy support for resource content settings until the feature + // is enabled by default. Resource identifiers are simply ignored by the + // PolicyProvider. + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider.GetContentSetting( + google_url, + google_url, + CONTENT_SETTINGS_TYPE_PLUGINS, + "")); + + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider.GetContentSetting( + google_url, + google_url, + CONTENT_SETTINGS_TYPE_PLUGINS, + "someplugin")); + + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider.GetContentSetting( + google_url, + google_url, + CONTENT_SETTINGS_TYPE_PLUGINS, + "anotherplugin")); +} + } // namespace content_settings diff --git a/chrome/browser/content_settings/content_settings_provider.h b/chrome/browser/content_settings/content_settings_provider.h index 621c522..eff1443 100644 --- a/chrome/browser/content_settings/content_settings_provider.h +++ b/chrome/browser/content_settings/content_settings_provider.h @@ -65,6 +65,11 @@ class ProviderInterface { virtual ~ProviderInterface() {} + // Returns true whether the content settings provider manages the + // |content_type|. + virtual bool ContentSettingsTypeIsManaged( + ContentSettingsType content_type) = 0; + // Returns a single ContentSetting which applies to a given |requesting_url|, // |embedding_url| pair or CONTENT_SETTING_DEFAULT, if no rule applies. For // ContentSettingsTypes that require a resource identifier to be specified, diff --git a/chrome/browser/content_settings/content_settings_provider_unittest.cc b/chrome/browser/content_settings/content_settings_provider_unittest.cc index 0fb0d53..11c0284 100644 --- a/chrome/browser/content_settings/content_settings_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_provider_unittest.cc @@ -34,7 +34,9 @@ TEST(ContentSettingsProviderTest, Mock) { CONTENT_SETTINGS_TYPE_PLUGINS, "java_plugin", CONTENT_SETTING_BLOCK, + false, false); + EXPECT_EQ(CONTENT_SETTING_BLOCK, mock_provider.GetContentSetting( url, url, CONTENT_SETTINGS_TYPE_PLUGINS, "java_plugin")); EXPECT_EQ(CONTENT_SETTING_DEFAULT, mock_provider.GetContentSetting( diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc index ab89ac8..b477c8a 100644 --- a/chrome/browser/content_settings/host_content_settings_map.cc +++ b/chrome/browser/content_settings/host_content_settings_map.cc @@ -100,8 +100,10 @@ HostContentSettingsMap::HostContentSettingsMap(Profile* profile) // The order in which the content settings providers are created is critical, // as providers that are further up in the list (i.e. added earlier) override // providers further down. - content_settings_providers_.push_back(ProviderPtr( - new content_settings::PrefProvider(profile))); + content_settings_providers_.push_back( + make_linked_ptr(new content_settings::PolicyProvider(profile))); + content_settings_providers_.push_back( + make_linked_ptr(new content_settings::PrefProvider(profile))); pref_change_registrar_.Init(prefs); pref_change_registrar_.Add(prefs::kBlockThirdPartyCookies, this); @@ -124,6 +126,7 @@ void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { content_settings::PrefDefaultProvider::RegisterUserPrefs(prefs); content_settings::PolicyDefaultProvider::RegisterUserPrefs(prefs); content_settings::PrefProvider::RegisterUserPrefs(prefs); + content_settings::PolicyProvider::RegisterUserPrefs(prefs); } ContentSetting HostContentSettingsMap::GetDefaultContentSetting( @@ -151,10 +154,8 @@ ContentSetting HostContentSettingsMap::GetContentSetting( ContentSetting setting = GetNonDefaultContentSetting(url, content_type, resource_identifier); - if (setting == CONTENT_SETTING_DEFAULT || - IsDefaultContentSettingManaged(content_type)) { + if (setting == CONTENT_SETTING_DEFAULT) return GetDefaultContentSetting(content_type); - } return setting; } @@ -173,8 +174,9 @@ ContentSetting HostContentSettingsMap::GetNonDefaultContentSetting( ++provider) { provided_setting = (*provider)->GetContentSetting( url, url, content_type, resource_identifier); - if (provided_setting != CONTENT_SETTING_DEFAULT) - break; + bool isManaged = (*provider)->ContentSettingsTypeIsManaged(content_type); + if (provided_setting != CONTENT_SETTING_DEFAULT || isManaged) + return provided_setting; } return provided_setting; } @@ -188,9 +190,8 @@ ContentSettings HostContentSettingsMap::GetContentSettings( for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) { // A managed default content setting has the highest priority and hence // will overwrite any previously set value. - if ((output.settings[j] == CONTENT_SETTING_DEFAULT && - j != CONTENT_SETTINGS_TYPE_PLUGINS) || - IsDefaultContentSettingManaged(ContentSettingsType(j))) { + if (output.settings[j] == CONTENT_SETTING_DEFAULT && + j != CONTENT_SETTINGS_TYPE_PLUGINS) { output.settings[j] = GetDefaultContentSetting(ContentSettingsType(j)); } } @@ -225,8 +226,14 @@ void HostContentSettingsMap::GetSettingsForOneType( ++provider) { // TODO(markusheintz): Only the rules that are applied should be collected. // Merge rules. + // TODO(markusheintz): GetAllContentSettingsRules should maybe not clear the + // passed vector in case rule sets are just unified. + Rules rules; (*provider)->GetAllContentSettingsRules( - content_type, resource_identifier, &content_settings_rules); + content_type, resource_identifier, &rules); + content_settings_rules.insert(content_settings_rules.end(), + rules.begin(), + rules.end()); } // convert Rules to SettingsForOneType diff --git a/chrome/browser/policy/configuration_policy_pref_store.cc b/chrome/browser/policy/configuration_policy_pref_store.cc index 88df148..1789bb7 100644 --- a/chrome/browser/policy/configuration_policy_pref_store.cc +++ b/chrome/browser/policy/configuration_policy_pref_store.cc @@ -214,6 +214,28 @@ const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry prefs::kManagedDefaultPluginsSetting }, { Value::TYPE_INTEGER, kPolicyDefaultPopupsSetting, prefs::kManagedDefaultPopupsSetting }, + { Value::TYPE_LIST, kPolicyCookiesAllowedForUrls, + prefs::kManagedCookiesAllowedForUrls }, + { Value::TYPE_LIST, kPolicyCookiesBlockedForUrls, + prefs::kManagedCookiesBlockedForUrls }, + { Value::TYPE_LIST, kPolicyCookiesSessionOnlyForUrls, + prefs::kManagedCookiesSessionOnlyForUrls }, + { Value::TYPE_LIST, kPolicyImagesAllowedForUrls, + prefs::kManagedImagesAllowedForUrls }, + { Value::TYPE_LIST, kPolicyImagesBlockedForUrls, + prefs::kManagedImagesBlockedForUrls }, + { Value::TYPE_LIST, kPolicyJavaScriptAllowedForUrls, + prefs::kManagedJavaScriptAllowedForUrls }, + { Value::TYPE_LIST, kPolicyJavaScriptBlockedForUrls, + prefs::kManagedJavaScriptBlockedForUrls }, + { Value::TYPE_LIST, kPolicyPluginsAllowedForUrls, + prefs::kManagedPluginsAllowedForUrls }, + { Value::TYPE_LIST, kPolicyPluginsBlockedForUrls, + prefs::kManagedPluginsBlockedForUrls }, + { Value::TYPE_LIST, kPolicyPopupsAllowedForUrls, + prefs::kManagedPopupsAllowedForUrls }, + { Value::TYPE_LIST, kPolicyPopupsBlockedForUrls, + prefs::kManagedPopupsBlockedForUrls }, { Value::TYPE_INTEGER, kPolicyDefaultNotificationSetting, prefs::kDesktopNotificationDefaultContentSetting }, { Value::TYPE_INTEGER, kPolicyDefaultGeolocationSetting, @@ -900,6 +922,28 @@ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() { key::kDefaultNotificationSetting }, { kPolicyDefaultGeolocationSetting, Value::TYPE_INTEGER, key::kDefaultGeolocationSetting }, + { kPolicyCookiesAllowedForUrls, Value::TYPE_LIST, + key::kCookiesAllowedForUrls }, + { kPolicyCookiesBlockedForUrls, Value::TYPE_LIST, + key::kCookiesBlockedForUrls }, + { kPolicyCookiesSessionOnlyForUrls, Value::TYPE_LIST, + key::kCookiesSessionOnlyForUrls }, + { kPolicyImagesAllowedForUrls, Value::TYPE_LIST, + key::kImagesAllowedForUrls }, + { kPolicyImagesBlockedForUrls, Value::TYPE_LIST, + key::kImagesBlockedForUrls }, + { kPolicyJavaScriptAllowedForUrls, Value::TYPE_LIST, + key::kJavaScriptAllowedForUrls }, + { kPolicyJavaScriptBlockedForUrls, Value::TYPE_LIST, + key::kJavaScriptBlockedForUrls }, + { kPolicyPluginsAllowedForUrls, Value::TYPE_LIST, + key::kPluginsAllowedForUrls }, + { kPolicyPluginsBlockedForUrls, Value::TYPE_LIST, + key::kPluginsBlockedForUrls }, + { kPolicyPopupsAllowedForUrls, Value::TYPE_LIST, + key::kPopupsAllowedForUrls }, + { kPolicyPopupsBlockedForUrls, Value::TYPE_LIST, + key::kPopupsBlockedForUrls }, { kPolicyAuthSchemes, Value::TYPE_STRING, key::kAuthSchemes }, { kPolicyDisableAuthNegotiateCnameLookup, Value::TYPE_BOOLEAN, key::kDisableAuthNegotiateCnameLookup }, |