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/cookie_settings.h"
7 #include "base/command_line.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/content_settings/content_settings_utils.h"
11 #include "chrome/browser/content_settings/host_content_settings_map.h"
12 #include "chrome/browser/profiles/incognito_helpers.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/content_settings_pattern.h"
16 #include "chrome/common/pref_names.h"
17 #include "components/keyed_service/content/browser_context_dependency_manager.h"
18 #include "components/keyed_service/core/keyed_service.h"
19 #include "components/pref_registry/pref_registry_syncable.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/notification_service.h"
22 #include "content/public/browser/notification_source.h"
23 #include "content/public/browser/user_metrics.h"
24 #include "extensions/common/constants.h"
25 #include "net/base/net_errors.h"
26 #include "net/base/static_cookie_policy.h"
29 using base::UserMetricsAction
;
30 using content::BrowserThread
;
34 bool IsValidSetting(ContentSetting setting
) {
35 return (setting
== CONTENT_SETTING_ALLOW
||
36 setting
== CONTENT_SETTING_SESSION_ONLY
||
37 setting
== CONTENT_SETTING_BLOCK
);
40 bool IsAllowed(ContentSetting setting
) {
41 DCHECK(IsValidSetting(setting
));
42 return (setting
== CONTENT_SETTING_ALLOW
||
43 setting
== CONTENT_SETTING_SESSION_ONLY
);
49 scoped_refptr
<CookieSettings
> CookieSettings::Factory::GetForProfile(
51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
52 return static_cast<CookieSettings
*>(
53 GetInstance()->GetServiceForBrowserContext(profile
, true).get());
57 CookieSettings::Factory
* CookieSettings::Factory::GetInstance() {
58 return Singleton
<CookieSettings::Factory
>::get();
61 CookieSettings::Factory::Factory()
62 : RefcountedBrowserContextKeyedServiceFactory(
64 BrowserContextDependencyManager::GetInstance()) {
67 CookieSettings::Factory::~Factory() {}
69 void CookieSettings::Factory::RegisterProfilePrefs(
70 user_prefs::PrefRegistrySyncable
* registry
) {
71 registry
->RegisterBooleanPref(
72 prefs::kBlockThirdPartyCookies
,
74 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
77 content::BrowserContext
* CookieSettings::Factory::GetBrowserContextToUse(
78 content::BrowserContext
* context
) const {
79 return chrome::GetBrowserContextRedirectedInIncognito(context
);
82 scoped_refptr
<RefcountedBrowserContextKeyedService
>
83 CookieSettings::Factory::BuildServiceInstanceFor(
84 content::BrowserContext
* context
) const {
85 Profile
* profile
= static_cast<Profile
*>(context
);
86 return new CookieSettings(profile
->GetHostContentSettingsMap(),
90 CookieSettings::CookieSettings(
91 HostContentSettingsMap
* host_content_settings_map
,
93 : host_content_settings_map_(host_content_settings_map
),
94 block_third_party_cookies_(
95 prefs
->GetBoolean(prefs::kBlockThirdPartyCookies
)) {
96 if (block_third_party_cookies_
) {
97 content::RecordAction(
98 UserMetricsAction("ThirdPartyCookieBlockingEnabled"));
100 content::RecordAction(
101 UserMetricsAction("ThirdPartyCookieBlockingDisabled"));
104 pref_change_registrar_
.Init(prefs
);
105 pref_change_registrar_
.Add(
106 prefs::kBlockThirdPartyCookies
,
107 base::Bind(&CookieSettings::OnBlockThirdPartyCookiesChanged
,
108 base::Unretained(this)));
112 CookieSettings::GetDefaultCookieSetting(std::string
* provider_id
) const {
113 return host_content_settings_map_
->GetDefaultContentSetting(
114 CONTENT_SETTINGS_TYPE_COOKIES
, provider_id
);
117 bool CookieSettings::IsReadingCookieAllowed(const GURL
& url
,
118 const GURL
& first_party_url
) const {
119 ContentSetting setting
= GetCookieSetting(url
, first_party_url
, false, NULL
);
120 return IsAllowed(setting
);
123 bool CookieSettings::IsSettingCookieAllowed(const GURL
& url
,
124 const GURL
& first_party_url
) const {
125 ContentSetting setting
= GetCookieSetting(url
, first_party_url
, true, NULL
);
126 return IsAllowed(setting
);
129 bool CookieSettings::IsCookieSessionOnly(const GURL
& origin
) const {
130 ContentSetting setting
= GetCookieSetting(origin
, origin
, true, NULL
);
131 DCHECK(IsValidSetting(setting
));
132 return (setting
== CONTENT_SETTING_SESSION_ONLY
);
135 void CookieSettings::GetCookieSettings(
136 ContentSettingsForOneType
* settings
) const {
137 return host_content_settings_map_
->GetSettingsForOneType(
138 CONTENT_SETTINGS_TYPE_COOKIES
, std::string(), settings
);
141 void CookieSettings::SetDefaultCookieSetting(ContentSetting setting
) {
142 DCHECK(IsValidSetting(setting
));
143 host_content_settings_map_
->SetDefaultContentSetting(
144 CONTENT_SETTINGS_TYPE_COOKIES
, setting
);
147 void CookieSettings::SetCookieSetting(
148 const ContentSettingsPattern
& primary_pattern
,
149 const ContentSettingsPattern
& secondary_pattern
,
150 ContentSetting setting
) {
151 DCHECK(IsValidSetting(setting
));
152 if (setting
== CONTENT_SETTING_SESSION_ONLY
) {
153 DCHECK(secondary_pattern
== ContentSettingsPattern::Wildcard());
155 host_content_settings_map_
->SetContentSetting(primary_pattern
,
157 CONTENT_SETTINGS_TYPE_COOKIES
,
162 void CookieSettings::ResetCookieSetting(
163 const ContentSettingsPattern
& primary_pattern
,
164 const ContentSettingsPattern
& secondary_pattern
) {
165 host_content_settings_map_
->SetContentSetting(primary_pattern
,
167 CONTENT_SETTINGS_TYPE_COOKIES
,
169 CONTENT_SETTING_DEFAULT
);
172 void CookieSettings::ShutdownOnUIThread() {
173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
174 pref_change_registrar_
.RemoveAll();
177 ContentSetting
CookieSettings::GetCookieSetting(
179 const GURL
& first_party_url
,
181 content_settings::SettingSource
* source
) const {
182 if (HostContentSettingsMap::ShouldAllowAllContent(
183 url
, first_party_url
, CONTENT_SETTINGS_TYPE_COOKIES
))
184 return CONTENT_SETTING_ALLOW
;
186 // First get any host-specific settings.
187 content_settings::SettingInfo info
;
188 scoped_ptr
<base::Value
> value(host_content_settings_map_
->GetWebsiteSetting(
191 CONTENT_SETTINGS_TYPE_COOKIES
,
195 *source
= info
.source
;
197 // If no explicit exception has been made and third-party cookies are blocked
198 // by default, apply that rule.
199 if (info
.primary_pattern
.MatchesAllHosts() &&
200 info
.secondary_pattern
.MatchesAllHosts() &&
201 ShouldBlockThirdPartyCookies() &&
202 !first_party_url
.SchemeIs(extensions::kExtensionScheme
)) {
203 net::StaticCookiePolicy
policy(
204 net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES
);
207 rv
= policy
.CanSetCookie(url
, first_party_url
);
209 rv
= policy
.CanGetCookies(url
, first_party_url
);
210 DCHECK_NE(net::ERR_IO_PENDING
, rv
);
212 return CONTENT_SETTING_BLOCK
;
215 // We should always have a value, at least from the default provider.
217 return content_settings::ValueToContentSetting(value
.get());
220 CookieSettings::~CookieSettings() {}
222 void CookieSettings::OnBlockThirdPartyCookiesChanged() {
223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
225 base::AutoLock
auto_lock(lock_
);
226 block_third_party_cookies_
= pref_change_registrar_
.prefs()->GetBoolean(
227 prefs::kBlockThirdPartyCookies
);
230 bool CookieSettings::ShouldBlockThirdPartyCookies() const {
231 base::AutoLock
auto_lock(lock_
);
232 return block_third_party_cookies_
;