Chromium Code Reviews| Index: chrome/browser/content_settings/cookie_settings.cc |
| diff --git a/chrome/browser/content_settings/cookie_settings.cc b/chrome/browser/content_settings/cookie_settings.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..65d73cd5b29712eccb013c0860cb27c1f4f1b2d2 |
| --- /dev/null |
| +++ b/chrome/browser/content_settings/cookie_settings.cc |
| @@ -0,0 +1,230 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "cookie_settings.h" |
| + |
| +#include "base/command_line.h" |
| +#include "chrome/browser/content_settings/content_settings_pattern.h" |
| +#include "chrome/browser/content_settings/host_content_settings_map.h" |
| +#include "chrome/browser/prefs/pref_service.h" |
| +#include "chrome/common/chrome_notification_types.h" |
| +#include "chrome/common/chrome_switches.h" |
| +#include "chrome/common/pref_names.h" |
| +#include "content/browser/browser_thread.h" |
| +#include "content/browser/user_metrics.h" |
| +#include "content/common/notification_service.h" |
| +#include "content/common/notification_source.h" |
| +#include "googleurl/src/gurl.h" |
| +#include "net/base/net_errors.h" |
| +#include "net/base/static_cookie_policy.h" |
| + |
| +CookieSettings::CookieSettings( |
| + HostContentSettingsMap* host_content_settings_map, |
| + PrefService* prefs, |
| + bool incognito) |
| + : host_content_settings_map_(host_content_settings_map), |
| + prefs_(prefs), |
| + is_off_the_record_(incognito), |
| + block_third_party_cookies_(false) { |
| + block_third_party_cookies_ = |
| + prefs_->GetBoolean(prefs::kBlockThirdPartyCookies); |
| + if (block_third_party_cookies_) { |
| + UserMetrics::RecordAction( |
| + UserMetricsAction("ThirdPartyCookieBlockingEnabled")); |
| + } else { |
| + UserMetrics::RecordAction( |
| + UserMetricsAction("ThirdPartyCookieBlockingDisabled")); |
| + } |
| + |
| + pref_change_registrar_.Init(prefs_); |
| + pref_change_registrar_.Add(prefs::kBlockThirdPartyCookies, this); |
| +} |
| + |
| +ContentSetting CookieSettings::GetDefaultSetting() const { |
| + ContentSetting allow_or_block = |
| + host_content_settings_map_->GetDefaultContentSetting( |
| + CONTENT_SETTINGS_TYPE_COOKIES); |
| + DCHECK(allow_or_block == CONTENT_SETTING_ALLOW || |
| + allow_or_block == CONTENT_SETTING_BLOCK); |
| + if (allow_or_block == CONTENT_SETTING_BLOCK) |
| + return allow_or_block; |
| + ContentSetting session_only = |
| + host_content_settings_map_->GetDefaultContentSetting( |
| + CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY); |
| + DCHECK(allow_or_block == CONTENT_SETTING_ALLOW || |
| + allow_or_block == CONTENT_SETTING_SESSION_ONLY); |
| + return session_only; |
| +} |
| + |
| +bool CookieSettings::IsReadingCookieAllowed(const GURL& url, |
| + const GURL& first_party_url) const { |
| + ContentSetting setting = GetCookieContentSetting( |
| + url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, false); |
| + DCHECK(setting == CONTENT_SETTING_ALLOW || |
| + setting == CONTENT_SETTING_BLOCK); |
| + return setting == CONTENT_SETTING_ALLOW; |
| +} |
| + |
| +bool CookieSettings::IsSettingCookieAllowed(const GURL& url, |
| + const GURL& first_party_url) const { |
| + ContentSetting setting = GetCookieContentSetting( |
| + url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, true); |
| + DCHECK(setting == CONTENT_SETTING_ALLOW || |
| + setting == CONTENT_SETTING_BLOCK); |
| + return setting == CONTENT_SETTING_ALLOW; |
| +} |
| + |
| +bool CookieSettings::IsCookieSessionOnly(const GURL& origin) const { |
| + // FIXME(marja): Add another content type here |
|
Bernhard Bauer
2011/09/01 11:41:54
Is this comment still up to date?
marja
2011/09/01 13:34:48
Removed.
|
| + ContentSetting setting = GetCookieContentSetting( |
|
Bernhard Bauer
2011/09/01 11:41:54
I think you could directly consult the HCSM here.
marja
2011/09/01 13:34:48
Hmm, not sure if I understand. Do you mean duplica
Bernhard Bauer
2011/09/01 13:58:49
No, HostContentSettingsMap has a GetContentSetting
|
| + origin, origin, CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, true); |
| + DCHECK(setting == CONTENT_SETTING_ALLOW || |
| + setting == CONTENT_SETTING_SESSION_ONLY); |
| + return (setting == CONTENT_SETTING_SESSION_ONLY); |
| +} |
| + |
| +void CookieSettings::SetDefaultSetting(ContentSetting setting) { |
| + DCHECK(setting == CONTENT_SETTING_ALLOW || |
| + setting == CONTENT_SETTING_SESSION_ONLY || |
| + setting == CONTENT_SETTING_BLOCK); |
| + ContentSetting allowed = CONTENT_SETTING_BLOCK; |
| + ContentSetting session_only = CONTENT_SETTING_ALLOW; |
| + if (setting == CONTENT_SETTING_ALLOW || |
| + setting == CONTENT_SETTING_SESSION_ONLY) |
| + allowed = CONTENT_SETTING_ALLOW; |
| + if (setting == CONTENT_SETTING_SESSION_ONLY) |
| + session_only = CONTENT_SETTING_SESSION_ONLY; |
| + host_content_settings_map_->SetDefaultContentSetting( |
| + CONTENT_SETTINGS_TYPE_COOKIES, allowed); |
| + host_content_settings_map_->SetDefaultContentSetting( |
| + CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, session_only); |
| +} |
| + |
| +void CookieSettings::SetCookieSetting( |
| + const ContentSettingsPattern& primary_pattern, |
| + ContentSetting content_setting) { |
| + DCHECK(content_setting == CONTENT_SETTING_ALLOW || |
| + content_setting == CONTENT_SETTING_SESSION_ONLY || |
| + content_setting == CONTENT_SETTING_BLOCK); |
| + bool allowed = |
| + content_setting == CONTENT_SETTING_ALLOW || |
| + content_setting == CONTENT_SETTING_SESSION_ONLY; |
| + bool session_only = (content_setting == CONTENT_SETTING_SESSION_ONLY); |
| + host_content_settings_map_->SetContentSetting( |
| + primary_pattern, ContentSettingsPattern::Wildcard(), |
| + CONTENT_SETTINGS_TYPE_COOKIES, "", |
| + allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK); |
| + host_content_settings_map_->SetContentSetting( |
| + primary_pattern, ContentSettingsPattern::Wildcard(), |
| + CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, "", |
| + session_only ? CONTENT_SETTING_SESSION_ONLY : CONTENT_SETTING_ALLOW); |
| +} |
| + |
| +void CookieSettings::ResetCookieSetting( |
| + const ContentSettingsPattern& primary_pattern) { |
| + host_content_settings_map_->SetContentSetting( |
| + primary_pattern, ContentSettingsPattern::Wildcard(), |
| + CONTENT_SETTINGS_TYPE_COOKIES, "", |
| + CONTENT_SETTING_DEFAULT); |
| + host_content_settings_map_->SetContentSetting( |
| + primary_pattern, ContentSettingsPattern::Wildcard(), |
| + CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, "", |
| + CONTENT_SETTING_DEFAULT); |
| +} |
| + |
| +void CookieSettings::SetBlockThirdPartyCookies(bool block) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(prefs_); |
| + |
| + // This setting may not be directly modified for OTR sessions. Instead, it |
| + // is synced to the main profile's setting. |
| + if (is_off_the_record_) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + // If the preference block-third-party-cookies is managed then do not allow to |
| + // change it. |
| + if (prefs_->IsManagedPreference(prefs::kBlockThirdPartyCookies)) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + { |
| + base::AutoLock auto_lock(lock_); |
| + block_third_party_cookies_ = block; |
| + } |
| + |
| + prefs_->SetBoolean(prefs::kBlockThirdPartyCookies, block); |
| +} |
| + |
| +void CookieSettings::Observe(int type, |
| + const NotificationSource& source, |
| + const NotificationDetails& details) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + |
| + if (type == chrome::NOTIFICATION_PREF_CHANGED) { |
| + DCHECK_EQ(prefs_, Source<PrefService>(source).ptr()); |
| + |
| + std::string* name = Details<std::string>(details).ptr(); |
| + if (*name == prefs::kBlockThirdPartyCookies) { |
| + base::AutoLock auto_lock(lock_); |
| + block_third_party_cookies_ = prefs_->GetBoolean( |
| + prefs::kBlockThirdPartyCookies); |
| + } else { |
| + NOTREACHED() << "Unexpected preference observed"; |
| + return; |
| + } |
| + } else { |
| + NOTREACHED() << "Unexpected notification"; |
| + } |
| +} |
| + |
| +void CookieSettings::Shutdown() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + pref_change_registrar_.RemoveAll(); |
| +} |
| + |
| +ContentSetting CookieSettings::GetCookieContentSetting( |
| + const GURL& url, |
| + const GURL& first_party_url, |
| + ContentSettingsType content_type, |
| + bool setting_cookie) const { |
| + if (HostContentSettingsMap::ShouldAllowAllContent( |
| + first_party_url, CONTENT_SETTINGS_TYPE_COOKIES)) |
| + return CONTENT_SETTING_ALLOW; |
| + |
| + // First get any host-specific settings. |
| + ContentSetting setting = |
| + host_content_settings_map_->GetNonDefaultContentSetting( |
| + url, first_party_url, content_type, ""); |
| + |
| + // Check if third-party cookie settings deny the cookie. This check makes |
| + // sense only for the CONTENT_SETTINGS_TYPE_COOKIES, since the session only |
| + // check is based on one url only. |
| + if (content_type == CONTENT_SETTINGS_TYPE_COOKIES && |
| + setting == CONTENT_SETTING_DEFAULT && |
| + BlockThirdPartyCookies()) { |
| + bool strict = CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kBlockReadingThirdPartyCookies); |
| + net::StaticCookiePolicy policy(strict ? |
| + net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES : |
| + net::StaticCookiePolicy::BLOCK_SETTING_THIRD_PARTY_COOKIES); |
| + int rv; |
| + if (setting_cookie) |
| + rv = policy.CanSetCookie(url, first_party_url); |
| + else |
| + rv = policy.CanGetCookies(url, first_party_url); |
| + DCHECK_NE(net::ERR_IO_PENDING, rv); |
| + if (rv != net::OK) |
| + setting = CONTENT_SETTING_BLOCK; |
| + } |
| + |
| + // If no other policy has changed the setting, use the default. |
| + if (setting == CONTENT_SETTING_DEFAULT) { |
| + setting = |
| + host_content_settings_map_->GetDefaultContentSetting(content_type); |
| + } |
| + return setting; |
| +} |