OLD | NEW |
(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 "chrome/browser/content_settings/content_settings_utils.h" |
| 9 #include "chrome/browser/content_settings/host_content_settings_map.h" |
| 10 #include "chrome/browser/prefs/pref_service.h" |
| 11 #include "chrome/browser/profiles/profile.h" |
| 12 #include "chrome/browser/profiles/profile_dependency_manager.h" |
| 13 #include "chrome/browser/profiles/profile_keyed_service.h" |
| 14 #include "chrome/common/chrome_notification_types.h" |
| 15 #include "chrome/common/chrome_switches.h" |
| 16 #include "chrome/common/content_settings_pattern.h" |
| 17 #include "chrome/common/pref_names.h" |
| 18 #include "content/browser/browser_thread.h" |
| 19 #include "content/browser/user_metrics.h" |
| 20 #include "content/public/browser/notification_service.h" |
| 21 #include "content/public/browser/notification_source.h" |
| 22 #include "googleurl/src/gurl.h" |
| 23 #include "net/base/net_errors.h" |
| 24 #include "net/base/static_cookie_policy.h" |
| 25 |
| 26 namespace { |
| 27 |
| 28 bool IsValidSetting(ContentSetting setting) { |
| 29 return (setting == CONTENT_SETTING_ALLOW || |
| 30 setting == CONTENT_SETTING_SESSION_ONLY || |
| 31 setting == CONTENT_SETTING_BLOCK); |
| 32 } |
| 33 |
| 34 bool IsAllowed(ContentSetting setting) { |
| 35 DCHECK(IsValidSetting(setting)); |
| 36 return (setting == CONTENT_SETTING_ALLOW || |
| 37 setting == CONTENT_SETTING_SESSION_ONLY); |
| 38 } |
| 39 |
| 40 } // namespace |
| 41 |
| 42 // |ProfileKeyedFactory| is the owner of the |ProfileKeyedService|s. This |
| 43 // wrapper class allows others to hold shared pointers to CookieSettings. |
| 44 class CookieSettingsWrapper : public ProfileKeyedService { |
| 45 public: |
| 46 explicit CookieSettingsWrapper(scoped_refptr<CookieSettings> cookie_settings) |
| 47 : cookie_settings_(cookie_settings) {} |
| 48 virtual ~CookieSettingsWrapper() {} |
| 49 |
| 50 CookieSettings* cookie_settings() { return cookie_settings_.get(); } |
| 51 |
| 52 private: |
| 53 // ProfileKeyedService methods: |
| 54 virtual void Shutdown() OVERRIDE { |
| 55 cookie_settings_->ShutdownOnUIThread(); |
| 56 } |
| 57 |
| 58 scoped_refptr<CookieSettings> cookie_settings_; |
| 59 }; |
| 60 |
| 61 // static |
| 62 CookieSettings::Factory* CookieSettings::Factory::GetInstance() { |
| 63 return Singleton<CookieSettings::Factory>::get(); |
| 64 } |
| 65 |
| 66 CookieSettingsWrapper* CookieSettings::Factory::GetWrapperForProfile( |
| 67 Profile* profile) { |
| 68 return static_cast<CookieSettingsWrapper*>( |
| 69 GetServiceForProfile(profile,true)); |
| 70 } |
| 71 |
| 72 CookieSettings::Factory::Factory() |
| 73 : ProfileKeyedServiceFactory(ProfileDependencyManager::GetInstance()) { |
| 74 } |
| 75 |
| 76 ProfileKeyedService* CookieSettings::Factory::BuildServiceInstanceFor( |
| 77 Profile* profile) const { |
| 78 scoped_refptr<CookieSettings> cookie_settings = new CookieSettings( |
| 79 profile->GetHostContentSettingsMap(), |
| 80 profile->GetPrefs()); |
| 81 return new CookieSettingsWrapper(cookie_settings); |
| 82 } |
| 83 |
| 84 CookieSettings::CookieSettings( |
| 85 HostContentSettingsMap* host_content_settings_map, |
| 86 PrefService* prefs) |
| 87 : host_content_settings_map_(host_content_settings_map), |
| 88 block_third_party_cookies_( |
| 89 prefs->GetBoolean(prefs::kBlockThirdPartyCookies)) { |
| 90 if (block_third_party_cookies_) { |
| 91 UserMetrics::RecordAction( |
| 92 UserMetricsAction("ThirdPartyCookieBlockingEnabled")); |
| 93 } else { |
| 94 UserMetrics::RecordAction( |
| 95 UserMetricsAction("ThirdPartyCookieBlockingDisabled")); |
| 96 } |
| 97 |
| 98 pref_change_registrar_.Init(prefs); |
| 99 pref_change_registrar_.Add(prefs::kBlockThirdPartyCookies, this); |
| 100 } |
| 101 |
| 102 CookieSettings::~CookieSettings() { |
| 103 } |
| 104 |
| 105 // static |
| 106 CookieSettings* CookieSettings::GetForProfile(Profile* profile) { |
| 107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 108 CookieSettings* cookie_settings = |
| 109 Factory::GetInstance()->GetWrapperForProfile(profile)->cookie_settings(); |
| 110 DCHECK(cookie_settings); |
| 111 return cookie_settings; |
| 112 } |
| 113 |
| 114 ContentSetting |
| 115 CookieSettings::GetDefaultCookieSetting(std::string* provider_id) const { |
| 116 return host_content_settings_map_->GetDefaultContentSetting( |
| 117 CONTENT_SETTINGS_TYPE_COOKIES, provider_id); |
| 118 } |
| 119 |
| 120 bool CookieSettings::IsReadingCookieAllowed(const GURL& url, |
| 121 const GURL& first_party_url) const { |
| 122 ContentSetting setting = GetCookieSetting(url, first_party_url, false); |
| 123 return IsAllowed(setting); |
| 124 } |
| 125 |
| 126 bool CookieSettings::IsSettingCookieAllowed(const GURL& url, |
| 127 const GURL& first_party_url) const { |
| 128 ContentSetting setting = GetCookieSetting(url, first_party_url, true); |
| 129 return IsAllowed(setting); |
| 130 } |
| 131 |
| 132 bool CookieSettings::IsCookieSessionOnly(const GURL& origin) const { |
| 133 ContentSetting setting = GetCookieSetting(origin, origin, true); |
| 134 DCHECK(IsValidSetting(setting)); |
| 135 return (setting == CONTENT_SETTING_SESSION_ONLY); |
| 136 } |
| 137 |
| 138 void CookieSettings::GetCookieSettings( |
| 139 ContentSettingsForOneType* settings) const { |
| 140 return host_content_settings_map_->GetSettingsForOneType( |
| 141 CONTENT_SETTINGS_TYPE_COOKIES, "", settings); |
| 142 } |
| 143 |
| 144 void CookieSettings::SetDefaultCookieSetting(ContentSetting setting) { |
| 145 DCHECK(IsValidSetting(setting)); |
| 146 host_content_settings_map_->SetDefaultContentSetting( |
| 147 CONTENT_SETTINGS_TYPE_COOKIES, setting); |
| 148 } |
| 149 |
| 150 void CookieSettings::SetCookieSetting( |
| 151 const ContentSettingsPattern& primary_pattern, |
| 152 const ContentSettingsPattern& secondary_pattern, |
| 153 ContentSetting setting) { |
| 154 DCHECK(IsValidSetting(setting)); |
| 155 if (setting == CONTENT_SETTING_SESSION_ONLY) { |
| 156 DCHECK(secondary_pattern == ContentSettingsPattern::Wildcard()); |
| 157 } |
| 158 host_content_settings_map_->SetContentSetting( |
| 159 primary_pattern, secondary_pattern, CONTENT_SETTINGS_TYPE_COOKIES, "", |
| 160 setting); |
| 161 } |
| 162 |
| 163 void CookieSettings::ResetCookieSetting( |
| 164 const ContentSettingsPattern& primary_pattern, |
| 165 const ContentSettingsPattern& secondary_pattern) { |
| 166 host_content_settings_map_->SetContentSetting( |
| 167 primary_pattern, secondary_pattern, CONTENT_SETTINGS_TYPE_COOKIES, "", |
| 168 CONTENT_SETTING_DEFAULT); |
| 169 } |
| 170 |
| 171 void CookieSettings::Observe(int type, |
| 172 const content::NotificationSource& source, |
| 173 const content::NotificationDetails& details) { |
| 174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 175 |
| 176 if (type == chrome::NOTIFICATION_PREF_CHANGED) { |
| 177 PrefService* prefs = content::Source<PrefService>(source).ptr(); |
| 178 std::string* name = content::Details<std::string>(details).ptr(); |
| 179 if (*name == prefs::kBlockThirdPartyCookies) { |
| 180 base::AutoLock auto_lock(lock_); |
| 181 block_third_party_cookies_ = prefs->GetBoolean( |
| 182 prefs::kBlockThirdPartyCookies); |
| 183 } else { |
| 184 NOTREACHED() << "Unexpected preference observed"; |
| 185 return; |
| 186 } |
| 187 } else { |
| 188 NOTREACHED() << "Unexpected notification"; |
| 189 } |
| 190 } |
| 191 |
| 192 void CookieSettings::ShutdownOnUIThread() { |
| 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 194 pref_change_registrar_.RemoveAll(); |
| 195 } |
| 196 |
| 197 ContentSetting CookieSettings::GetCookieSetting( |
| 198 const GURL& url, |
| 199 const GURL& first_party_url, |
| 200 bool setting_cookie) const { |
| 201 if (HostContentSettingsMap::ShouldAllowAllContent( |
| 202 first_party_url, |
| 203 CONTENT_SETTINGS_TYPE_COOKIES)) { |
| 204 return CONTENT_SETTING_ALLOW; |
| 205 } |
| 206 |
| 207 ContentSettingsPattern primary_pattern; |
| 208 ContentSettingsPattern secondary_pattern; |
| 209 // First get any host-specific settings. |
| 210 scoped_ptr<base::Value> value( |
| 211 host_content_settings_map_->GetContentSettingValue( |
| 212 url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, "", |
| 213 &primary_pattern, &secondary_pattern)); |
| 214 |
| 215 // If no explicit exception has been made and third-party cookies are blocked |
| 216 // by default, apply that rule. |
| 217 if (primary_pattern == ContentSettingsPattern::Wildcard() && |
| 218 secondary_pattern == ContentSettingsPattern::Wildcard() && |
| 219 ShouldBlockThirdPartyCookies()) { |
| 220 bool strict = CommandLine::ForCurrentProcess()->HasSwitch( |
| 221 switches::kBlockReadingThirdPartyCookies); |
| 222 net::StaticCookiePolicy policy(strict ? |
| 223 net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES : |
| 224 net::StaticCookiePolicy::BLOCK_SETTING_THIRD_PARTY_COOKIES); |
| 225 int rv; |
| 226 if (setting_cookie) |
| 227 rv = policy.CanSetCookie(url, first_party_url); |
| 228 else |
| 229 rv = policy.CanGetCookies(url, first_party_url); |
| 230 DCHECK_NE(net::ERR_IO_PENDING, rv); |
| 231 if (rv != net::OK) |
| 232 return CONTENT_SETTING_BLOCK; |
| 233 } |
| 234 |
| 235 // We should always have a value, at least from the default provider. |
| 236 DCHECK(value.get()); |
| 237 return content_settings::ValueToContentSetting(value.get()); |
| 238 } |
| 239 |
| 240 // static |
| 241 void CookieSettings::RegisterUserPrefs(PrefService* prefs) { |
| 242 prefs->RegisterBooleanPref(prefs::kBlockThirdPartyCookies, |
| 243 false, |
| 244 PrefService::SYNCABLE_PREF); |
| 245 } |
| 246 |
| 247 bool CookieSettings::ShouldBlockThirdPartyCookies() const { |
| 248 base::AutoLock auto_lock(lock_); |
| 249 return block_third_party_cookies_; |
| 250 } |
OLD | NEW |