Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: chrome/browser/content_settings/cookie_settings.cc

Issue 7713034: HostContentSettingsMap refactoring. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Keeping up to date with trunk. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/memory/singleton.h"
9 #include "chrome/browser/content_settings/content_settings_pattern.h"
10 #include "chrome/browser/content_settings/host_content_settings_map.h"
11 #include "chrome/browser/prefs/pref_service.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/profiles/profile_dependency_manager.h"
14 #include "chrome/browser/profiles/profile_keyed_service.h"
15 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
16 #include "chrome/common/chrome_notification_types.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/pref_names.h"
19 #include "content/browser/browser_thread.h"
20 #include "content/browser/user_metrics.h"
21 #include "content/common/notification_service.h"
22 #include "content/common/notification_source.h"
23 #include "googleurl/src/gurl.h"
24 #include "net/base/net_errors.h"
25 #include "net/base/static_cookie_policy.h"
26
27 namespace {
28
29 // ProfileKeyedFactory is the owner of the ProfileKeyedServices. This wrapper
30 // class allows others to hold shared pointers to CookieSettings.
31 class CookieSettingsWrapper : public ProfileKeyedService {
32 public:
33 explicit CookieSettingsWrapper(scoped_refptr<CookieSettings> cookie_settings)
34 : cookie_settings_(cookie_settings) {}
35 virtual ~CookieSettingsWrapper() {}
36
37 CookieSettings* cookie_settings() { return cookie_settings_.get(); }
38
39 private:
40 // ProfileKeyedService methods:
41 virtual void Shutdown() OVERRIDE {
42 cookie_settings_->ShutdownOnUIThread();
43 }
44
45 scoped_refptr<CookieSettings> cookie_settings_;
46 };
47
48 // Helper functions for converting cookie settings.
49
50 // Converts a single cookie content setting into a content setting pair for
51 // (cookies, permanent cookies).
52 void ConvertCookieSettingToSettingPair(
53 ContentSetting setting, ContentSetting* cookies_allowed,
54 ContentSetting* permanent_cookies_allowed) {
55 *cookies_allowed = CONTENT_SETTING_BLOCK;
56 *permanent_cookies_allowed = CONTENT_SETTING_ALLOW;
57 if (setting == CONTENT_SETTING_ALLOW ||
58 setting == CONTENT_SETTING_SESSION_ONLY)
59 *cookies_allowed = CONTENT_SETTING_ALLOW;
60 if (setting == CONTENT_SETTING_SESSION_ONLY)
61 *permanent_cookies_allowed = CONTENT_SETTING_BLOCK;
62 }
63
64 // Converts the content settings pair (cookies, permanent cookies) into a
65 // single content setting.
66 ContentSetting ConvertSettingPairToCookieSetting(
67 ContentSetting cookies_allowed, ContentSetting permanent_cookies_allowed) {
68 DCHECK(cookies_allowed == CONTENT_SETTING_ALLOW ||
69 cookies_allowed == CONTENT_SETTING_BLOCK);
70 DCHECK(permanent_cookies_allowed == CONTENT_SETTING_ALLOW ||
71 permanent_cookies_allowed == CONTENT_SETTING_BLOCK);
72 if (cookies_allowed == CONTENT_SETTING_BLOCK)
73 return CONTENT_SETTING_BLOCK;
74 if (permanent_cookies_allowed == CONTENT_SETTING_ALLOW)
75 return CONTENT_SETTING_ALLOW;
76 return CONTENT_SETTING_SESSION_ONLY;
77 }
78
79 } // namespace
80
81 class CookieSettings::Factory : public ProfileKeyedServiceFactory {
82 public:
83 static Factory* GetInstance();
84
85 CookieSettingsWrapper* GetWrapperForProfile(Profile* profile);
86
87 private:
88 friend struct DefaultSingletonTraits<Factory>;
89
90 Factory();
91 virtual ~Factory() {}
92
93 // PrefoileKeyedServiceFactory methods:
Bernhard Bauer 2011/09/14 16:01:36 Nit: ProfileKeyedServiceFactory
94 virtual CookieSettingsWrapper* BuildServiceInstanceFor(
95 Profile* profile) const OVERRIDE;
96 virtual bool ServiceRedirectedInIncognito() OVERRIDE { return true; }
97 };
98
99 // static
100 CookieSettings::Factory* CookieSettings::Factory::GetInstance() {
101 return Singleton<CookieSettings::Factory>::get();
102 }
103
104 CookieSettingsWrapper* CookieSettings::Factory::GetWrapperForProfile(
105 Profile* profile) {
106 return static_cast<CookieSettingsWrapper*>(
107 GetServiceForProfile(profile,true));
108 }
109
110 CookieSettings::Factory::Factory()
111 : ProfileKeyedServiceFactory(ProfileDependencyManager::GetInstance()) {
112 }
113
114 CookieSettingsWrapper* CookieSettings::Factory::BuildServiceInstanceFor(
115 Profile* profile) const {
116 scoped_refptr<CookieSettings> cookie_settings = new CookieSettings(
117 profile->GetHostContentSettingsMap(),
118 profile->GetPrefs());
119 return new CookieSettingsWrapper(cookie_settings);
120 }
121
122 CookieSettings::CookieSettings(
123 HostContentSettingsMap* host_content_settings_map,
124 PrefService* prefs)
125 : host_content_settings_map_(host_content_settings_map),
126 block_third_party_cookies_(
127 prefs->GetBoolean(prefs::kBlockThirdPartyCookies)) {
128 if (block_third_party_cookies_) {
129 UserMetrics::RecordAction(
130 UserMetricsAction("ThirdPartyCookieBlockingEnabled"));
131 } else {
132 UserMetrics::RecordAction(
133 UserMetricsAction("ThirdPartyCookieBlockingDisabled"));
134 }
135
136 pref_change_registrar_.Init(prefs);
137 pref_change_registrar_.Add(prefs::kBlockThirdPartyCookies, this);
138 }
139
140 CookieSettings::~CookieSettings() {
141 }
142
143 // static
144 CookieSettings* CookieSettings::GetForProfile(Profile* profile) {
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
146 CookieSettings* cookie_settings =
147 Factory::GetInstance()->GetWrapperForProfile(profile)->cookie_settings();
148 DCHECK(cookie_settings);
149 return cookie_settings;
150 }
151
152 ContentSetting CookieSettings::GetDefaultCookieSetting() const {
153 ContentSetting cookies_allowed =
154 host_content_settings_map_->GetDefaultContentSetting(
155 CONTENT_SETTINGS_TYPE_COOKIES);
156 ContentSetting permanent_cookies_allowed =
157 host_content_settings_map_->GetDefaultContentSetting(
158 CONTENT_SETTINGS_TYPE_PERMANENT_COOKIES);
159 return ConvertSettingPairToCookieSetting(
160 cookies_allowed, permanent_cookies_allowed);
161 }
162
163 bool CookieSettings::IsReadingCookieAllowed(const GURL& url,
164 const GURL& first_party_url) const {
165 ContentSetting setting = GetCookieContentSetting(
166 url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, false);
167 DCHECK(setting == CONTENT_SETTING_ALLOW ||
168 setting == CONTENT_SETTING_BLOCK);
169 return setting == CONTENT_SETTING_ALLOW;
170 }
171
172 bool CookieSettings::IsSettingCookieAllowed(const GURL& url,
173 const GURL& first_party_url) const {
174 ContentSetting setting = GetCookieContentSetting(
175 url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, true);
176 DCHECK(setting == CONTENT_SETTING_ALLOW ||
177 setting == CONTENT_SETTING_BLOCK);
178 return setting == CONTENT_SETTING_ALLOW;
179 }
180
181 bool CookieSettings::IsCookieSessionOnly(const GURL& origin) const {
182 ContentSetting setting = GetCookieContentSetting(
183 origin, origin, CONTENT_SETTINGS_TYPE_PERMANENT_COOKIES, true);
184 DCHECK(setting == CONTENT_SETTING_ALLOW ||
185 setting == CONTENT_SETTING_BLOCK);
186 return (setting == CONTENT_SETTING_BLOCK);
187 }
188
189 void CookieSettings::GetCookieSettings(
190 HostContentSettingsMap::SettingsForOneType* settings) const {
191 DCHECK(settings);
192 settings->clear();
193
194 // cookie_settings and permanent_cookie_settings will contain the same
Bernhard Bauer 2011/09/14 16:01:36 Nit: Please add bars around |cookie_settings| and
195 // elements, since all exceptions are stored for both content types.
196 HostContentSettingsMap::SettingsForOneType cookie_settings;
197 host_content_settings_map_->GetSettingsForOneType(
198 CONTENT_SETTINGS_TYPE_COOKIES, "", &cookie_settings);
199 HostContentSettingsMap::SettingsForOneType permanent_cookie_settings;
200 host_content_settings_map_->GetSettingsForOneType(
201 CONTENT_SETTINGS_TYPE_PERMANENT_COOKIES, "", &permanent_cookie_settings);
202 DCHECK(cookie_settings.size() == permanent_cookie_settings.size());
Bernhard Bauer 2011/09/14 16:01:36 If you use DCHECK_EQ(expected, actual) you get nic
203
204 HostContentSettingsMap::PatternSettingSourceTuple setting;
205 setting.b = ContentSettingsPattern::Wildcard();
206 for (size_t i = 0; i < cookie_settings.size(); ++i) {
207 DCHECK(cookie_settings[i].a == permanent_cookie_settings[i].a);
208 setting.a = cookie_settings[i].a;
209 setting.c = ConvertSettingPairToCookieSetting(
210 cookie_settings[i].c, permanent_cookie_settings[i].c);
211 settings->push_back(setting);
212 }
213 }
214
215 void CookieSettings::SetDefaultCookieSetting(ContentSetting setting) {
216 DCHECK(setting == CONTENT_SETTING_ALLOW ||
217 setting == CONTENT_SETTING_SESSION_ONLY ||
218 setting == CONTENT_SETTING_BLOCK);
219 ContentSetting cookies_allowed;
220 ContentSetting permanent_cookies_allowed;
221 ConvertCookieSettingToSettingPair(setting,
222 &cookies_allowed,
223 &permanent_cookies_allowed);
224 host_content_settings_map_->SetDefaultContentSetting(
225 CONTENT_SETTINGS_TYPE_PERMANENT_COOKIES, permanent_cookies_allowed);
226 host_content_settings_map_->SetDefaultContentSetting(
227 CONTENT_SETTINGS_TYPE_COOKIES, cookies_allowed);
228 }
229
230 void CookieSettings::SetCookieSetting(
231 const ContentSettingsPattern& primary_pattern,
232 ContentSetting setting) {
233 DCHECK(setting == CONTENT_SETTING_ALLOW ||
234 setting == CONTENT_SETTING_SESSION_ONLY ||
235 setting == CONTENT_SETTING_BLOCK);
236 ContentSetting cookies_allowed;
237 ContentSetting permanent_cookies_allowed;
238 ConvertCookieSettingToSettingPair(setting,
239 &cookies_allowed,
240 &permanent_cookies_allowed);
241 // Set CONTENT_SETTINGS_TYPE_PERMANENT_COOKIES first; when clients monitoring
242 // CONTENT_SETTINGS_TYPE_COOKIES get a notification, we're already in a
243 // consistent state.
244 host_content_settings_map_->SetContentSetting(
245 primary_pattern, ContentSettingsPattern::Wildcard(),
246 CONTENT_SETTINGS_TYPE_PERMANENT_COOKIES, "",
247 permanent_cookies_allowed);
248 host_content_settings_map_->SetContentSetting(
249 primary_pattern, ContentSettingsPattern::Wildcard(),
250 CONTENT_SETTINGS_TYPE_COOKIES, "",
251 cookies_allowed);
252 }
253
254 void CookieSettings::ResetCookieSetting(
255 const ContentSettingsPattern& primary_pattern) {
256 // Set CONTENT_SETTINGS_TYPE_PERMANENT_COOKIES first; when clients monitoring
257 // CONTENT_SETTINGS_TYPE_COOKIES get a notification, we're already in a
258 // consistent state.
259 host_content_settings_map_->SetContentSetting(
260 primary_pattern, ContentSettingsPattern::Wildcard(),
261 CONTENT_SETTINGS_TYPE_PERMANENT_COOKIES, "",
262 CONTENT_SETTING_DEFAULT);
263 host_content_settings_map_->SetContentSetting(
264 primary_pattern, ContentSettingsPattern::Wildcard(),
265 CONTENT_SETTINGS_TYPE_COOKIES, "",
266 CONTENT_SETTING_DEFAULT);
267 }
268
269 void CookieSettings::Observe(int type,
270 const NotificationSource& source,
271 const NotificationDetails& details) {
272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
273
274 if (type == chrome::NOTIFICATION_PREF_CHANGED) {
275 PrefService* prefs = Source<PrefService>(source).ptr();
276
277 std::string* name = Details<std::string>(details).ptr();
278 if (*name == prefs::kBlockThirdPartyCookies) {
279 base::AutoLock auto_lock(lock_);
280 block_third_party_cookies_ = prefs->GetBoolean(
281 prefs::kBlockThirdPartyCookies);
282 } else {
283 NOTREACHED() << "Unexpected preference observed";
284 return;
285 }
286 } else {
287 NOTREACHED() << "Unexpected notification";
288 }
289 }
290
291 void CookieSettings::ShutdownOnUIThread() {
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
293 pref_change_registrar_.RemoveAll();
294 }
295
296 ContentSetting CookieSettings::GetCookieContentSetting(
297 const GURL& url,
298 const GURL& first_party_url,
299 ContentSettingsType content_type,
300 bool setting_cookie) const {
301 if (HostContentSettingsMap::ShouldAllowAllContent(
302 first_party_url, CONTENT_SETTINGS_TYPE_COOKIES))
303 return CONTENT_SETTING_ALLOW;
304
305 // First get any host-specific settings.
306 ContentSetting setting =
307 host_content_settings_map_->GetNonDefaultContentSetting(
308 url, first_party_url, content_type, "");
309
310 // Check if third-party cookie settings deny the cookie. This check makes
311 // sense only for the CONTENT_SETTINGS_TYPE_COOKIES, since the session only
312 // check is based on one url only.
313 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES &&
314 setting == CONTENT_SETTING_DEFAULT &&
315 ShouldBlockThirdPartyCookies()) {
316 bool strict = CommandLine::ForCurrentProcess()->HasSwitch(
317 switches::kBlockReadingThirdPartyCookies);
318 net::StaticCookiePolicy policy(strict ?
319 net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES :
320 net::StaticCookiePolicy::BLOCK_SETTING_THIRD_PARTY_COOKIES);
321 int rv;
322 if (setting_cookie)
323 rv = policy.CanSetCookie(url, first_party_url);
324 else
325 rv = policy.CanGetCookies(url, first_party_url);
326 DCHECK_NE(net::ERR_IO_PENDING, rv);
327 if (rv != net::OK)
328 setting = CONTENT_SETTING_BLOCK;
329 }
330
331 // If no other policy has changed the setting, use the default.
332 if (setting == CONTENT_SETTING_DEFAULT) {
333 setting =
334 host_content_settings_map_->GetDefaultContentSetting(content_type);
335 }
336 return setting;
337 }
338
339 bool CookieSettings::ShouldBlockThirdPartyCookies() const {
340 base::AutoLock auto_lock(lock_);
341 return block_third_party_cookies_;
342 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698