diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 21:00:34 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 21:00:34 +0000 |
commit | 15e84d9dad946d522ca6b5acf7db721a4ea76946 (patch) | |
tree | af079dd93c04f3736f10ac77da8a86ce099cc4d2 /chrome/browser/net | |
parent | 1cc71de3863b49ba125576bdff84d739356070fb (diff) | |
download | chromium_src-15e84d9dad946d522ca6b5acf7db721a4ea76946.zip chromium_src-15e84d9dad946d522ca6b5acf7db721a4ea76946.tar.gz chromium_src-15e84d9dad946d522ca6b5acf7db721a4ea76946.tar.bz2 |
Implement extended cookie controls.
BUG=32782
TEST=none
Review URL: http://codereview.chromium.org/554119
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37535 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/net')
-rw-r--r-- | chrome/browser/net/chrome_cookie_policy.cc | 142 | ||||
-rw-r--r-- | chrome/browser/net/chrome_cookie_policy.h | 81 | ||||
-rw-r--r-- | chrome/browser/net/chrome_cookie_policy_unittest.cc | 49 | ||||
-rw-r--r-- | chrome/browser/net/chrome_url_request_context.cc | 28 | ||||
-rw-r--r-- | chrome/browser/net/chrome_url_request_context.h | 11 | ||||
-rw-r--r-- | chrome/browser/net/cookie_policy_browsertest.cc | 9 |
6 files changed, 284 insertions, 36 deletions
diff --git a/chrome/browser/net/chrome_cookie_policy.cc b/chrome/browser/net/chrome_cookie_policy.cc new file mode 100644 index 0000000..fccb737 --- /dev/null +++ b/chrome/browser/net/chrome_cookie_policy.cc @@ -0,0 +1,142 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/chrome_cookie_policy.h" + +#include "base/utf_string_conversions.h" +#include "chrome/browser/profile.h" +#include "chrome/common/pref_service.h" +#include "chrome/common/pref_names.h" +#include "googleurl/src/gurl.h" +#include "net/base/registry_controlled_domain.h" + +ChromeCookiePolicy::ChromeCookiePolicy(Profile* profile) : profile_(profile) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + + const DictionaryValue* cookie_exceptions_dict = + profile_->GetPrefs()->GetDictionary(prefs::kCookieExceptions); + // Careful: The returned value could be NULL if the pref has never been set. + if (cookie_exceptions_dict != NULL) { + for (DictionaryValue::key_iterator i(cookie_exceptions_dict->begin_keys()); + i != cookie_exceptions_dict->end_keys(); ++i) { + std::wstring wide_domain(*i); + int content_settings = 0; + bool success = cookie_exceptions_dict->GetIntegerWithoutPathExpansion( + wide_domain, &content_settings); + DCHECK(success); + per_domain_policy_[WideToUTF8(wide_domain)] = + static_cast<ContentPermissionType>(content_settings); + } + } + net::CookiePolicy::set_type(net::CookiePolicy::FromInt( + profile_->GetPrefs()->GetInteger(prefs::kCookieBehavior))); +} + +// static +void ChromeCookiePolicy::RegisterUserPrefs(PrefService* prefs) { + prefs->RegisterDictionaryPref(prefs::kCookieExceptions); + prefs->RegisterIntegerPref(prefs::kCookieBehavior, + net::CookiePolicy::ALLOW_ALL_COOKIES); +} + +void ChromeCookiePolicy::ResetToDefaults() { + net::CookiePolicy::set_type(net::CookiePolicy::ALLOW_ALL_COOKIES); + per_domain_policy_.clear(); + profile_->GetPrefs()->ClearPref(prefs::kCookieBehavior); + profile_->GetPrefs()->ClearPref(prefs::kCookieExceptions); +} + +bool ChromeCookiePolicy::CanGetCookies(const GURL& url, + const GURL& first_party_for_cookies) { + AutoLock auto_lock(lock_); + ContentPermissionType permission = CheckPermissionForHost(url.host()); + switch (permission) { + case CONTENT_PERMISSION_TYPE_DEFAULT: + return net::CookiePolicy::CanGetCookies(url, first_party_for_cookies); + + case CONTENT_PERMISSION_TYPE_BLOCK: + return false; + + case CONTENT_PERMISSION_TYPE_ALLOW: + return true; + + case CONTENT_PERMISSION_TYPE_ASK: + // TODO(darin): ask the user. + + default: + NOTREACHED(); + } + return false; // To avoid compiler warnings. +} + +bool ChromeCookiePolicy::CanSetCookie(const GURL& url, + const GURL& first_party_for_cookies) { + AutoLock auto_lock(lock_); + ContentPermissionType permission = CheckPermissionForHost(url.host()); + switch (permission) { + case CONTENT_PERMISSION_TYPE_DEFAULT: + return net::CookiePolicy::CanSetCookie(url, first_party_for_cookies); + + case CONTENT_PERMISSION_TYPE_BLOCK: + return false; + + case CONTENT_PERMISSION_TYPE_ALLOW: + return true; + + case CONTENT_PERMISSION_TYPE_ASK: + // TODO(darin): ask the user. + + default: + NOTREACHED(); + } + return false; // To avoid compiler warnings. +} + +void ChromeCookiePolicy::SetPerDomainPermission(const std::string& domain, + ContentPermissionType type) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + if (domain.empty()) + return; + + { + AutoLock auto_lock(lock_); + if (type == CONTENT_PERMISSION_TYPE_DEFAULT) + per_domain_policy_.erase(domain); + else + per_domain_policy_[domain] = type; + } + + DictionaryValue* cookie_exceptions_dict = + profile_->GetPrefs()->GetMutableDictionary(prefs::kCookieExceptions); + std::wstring wide_domain(UTF8ToWide(domain)); + if (type == CONTENT_PERMISSION_TYPE_DEFAULT) { + cookie_exceptions_dict->RemoveWithoutPathExpansion(wide_domain, NULL); + } else { + cookie_exceptions_dict->SetWithoutPathExpansion(wide_domain, + Value::CreateIntegerValue(type)); + } +} + +void ChromeCookiePolicy::set_type(Type type) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + + AutoLock auto_lock(lock_); + net::CookiePolicy::set_type(type); + profile_->GetPrefs()->SetInteger(prefs::kCookieBehavior, type); +} + +ContentPermissionType ChromeCookiePolicy::CheckPermissionForHost( + const std::string& host) const { + std::string search_key(host); + while (!search_key.empty()) { + CookiePolicies::const_iterator i(per_domain_policy_.find(search_key)); + if (i != per_domain_policy_.end()) + return i->second; + size_t dot_pos = search_key.find_first_of('.'); + if (dot_pos == std::string::npos) + break; + search_key = search_key.substr(dot_pos+1); + } + return CONTENT_PERMISSION_TYPE_DEFAULT; +} diff --git a/chrome/browser/net/chrome_cookie_policy.h b/chrome/browser/net/chrome_cookie_policy.h new file mode 100644 index 0000000..88e698b --- /dev/null +++ b/chrome/browser/net/chrome_cookie_policy.h @@ -0,0 +1,81 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NET_CHROME_COOKIE_POLICY_H_ +#define CHROME_BROWSER_NET_CHROME_COOKIE_POLICY_H_ + +#include <map> +#include <string> + +#include "base/basictypes.h" +#include "base/lock.h" +#include "chrome/common/content_permission_types.h" +#include "net/base/cookie_policy.h" + +class GURL; +class PrefService; +class Profile; + +// The ChromeCookiePolicy class implements per-domain cookie policies. +class ChromeCookiePolicy : public net::CookiePolicy { + public: + typedef std::map<std::string, ContentPermissionType> CookiePolicies; + + explicit ChromeCookiePolicy(Profile* profile); + + virtual ~ChromeCookiePolicy() {} + + static void RegisterUserPrefs(PrefService* prefs); + + void ResetToDefaults(); + + // Consult the user's cookie blocking preferences to determine whether the + // URL's cookies can be read. + virtual bool CanGetCookies(const GURL& url, + const GURL& first_party_for_cookies); + + // Consult the user's cookie blocking preferences to determine whether the + // URL's cookies can be set. + virtual bool CanSetCookie(const GURL& url, + const GURL& first_party_for_cookies); + + // Sets per domain policies. A policy of type DEFAULT will erase the entry. + // + // This should be called only on the UI thread. + void SetPerDomainPermission(const std::string& domain, + ContentPermissionType type); + + // Returns all per domain policies. + // + // This can be called on any thread. + CookiePolicies GetAllPerDomainPermissions() const { + return per_domain_policy_; + } + + // Sets the current policy to enforce. + // + // This should be called only on the UI thread. + void set_type(Type type); + + // This can be called on any thread. + Type type() const { + AutoLock auto_lock(lock_); + return net::CookiePolicy::type(); + } + + protected: + ContentPermissionType CheckPermissionForHost(const std::string& host) const; + + Profile* profile_; + + mutable Lock lock_; + + // Local copy of prefs. + CookiePolicies per_domain_policy_; + + private: + DISALLOW_COPY_AND_ASSIGN(ChromeCookiePolicy); +}; + +#endif // CHROME_BROWSER_NET_CHROME_COOKIE_POLICY_H_ diff --git a/chrome/browser/net/chrome_cookie_policy_unittest.cc b/chrome/browser/net/chrome_cookie_policy_unittest.cc new file mode 100644 index 0000000..5bec23a --- /dev/null +++ b/chrome/browser/net/chrome_cookie_policy_unittest.cc @@ -0,0 +1,49 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/chrome_cookie_policy.h" + +#include "chrome/test/testing_profile.h" +#include "testing/gtest/include/gtest/gtest.h" + + +namespace { + +class ChromeCookiePolicyTest : public testing::Test { + public: + ChromeCookiePolicyTest() + : ui_thread_(ChromeThread::UI, &message_loop_) {} + + protected: + MessageLoop message_loop_; + ChromeThread ui_thread_; +}; + +TEST_F(ChromeCookiePolicyTest, DefaultValues) { + TestingProfile profile; + ChromeCookiePolicy* cookie_policy = profile.GetCookiePolicy(); + + // Check setting of default permissions. + cookie_policy->set_type(net::CookiePolicy::ALLOW_ALL_COOKIES); + EXPECT_EQ(net::CookiePolicy::ALLOW_ALL_COOKIES, cookie_policy->type()); + + // Check per host permissions returned. + EXPECT_TRUE(cookie_policy->CanSetCookie(GURL("http://www.example.com"), + GURL("http://www.example.com"))); + cookie_policy->SetPerDomainPermission("example.com", + CONTENT_PERMISSION_TYPE_BLOCK); + EXPECT_FALSE(cookie_policy->CanSetCookie(GURL("http://www.example.com"), + GURL("http://www.example.com"))); + EXPECT_TRUE(cookie_policy->CanSetCookie(GURL("http://other.com"), + GURL("http://other.com"))); + + // Check returning settings for a given resource. + ChromeCookiePolicy::CookiePolicies policies; + policies = cookie_policy->GetAllPerDomainPermissions(); + EXPECT_EQ(1U, policies.size()); + EXPECT_EQ("example.com", policies.begin()->first); + EXPECT_EQ(CONTENT_PERMISSION_TYPE_BLOCK, policies.begin()->second); +} + +} // namespace diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index a50013d..88914dc 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -544,15 +544,6 @@ void ChromeURLRequestContextGetter::Observe( this, &ChromeURLRequestContextGetter::OnAcceptLanguageChange, accept_language)); - } else if (*pref_name_in == prefs::kCookieBehavior) { - net::CookiePolicy::Type policy_type = net::CookiePolicy::FromInt( - prefs_->GetInteger(prefs::kCookieBehavior)); - ChromeThread::PostTask( - ChromeThread::IO, FROM_HERE, - NewRunnableMethod( - this, - &ChromeURLRequestContextGetter::OnCookiePolicyChange, - policy_type)); } else if (*pref_name_in == prefs::kDefaultCharset) { std::string default_charset = WideToASCII(prefs->GetString(prefs::kDefaultCharset)); @@ -574,7 +565,6 @@ void ChromeURLRequestContextGetter::RegisterPrefsObserver(Profile* profile) { prefs_ = profile->GetPrefs(); prefs_->AddPrefObserver(prefs::kAcceptLanguages, this); - prefs_->AddPrefObserver(prefs::kCookieBehavior, this); prefs_->AddPrefObserver(prefs::kDefaultCharset, this); } @@ -596,11 +586,6 @@ void ChromeURLRequestContextGetter::OnAcceptLanguageChange( GetIOContext()->OnAcceptLanguageChange(accept_language); } -void ChromeURLRequestContextGetter::OnCookiePolicyChange( - net::CookiePolicy::Type type) { - GetIOContext()->OnCookiePolicyChange(type); -} - void ChromeURLRequestContextGetter::OnDefaultCharsetChange( const std::string& default_charset) { GetIOContext()->OnDefaultCharsetChange(default_charset); @@ -769,7 +754,7 @@ ChromeURLRequestContext::ChromeURLRequestContext( http_transaction_factory_ = other->http_transaction_factory_; ftp_transaction_factory_ = other->ftp_transaction_factory_; cookie_store_ = other->cookie_store_; - cookie_policy_.set_type(other->cookie_policy_.type()); + cookie_policy_ = other->cookie_policy_; transport_security_state_ = other->transport_security_state_; accept_language_ = other->accept_language_; accept_charset_ = other->accept_charset_; @@ -798,12 +783,6 @@ void ChromeURLRequestContext::OnAcceptLanguageChange( net::HttpUtil::GenerateAcceptLanguageHeader(accept_language); } -void ChromeURLRequestContext::OnCookiePolicyChange( - net::CookiePolicy::Type type) { - CheckCurrentlyOnIOThread(); - cookie_policy_.set_type(type); -} - void ChromeURLRequestContext::OnDefaultCharsetChange( const std::string& default_charset) { CheckCurrentlyOnIOThread(); @@ -855,8 +834,7 @@ ChromeURLRequestContextFactory::ChromeURLRequestContextFactory(Profile* profile) // net_util::GetSuggestedFilename is unlikely to be taken. referrer_charset_ = default_charset; - cookie_policy_type_ = net::CookiePolicy::FromInt( - prefs->GetInteger(prefs::kCookieBehavior)); + cookie_policy_ = profile->GetCookiePolicy(); host_content_settings_map_ = profile->GetHostContentSettingsMap(); @@ -903,7 +881,7 @@ void ChromeURLRequestContextFactory::ApplyProfileParametersToContext( context->set_accept_language(accept_language_); context->set_accept_charset(accept_charset_); context->set_referrer_charset(referrer_charset_); - context->set_cookie_policy_type(cookie_policy_type_); + context->set_cookie_policy(cookie_policy_); context->set_extension_info(extension_info_); context->set_user_script_dir_path(user_script_dir_path_); context->set_host_content_settings_map(host_content_settings_map_); diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h index d1953ef..ae412ba 100644 --- a/chrome/browser/net/chrome_url_request_context.h +++ b/chrome/browser/net/chrome_url_request_context.h @@ -9,6 +9,7 @@ #include "base/linked_ptr.h" #include "chrome/browser/host_content_settings_map.h" #include "chrome/browser/host_zoom_map.h" +#include "chrome/browser/net/chrome_cookie_policy.h" #include "chrome/browser/net/url_request_context_getter.h" #include "chrome/common/appcache/chrome_appcache_service.h" #include "chrome/common/notification_registrar.h" @@ -136,8 +137,8 @@ class ChromeURLRequestContext : public URLRequestContext { void set_referrer_charset(const std::string& referrer_charset) { referrer_charset_ = referrer_charset; } - void set_cookie_policy_type(net::CookiePolicy::Type type) { - cookie_policy_.set_type(type); + void set_cookie_policy(ChromeCookiePolicy* policy) { + cookie_policy_ = policy; } void set_extension_info( const ChromeURLRequestContext::ExtensionInfoMap& info) { @@ -189,9 +190,6 @@ class ChromeURLRequestContext : public URLRequestContext { // Callback for when the accept language changes. void OnAcceptLanguageChange(const std::string& accept_language); - // Callback for when the cookie policy changes. - void OnCookiePolicyChange(net::CookiePolicy::Type type); - // Callback for when the default charset changes. void OnDefaultCharsetChange(const std::string& default_charset); @@ -314,7 +312,6 @@ class ChromeURLRequestContextGetter : public URLRequestContextGetter, // These methods simply forward to the corresponding method on // ChromeURLRequestContext. void OnAcceptLanguageChange(const std::string& accept_language); - void OnCookiePolicyChange(net::CookiePolicy::Type type); void OnDefaultCharsetChange(const std::string& default_charset); // Saves the cookie store to |result| and signals |completion|. @@ -368,7 +365,7 @@ class ChromeURLRequestContextFactory { std::string accept_language_; std::string accept_charset_; std::string referrer_charset_; - net::CookiePolicy::Type cookie_policy_type_; + ChromeCookiePolicy* cookie_policy_; ChromeURLRequestContext::ExtensionInfoMap extension_info_; // TODO(aa): I think this can go away now as we no longer support standalone // user scripts. diff --git a/chrome/browser/net/cookie_policy_browsertest.cc b/chrome/browser/net/cookie_policy_browsertest.cc index 7dbecf9..9f4b1f4 100644 --- a/chrome/browser/net/cookie_policy_browsertest.cc +++ b/chrome/browser/net/cookie_policy_browsertest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "chrome/browser/browser.h" +#include "chrome/browser/net/chrome_cookie_policy.h" #include "chrome/browser/net/url_request_context_getter.h" #include "chrome/browser/profile.h" #include "chrome/common/pref_names.h" @@ -25,8 +26,8 @@ IN_PROC_BROWSER_TEST_F(CookiePolicyBrowserTest, AllowFirstPartyCookies) { ASSERT_TRUE(server != NULL); PrefService* prefs = browser()->profile()->GetPrefs(); - prefs->SetInteger(prefs::kCookieBehavior, - net::CookiePolicy::BLOCK_THIRD_PARTY_COOKIES); + browser()->profile()->GetCookiePolicy()->set_type( + net::CookiePolicy::BLOCK_THIRD_PARTY_COOKIES); net::CookiePolicy::Type policy_type = net::CookiePolicy::FromInt( prefs->GetInteger(prefs::kCookieBehavior)); ASSERT_EQ(net::CookiePolicy::BLOCK_THIRD_PARTY_COOKIES, policy_type); @@ -54,8 +55,8 @@ IN_PROC_BROWSER_TEST_F(CookiePolicyBrowserTest, ASSERT_TRUE(server != NULL); PrefService* prefs = browser()->profile()->GetPrefs(); - prefs->SetInteger(prefs::kCookieBehavior, - net::CookiePolicy::BLOCK_THIRD_PARTY_COOKIES); + browser()->profile()->GetCookiePolicy()->set_type( + net::CookiePolicy::BLOCK_THIRD_PARTY_COOKIES); net::CookiePolicy::Type policy_type = net::CookiePolicy::FromInt( prefs->GetInteger(prefs::kCookieBehavior)); ASSERT_EQ(net::CookiePolicy::BLOCK_THIRD_PARTY_COOKIES, policy_type); |