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/prefs/pref_service.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/profiles/incognito_helpers.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/common/pref_names.h"
12 #include "components/content_settings/core/browser/content_settings_utils.h"
13 #include "components/content_settings/core/browser/host_content_settings_map.h"
14 #include "components/content_settings/core/common/content_settings_pattern.h"
15 #include "components/keyed_service/content/browser_context_dependency_manager.h"
16 #include "components/keyed_service/core/keyed_service.h"
17 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/user_metrics.h"
22 #include "extensions/common/constants.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/static_cookie_policy.h"
27 using base::UserMetricsAction
;
28 using content::BrowserThread
;
32 bool IsValidSetting(ContentSetting setting
) {
33 return (setting
== CONTENT_SETTING_ALLOW
||
34 setting
== CONTENT_SETTING_SESSION_ONLY
||
35 setting
== CONTENT_SETTING_BLOCK
);
38 bool IsAllowed(ContentSetting setting
) {
39 DCHECK(IsValidSetting(setting
));
40 return (setting
== CONTENT_SETTING_ALLOW
||
41 setting
== CONTENT_SETTING_SESSION_ONLY
);
47 scoped_refptr
<CookieSettings
> CookieSettings::Factory::GetForProfile(
49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
50 return static_cast<CookieSettings
*>(
51 GetInstance()->GetServiceForBrowserContext(profile
, true).get());
55 CookieSettings::Factory
* CookieSettings::Factory::GetInstance() {
56 return Singleton
<CookieSettings::Factory
>::get();
59 CookieSettings::Factory::Factory()
60 : RefcountedBrowserContextKeyedServiceFactory(
62 BrowserContextDependencyManager::GetInstance()) {
65 CookieSettings::Factory::~Factory() {}
67 void CookieSettings::Factory::RegisterProfilePrefs(
68 user_prefs::PrefRegistrySyncable
* registry
) {
69 registry
->RegisterBooleanPref(
70 prefs::kBlockThirdPartyCookies
,
72 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
75 content::BrowserContext
* CookieSettings::Factory::GetBrowserContextToUse(
76 content::BrowserContext
* context
) const {
77 return chrome::GetBrowserContextRedirectedInIncognito(context
);
80 scoped_refptr
<RefcountedKeyedService
>
81 CookieSettings::Factory::BuildServiceInstanceFor(
82 content::BrowserContext
* context
) const {
83 Profile
* profile
= static_cast<Profile
*>(context
);
84 return new CookieSettings(profile
->GetHostContentSettingsMap(),
88 CookieSettings::CookieSettings(
89 HostContentSettingsMap
* host_content_settings_map
,
91 : host_content_settings_map_(host_content_settings_map
),
92 block_third_party_cookies_(
93 prefs
->GetBoolean(prefs::kBlockThirdPartyCookies
)) {
94 if (block_third_party_cookies_
) {
95 content::RecordAction(
96 UserMetricsAction("ThirdPartyCookieBlockingEnabled"));
98 content::RecordAction(
99 UserMetricsAction("ThirdPartyCookieBlockingDisabled"));
102 pref_change_registrar_
.Init(prefs
);
103 pref_change_registrar_
.Add(
104 prefs::kBlockThirdPartyCookies
,
105 base::Bind(&CookieSettings::OnBlockThirdPartyCookiesChanged
,
106 base::Unretained(this)));
110 CookieSettings::GetDefaultCookieSetting(std::string
* provider_id
) const {
111 return host_content_settings_map_
->GetDefaultContentSetting(
112 CONTENT_SETTINGS_TYPE_COOKIES
, provider_id
);
115 bool CookieSettings::IsReadingCookieAllowed(const GURL
& url
,
116 const GURL
& first_party_url
) const {
117 ContentSetting setting
= GetCookieSetting(url
, first_party_url
, false, NULL
);
118 return IsAllowed(setting
);
121 bool CookieSettings::IsSettingCookieAllowed(const GURL
& url
,
122 const GURL
& first_party_url
) const {
123 ContentSetting setting
= GetCookieSetting(url
, first_party_url
, true, NULL
);
124 return IsAllowed(setting
);
127 bool CookieSettings::IsCookieSessionOnly(const GURL
& origin
) const {
128 ContentSetting setting
= GetCookieSetting(origin
, origin
, true, NULL
);
129 DCHECK(IsValidSetting(setting
));
130 return (setting
== CONTENT_SETTING_SESSION_ONLY
);
133 void CookieSettings::GetCookieSettings(
134 ContentSettingsForOneType
* settings
) const {
135 return host_content_settings_map_
->GetSettingsForOneType(
136 CONTENT_SETTINGS_TYPE_COOKIES
, std::string(), settings
);
139 void CookieSettings::SetDefaultCookieSetting(ContentSetting setting
) {
140 DCHECK(IsValidSetting(setting
));
141 host_content_settings_map_
->SetDefaultContentSetting(
142 CONTENT_SETTINGS_TYPE_COOKIES
, setting
);
145 void CookieSettings::SetCookieSetting(
146 const ContentSettingsPattern
& primary_pattern
,
147 const ContentSettingsPattern
& secondary_pattern
,
148 ContentSetting setting
) {
149 DCHECK(IsValidSetting(setting
));
150 if (setting
== CONTENT_SETTING_SESSION_ONLY
) {
151 DCHECK(secondary_pattern
== ContentSettingsPattern::Wildcard());
153 host_content_settings_map_
->SetContentSetting(primary_pattern
,
155 CONTENT_SETTINGS_TYPE_COOKIES
,
160 void CookieSettings::ResetCookieSetting(
161 const ContentSettingsPattern
& primary_pattern
,
162 const ContentSettingsPattern
& secondary_pattern
) {
163 host_content_settings_map_
->SetContentSetting(primary_pattern
,
165 CONTENT_SETTINGS_TYPE_COOKIES
,
167 CONTENT_SETTING_DEFAULT
);
170 void CookieSettings::ShutdownOnUIThread() {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
172 pref_change_registrar_
.RemoveAll();
175 ContentSetting
CookieSettings::GetCookieSetting(
177 const GURL
& first_party_url
,
179 content_settings::SettingSource
* source
) const {
180 if (HostContentSettingsMap::ShouldAllowAllContent(
181 url
, first_party_url
, CONTENT_SETTINGS_TYPE_COOKIES
))
182 return CONTENT_SETTING_ALLOW
;
184 // First get any host-specific settings.
185 content_settings::SettingInfo info
;
186 scoped_ptr
<base::Value
> value
= host_content_settings_map_
->GetWebsiteSetting(
189 CONTENT_SETTINGS_TYPE_COOKIES
,
193 *source
= info
.source
;
195 // If no explicit exception has been made and third-party cookies are blocked
196 // by default, apply that rule.
197 if (info
.primary_pattern
.MatchesAllHosts() &&
198 info
.secondary_pattern
.MatchesAllHosts() &&
199 ShouldBlockThirdPartyCookies() &&
200 !first_party_url
.SchemeIs(extensions::kExtensionScheme
)) {
201 net::StaticCookiePolicy
policy(
202 net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES
);
205 rv
= policy
.CanSetCookie(url
, first_party_url
);
207 rv
= policy
.CanGetCookies(url
, first_party_url
);
208 DCHECK_NE(net::ERR_IO_PENDING
, rv
);
210 return CONTENT_SETTING_BLOCK
;
213 // We should always have a value, at least from the default provider.
215 return content_settings::ValueToContentSetting(value
.get());
218 CookieSettings::~CookieSettings() {}
220 void CookieSettings::OnBlockThirdPartyCookiesChanged() {
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
223 base::AutoLock
auto_lock(lock_
);
224 block_third_party_cookies_
= pref_change_registrar_
.prefs()->GetBoolean(
225 prefs::kBlockThirdPartyCookies
);
228 bool CookieSettings::ShouldBlockThirdPartyCookies() const {
229 base::AutoLock
auto_lock(lock_
);
230 return block_third_party_cookies_
;