- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / content_settings / cookie_settings.cc
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.
4
5 #include "chrome/browser/content_settings/cookie_settings.h"
6
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/browser_context_keyed_service/browser_context_dependency_manager.h"
18 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
19 #include "components/user_prefs/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"
27 #include "url/gurl.h"
28
29 using content::BrowserThread;
30 using content::UserMetricsAction;
31
32 namespace {
33
34 bool IsValidSetting(ContentSetting setting) {
35   return (setting == CONTENT_SETTING_ALLOW ||
36           setting == CONTENT_SETTING_SESSION_ONLY ||
37           setting == CONTENT_SETTING_BLOCK);
38 }
39
40 bool IsAllowed(ContentSetting setting) {
41   DCHECK(IsValidSetting(setting));
42   return (setting == CONTENT_SETTING_ALLOW ||
43           setting == CONTENT_SETTING_SESSION_ONLY);
44 }
45
46 }  // namespace
47
48 // static
49 scoped_refptr<CookieSettings> CookieSettings::Factory::GetForProfile(
50     Profile* profile) {
51   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
52   return static_cast<CookieSettings*>(
53       GetInstance()->GetServiceForBrowserContext(profile, true).get());
54 }
55
56 // static
57 CookieSettings::Factory* CookieSettings::Factory::GetInstance() {
58   return Singleton<CookieSettings::Factory>::get();
59 }
60
61 CookieSettings::Factory::Factory()
62     : RefcountedBrowserContextKeyedServiceFactory(
63         "CookieSettings",
64         BrowserContextDependencyManager::GetInstance()) {
65 }
66
67 CookieSettings::Factory::~Factory() {}
68
69 void CookieSettings::Factory::RegisterProfilePrefs(
70     user_prefs::PrefRegistrySyncable* registry) {
71   registry->RegisterBooleanPref(
72       prefs::kBlockThirdPartyCookies,
73       false,
74       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
75 }
76
77 content::BrowserContext* CookieSettings::Factory::GetBrowserContextToUse(
78     content::BrowserContext* context) const {
79   return chrome::GetBrowserContextRedirectedInIncognito(context);
80 }
81
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(),
87                             profile->GetPrefs());
88 }
89
90 CookieSettings::CookieSettings(
91     HostContentSettingsMap* host_content_settings_map,
92     PrefService* prefs)
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"));
99   } else {
100     content::RecordAction(
101         UserMetricsAction("ThirdPartyCookieBlockingDisabled"));
102   }
103
104   pref_change_registrar_.Init(prefs);
105   pref_change_registrar_.Add(
106       prefs::kBlockThirdPartyCookies,
107       base::Bind(&CookieSettings::OnBlockThirdPartyCookiesChanged,
108                  base::Unretained(this)));
109 }
110
111 ContentSetting
112 CookieSettings::GetDefaultCookieSetting(std::string* provider_id) const {
113   return host_content_settings_map_->GetDefaultContentSetting(
114       CONTENT_SETTINGS_TYPE_COOKIES, provider_id);
115 }
116
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);
121 }
122
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);
127 }
128
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);
133 }
134
135 void CookieSettings::GetCookieSettings(
136     ContentSettingsForOneType* settings) const {
137   return host_content_settings_map_->GetSettingsForOneType(
138       CONTENT_SETTINGS_TYPE_COOKIES, std::string(), settings);
139 }
140
141 void CookieSettings::SetDefaultCookieSetting(ContentSetting setting) {
142   DCHECK(IsValidSetting(setting));
143   host_content_settings_map_->SetDefaultContentSetting(
144       CONTENT_SETTINGS_TYPE_COOKIES, setting);
145 }
146
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());
154   }
155   host_content_settings_map_->SetContentSetting(primary_pattern,
156                                                 secondary_pattern,
157                                                 CONTENT_SETTINGS_TYPE_COOKIES,
158                                                 std::string(),
159                                                 setting);
160 }
161
162 void CookieSettings::ResetCookieSetting(
163     const ContentSettingsPattern& primary_pattern,
164     const ContentSettingsPattern& secondary_pattern) {
165   host_content_settings_map_->SetContentSetting(primary_pattern,
166                                                 secondary_pattern,
167                                                 CONTENT_SETTINGS_TYPE_COOKIES,
168                                                 std::string(),
169                                                 CONTENT_SETTING_DEFAULT);
170 }
171
172 void CookieSettings::ShutdownOnUIThread() {
173   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
174   pref_change_registrar_.RemoveAll();
175 }
176
177 ContentSetting CookieSettings::GetCookieSetting(
178     const GURL& url,
179     const GURL& first_party_url,
180     bool setting_cookie,
181     content_settings::SettingSource* source) const {
182   if (HostContentSettingsMap::ShouldAllowAllContent(
183         url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES))
184     return CONTENT_SETTING_ALLOW;
185
186   // First get any host-specific settings.
187   content_settings::SettingInfo info;
188   scoped_ptr<base::Value> value(host_content_settings_map_->GetWebsiteSetting(
189       url,
190       first_party_url,
191       CONTENT_SETTINGS_TYPE_COOKIES,
192       std::string(),
193       &info));
194   if (source)
195     *source = info.source;
196
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     bool not_strict = CommandLine::ForCurrentProcess()->HasSwitch(
204         switches::kOnlyBlockSettingThirdPartyCookies);
205     net::StaticCookiePolicy policy(not_strict ?
206         net::StaticCookiePolicy::BLOCK_SETTING_THIRD_PARTY_COOKIES :
207         net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES);
208     int rv;
209     if (setting_cookie)
210       rv = policy.CanSetCookie(url, first_party_url);
211     else
212       rv = policy.CanGetCookies(url, first_party_url);
213     DCHECK_NE(net::ERR_IO_PENDING, rv);
214     if (rv != net::OK)
215       return CONTENT_SETTING_BLOCK;
216   }
217
218   // We should always have a value, at least from the default provider.
219   DCHECK(value.get());
220   return content_settings::ValueToContentSetting(value.get());
221 }
222
223 CookieSettings::~CookieSettings() {}
224
225 void CookieSettings::OnBlockThirdPartyCookiesChanged() {
226   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
227
228   base::AutoLock auto_lock(lock_);
229   block_third_party_cookies_ = pref_change_registrar_.prefs()->GetBoolean(
230       prefs::kBlockThirdPartyCookies);
231 }
232
233 bool CookieSettings::ShouldBlockThirdPartyCookies() const {
234   base::AutoLock auto_lock(lock_);
235   return block_third_party_cookies_;
236 }