diff options
author | hjd@chromium.org <hjd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-29 19:01:02 +0000 |
---|---|---|
committer | hjd@chromium.org <hjd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-29 19:01:02 +0000 |
commit | 41d70bd6049acc562fa0ff51bd3f7453d4969f07 (patch) | |
tree | 1433d7b4d2784f949529687f9f8761b8df85fee7 | |
parent | 2b4e10f4dcd668a1e0ba3b800672e1ba4e6909de (diff) | |
download | chromium_src-41d70bd6049acc562fa0ff51bd3f7453d4969f07.zip chromium_src-41d70bd6049acc562fa0ff51bd3f7453d4969f07.tar.gz chromium_src-41d70bd6049acc562fa0ff51bd3f7453d4969f07.tar.bz2 |
Makes Third Party Cookie Settings per Aw
The third party bit of state is moved onto AwSettings.
AwCookiePolicy is split up in to a class which finds the right bits,
AwCookieAccessPolicy and AwStaticCookiePolicy which implements the
actual logic.
BUG=369496
TEST=AndroidWebviewTest
Review URL: https://codereview.chromium.org/288203002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273528 0039d316-1c4b-4281-b951-d872f2087c98
19 files changed, 350 insertions, 275 deletions
diff --git a/android_webview/android_webview_tests.gypi b/android_webview/android_webview_tests.gypi index 887d504..d18f876 100644 --- a/android_webview/android_webview_tests.gypi +++ b/android_webview/android_webview_tests.gypi @@ -96,7 +96,7 @@ '<(SHARED_INTERMEDIATE_DIR)/android_webview_unittests', ], 'sources': [ - 'browser/aw_cookie_access_policy_unittest.cc', + 'browser/aw_static_cookie_policy_unittest.cc', 'browser/aw_form_database_service_unittest.cc', 'browser/global_tile_manager_unittest.cc', 'browser/net/android_stream_reader_url_request_job_unittest.cc', diff --git a/android_webview/browser/aw_contents_io_thread_client.h b/android_webview/browser/aw_contents_io_thread_client.h index 8186739..0ac29fc 100644 --- a/android_webview/browser/aw_contents_io_thread_client.h +++ b/android_webview/browser/aw_contents_io_thread_client.h @@ -84,6 +84,9 @@ class AwContentsIoThreadClient { // This method is called on the IO thread only. virtual bool ShouldBlockNetworkLoads() const = 0; + // Retrieve the AcceptThirdPartyCookies setting value of this AwContents. + virtual bool ShouldAcceptThirdPartyCookies() const = 0; + // Called when ResourceDispathcerHost detects a download request. // The download is already cancelled when this is called, since // relevant for DownloadListener is already extracted. diff --git a/android_webview/browser/aw_cookie_access_policy.cc b/android_webview/browser/aw_cookie_access_policy.cc index 06e30605..e07db11 100644 --- a/android_webview/browser/aw_cookie_access_policy.cc +++ b/android_webview/browser/aw_cookie_access_policy.cc @@ -4,13 +4,17 @@ #include "android_webview/browser/aw_cookie_access_policy.h" +#include "android_webview/browser/aw_contents_io_thread_client.h" + #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/resource_request_info.h" #include "net/base/net_errors.h" using base::AutoLock; using content::BrowserThread; +using content::ResourceRequestInfo; using net::StaticCookiePolicy; namespace android_webview { @@ -23,43 +27,59 @@ AwCookieAccessPolicy::~AwCookieAccessPolicy() { } AwCookieAccessPolicy::AwCookieAccessPolicy() - : allow_access_(true), - allow_third_party_access_(true) { + : accept_cookies_(true) { } AwCookieAccessPolicy* AwCookieAccessPolicy::GetInstance() { return g_lazy_instance.Pointer(); } -bool AwCookieAccessPolicy::GetGlobalAllowAccess() { +bool AwCookieAccessPolicy::GetShouldAcceptCookies() { AutoLock lock(lock_); - return allow_access_; + return accept_cookies_; } -void AwCookieAccessPolicy::SetGlobalAllowAccess(bool allow) { +void AwCookieAccessPolicy::SetShouldAcceptCookies(bool allow) { AutoLock lock(lock_); - allow_access_ = allow; + accept_cookies_ = allow; } -bool AwCookieAccessPolicy::GetThirdPartyAllowAccess() { - AutoLock lock(lock_); - return allow_third_party_access_; +bool AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies( + int render_process_id, + int render_frame_id) { + scoped_ptr<AwContentsIoThreadClient> io_thread_client = + AwContentsIoThreadClient::FromID(render_process_id, render_frame_id); + if (!io_thread_client) { + return false; + } + return io_thread_client->ShouldAcceptThirdPartyCookies(); } -void AwCookieAccessPolicy::SetThirdPartyAllowAccess(bool allow) { - AutoLock lock(lock_); - allow_third_party_access_ = allow; +bool AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies( + const net::URLRequest& request) { + const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request); + if (!info) { + return false; + } + return GetShouldAcceptThirdPartyCookies(info->GetChildID(), + info->GetRenderFrameID()); } bool AwCookieAccessPolicy::OnCanGetCookies(const net::URLRequest& request, const net::CookieList& cookie_list) { - return AllowGet(request.url(), request.first_party_for_cookies()); + bool global = GetShouldAcceptCookies(); + bool thirdParty = GetShouldAcceptThirdPartyCookies(request); + return AwStaticCookiePolicy(global, thirdParty) + .AllowGet(request.url(), request.first_party_for_cookies()); } bool AwCookieAccessPolicy::OnCanSetCookie(const net::URLRequest& request, const std::string& cookie_line, net::CookieOptions* options) { - return AllowSet(request.url(), request.first_party_for_cookies()); + bool global = GetShouldAcceptCookies(); + bool thirdParty = GetShouldAcceptThirdPartyCookies(request); + return AwStaticCookiePolicy(global, thirdParty) + .AllowSet(request.url(), request.first_party_for_cookies()); } bool AwCookieAccessPolicy::AllowGetCookie(const GURL& url, @@ -68,7 +88,10 @@ bool AwCookieAccessPolicy::AllowGetCookie(const GURL& url, content::ResourceContext* context, int render_process_id, int render_frame_id) { - return AllowGet(url, first_party); + bool global = GetShouldAcceptCookies(); + bool thirdParty = + GetShouldAcceptThirdPartyCookies(render_process_id, render_frame_id); + return AwStaticCookiePolicy(global, thirdParty).AllowGet(url, first_party); } bool AwCookieAccessPolicy::AllowSetCookie(const GURL& url, @@ -78,26 +101,37 @@ bool AwCookieAccessPolicy::AllowSetCookie(const GURL& url, int render_process_id, int render_frame_id, net::CookieOptions* options) { - return AllowSet(url, first_party); + bool global = GetShouldAcceptCookies(); + bool thirdParty = + GetShouldAcceptThirdPartyCookies(render_process_id, render_frame_id); + return AwStaticCookiePolicy(global, thirdParty).AllowSet(url, first_party); +} + +AwStaticCookiePolicy::AwStaticCookiePolicy(bool accept_cookies, + bool accept_third_party_cookies) + : accept_cookies_(accept_cookies), + accept_third_party_cookies_(accept_third_party_cookies) { } -StaticCookiePolicy::Type AwCookieAccessPolicy::GetPolicy() { - if (!GetGlobalAllowAccess()) { +StaticCookiePolicy::Type AwStaticCookiePolicy::GetPolicy() const { + if (!accept_cookies()) { return StaticCookiePolicy::BLOCK_ALL_COOKIES; - } else if (!GetThirdPartyAllowAccess()) { + } else if (!accept_third_party_cookies()) { return StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES; } return StaticCookiePolicy::ALLOW_ALL_COOKIES; } -bool AwCookieAccessPolicy::AllowSet(const GURL& url, const GURL& first_party) { - return StaticCookiePolicy(GetPolicy()).CanSetCookie(url, first_party) - == net::OK; +bool AwStaticCookiePolicy::AllowSet(const GURL& url, + const GURL& first_party) const { + return StaticCookiePolicy(GetPolicy()).CanSetCookie(url, first_party) == + net::OK; } -bool AwCookieAccessPolicy::AllowGet(const GURL& url, const GURL& first_party) { - return StaticCookiePolicy(GetPolicy()).CanGetCookies(url, first_party) - == net::OK; +bool AwStaticCookiePolicy::AllowGet(const GURL& url, + const GURL& first_party) const { + return StaticCookiePolicy(GetPolicy()).CanGetCookies(url, first_party) == + net::OK; } } // namespace android_webview diff --git a/android_webview/browser/aw_cookie_access_policy.h b/android_webview/browser/aw_cookie_access_policy.h index 7fd7b59..480eddd 100644 --- a/android_webview/browser/aw_cookie_access_policy.h +++ b/android_webview/browser/aw_cookie_access_policy.h @@ -25,19 +25,20 @@ class GURL; namespace android_webview { // Manages the cookie access (both setting and getting) policy for WebView. +// Currently we don't distinguish between sources (i.e. network vs. JavaScript) +// or between reading vs. writing cookies. class AwCookieAccessPolicy { public: static AwCookieAccessPolicy* GetInstance(); - // These manage the global access state shared across requests regardless of - // source (i.e. network or JavaScript). - bool GetGlobalAllowAccess(); - void SetGlobalAllowAccess(bool allow); + // Can we read/write any cookies? + bool GetShouldAcceptCookies(); + void SetShouldAcceptCookies(bool allow); - // These allow more fine grained control over requests depending on whether - // the cookie is third party or not. - bool GetThirdPartyAllowAccess(); - void SetThirdPartyAllowAccess(bool allow); + // Can we read/write third party cookies? + bool GetShouldAcceptThirdPartyCookies(int render_process_id, + int render_frame_id); + bool GetShouldAcceptThirdPartyCookies(const net::URLRequest& request); // These are the functions called when operating over cookies from the // network. See NetworkDelegate for further descriptions. @@ -68,20 +69,42 @@ class AwCookieAccessPolicy { AwCookieAccessPolicy(); ~AwCookieAccessPolicy(); - bool allow_access_; - bool allow_third_party_access_; + bool accept_cookies_; base::Lock lock_; - // We have two bits of state but only three different cases: - // If !GlobalAllowAccess then reject all cookies. - // If GlobalAllowAccess and !ThirdPartyAllowAccess then reject third party. - // If GlobalAllowAccess and ThirdPartyAllowAccess then allow all cookies. - net::StaticCookiePolicy::Type GetPolicy(void); + DISALLOW_COPY_AND_ASSIGN(AwCookieAccessPolicy); +}; - bool AllowGet(const GURL& url, const GURL& first_party); - bool AllowSet(const GURL& url, const GURL& first_party); +class AwStaticCookiePolicy { + public: + AwStaticCookiePolicy(bool allow_global_access, + bool allow_third_party_access); - DISALLOW_COPY_AND_ASSIGN(AwCookieAccessPolicy); + bool accept_cookies() const { + return accept_cookies_; + } + + bool accept_third_party_cookies() const { + return accept_third_party_cookies_; + } + + bool AllowGet(const GURL& url, const GURL& first_party) const; + bool AllowSet(const GURL& url, const GURL& first_party) const; + + private: + const bool accept_cookies_; + const bool accept_third_party_cookies_; + + // We have two bits of state but only three different cases: + // If !ShouldAcceptCookies + // then reject all cookies. + // If ShouldAcceptCookies and !ShouldAcceptThirdPartyCookies + // then reject third party. + // If ShouldAcceptCookies and ShouldAcceptThirdPartyCookies + // then allow all cookies. + net::StaticCookiePolicy::Type GetPolicy() const; + + DISALLOW_COPY_AND_ASSIGN(AwStaticCookiePolicy); }; } // namespace android_webview diff --git a/android_webview/browser/aw_cookie_access_policy_unittest.cc b/android_webview/browser/aw_cookie_access_policy_unittest.cc deleted file mode 100644 index 6f8a1f1..0000000 --- a/android_webview/browser/aw_cookie_access_policy_unittest.cc +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2014 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 "android_webview/browser/aw_cookie_access_policy.h" - -#include "base/run_loop.h" -#include "net/base/request_priority.h" -#include "net/cookies/canonical_cookie.h" -#include "net/url_request/url_request_test_util.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { -class ResourceContext; -} - -namespace net { -class CookieOptions; -} - -class GURL; - -using android_webview::AwCookieAccessPolicy; -using net::CookieList; -using net::TestDelegate; -using net::TestJobInterceptor; -using net::TestNetworkDelegate; -using net::TestURLRequestContext; -using net::TestURLRequest; -using testing::Test; - -class AwCookieAccessPolicyTest : public Test { - public: - static const GURL kUrlFirstParty; - static const GURL kUrlThirdParty; - - AwCookieAccessPolicyTest() - : loop_(), - context_(), - url_request_delegate_(), - network_delegate_(), - first_party_request_() {} - - virtual void SetUp() { - context_.set_network_delegate(&network_delegate_); - first_party_request_.reset(new TestURLRequest(kUrlFirstParty, - net::DEFAULT_PRIORITY, - &url_request_delegate_, - &context_)); - first_party_request_->set_method("GET"); - - third_party_request_.reset(new TestURLRequest(kUrlThirdParty, - net::DEFAULT_PRIORITY, - &url_request_delegate_, - &context_)); - third_party_request_->set_method("GET"); - third_party_request_->set_first_party_for_cookies(kUrlFirstParty); - } - - AwCookieAccessPolicy* policy() { - return AwCookieAccessPolicy::GetInstance(); - } - - bool GetGlobalAllowAccess() { - return policy()->GetGlobalAllowAccess(); - } - - void SetGlobalAllowAccess(bool allow) { - policy()->SetGlobalAllowAccess(allow); - } - - bool GetThirdPartyAllowAccess() { - return policy()->GetThirdPartyAllowAccess(); - } - - void SetThirdPartyAllowAccess(bool allow) { - policy()->SetThirdPartyAllowAccess(allow); - } - - bool OnCanGetCookies(const net::URLRequest& request) { - return policy()->OnCanGetCookies(request, CookieList()); - } - - bool OnCanSetCookie(const net::URLRequest& request) { - return policy()->OnCanSetCookie(request, "", NULL); - } - - bool AllowGetCookie(const GURL& url, const GURL& first_party) { - return policy()->AllowGetCookie(url, first_party, CookieList(), NULL, 0, 0); - } - - bool AllowSetCookie(const GURL& url, const GURL& first_party) { - return policy()->AllowSetCookie(url, first_party, "", NULL, 0, 0, NULL); - } - - void expectFirstPartyAccess(bool expectedResult) { - EXPECT_EQ(expectedResult, AllowSetCookie(kUrlFirstParty, kUrlFirstParty)); - EXPECT_EQ(expectedResult, AllowGetCookie(kUrlFirstParty, kUrlFirstParty)); - EXPECT_EQ(expectedResult, OnCanGetCookies(*first_party_request_)); - EXPECT_EQ(expectedResult, OnCanSetCookie(*first_party_request_)); - } - - void expectThirdPartyAccess(bool expectedResult) { - EXPECT_EQ(expectedResult, AllowSetCookie(kUrlFirstParty, kUrlThirdParty)); - EXPECT_EQ(expectedResult, AllowGetCookie(kUrlFirstParty, kUrlThirdParty)); - EXPECT_EQ(expectedResult, OnCanGetCookies(*third_party_request_)); - EXPECT_EQ(expectedResult, OnCanSetCookie(*third_party_request_)); - } - - protected: - base::MessageLoopForIO loop_; - TestURLRequestContext context_; - TestDelegate url_request_delegate_; - TestNetworkDelegate network_delegate_; - scoped_ptr<TestURLRequest> first_party_request_; - scoped_ptr<TestURLRequest> third_party_request_; -}; - -const GURL AwCookieAccessPolicyTest::kUrlFirstParty = - GURL("http://first.example"); -const GURL AwCookieAccessPolicyTest::kUrlThirdParty = - GURL("http://third.example"); - -TEST_F(AwCookieAccessPolicyTest, BlockAllCookies) { - SetGlobalAllowAccess(false); - SetThirdPartyAllowAccess(false); - expectFirstPartyAccess(false); - expectThirdPartyAccess(false); -} - -TEST_F(AwCookieAccessPolicyTest, BlockAllCookiesWithThirdPartySet) { - SetGlobalAllowAccess(false); - SetThirdPartyAllowAccess(true); - expectFirstPartyAccess(false); - expectThirdPartyAccess(false); -} - -TEST_F(AwCookieAccessPolicyTest, FirstPartyCookiesOnly) { - SetGlobalAllowAccess(true); - SetThirdPartyAllowAccess(false); - expectFirstPartyAccess(true); - expectThirdPartyAccess(false); -} - -TEST_F(AwCookieAccessPolicyTest, AllowAllCookies) { - SetGlobalAllowAccess(true); - SetThirdPartyAllowAccess(true); - expectFirstPartyAccess(true); - expectThirdPartyAccess(true); -} diff --git a/android_webview/browser/aw_static_cookie_policy_unittest.cc b/android_webview/browser/aw_static_cookie_policy_unittest.cc new file mode 100644 index 0000000..edeb315 --- /dev/null +++ b/android_webview/browser/aw_static_cookie_policy_unittest.cc @@ -0,0 +1,66 @@ +// Copyright 2014 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 "android_webview/browser/aw_cookie_access_policy.h" + +#include "testing/gtest/include/gtest/gtest.h" + +class GURL; + +using android_webview::AwStaticCookiePolicy; +using testing::Test; + +class AwStaticCookiePolicyTest : public Test { + public: + static const GURL kUrlFirstParty; + static const GURL kUrlThirdParty; + + AwStaticCookiePolicyTest() {} + + void expectFirstPartyAccess(const AwStaticCookiePolicy& policy, + bool expectedResult) { + EXPECT_EQ(expectedResult, policy.AllowSet(kUrlFirstParty, kUrlFirstParty)); + EXPECT_EQ(expectedResult, policy.AllowGet(kUrlFirstParty, kUrlFirstParty)); + } + + void expectThirdPartyAccess(const AwStaticCookiePolicy& policy, + bool expectedResult) { + EXPECT_EQ(expectedResult, policy.AllowSet(kUrlFirstParty, kUrlThirdParty)); + EXPECT_EQ(expectedResult, policy.AllowGet(kUrlFirstParty, kUrlThirdParty)); + } +}; + +const GURL AwStaticCookiePolicyTest::kUrlFirstParty = + GURL("http://first.example"); +const GURL AwStaticCookiePolicyTest::kUrlThirdParty = + GURL("http://third.example"); + +TEST_F(AwStaticCookiePolicyTest, BlockAllCookies) { + AwStaticCookiePolicy policy(false /* allow_cookies */, + false /* allow_third_party_cookies */); + expectFirstPartyAccess(policy, false); + expectThirdPartyAccess(policy, false); +} + +TEST_F(AwStaticCookiePolicyTest, BlockAllCookiesWithThirdPartySet) { + AwStaticCookiePolicy policy(false /* allow_cookies */, + true /* allow_third_party_cookies */); + expectFirstPartyAccess(policy, false); + expectThirdPartyAccess(policy, false); +} + +TEST_F(AwStaticCookiePolicyTest, FirstPartyCookiesOnly) { + AwStaticCookiePolicy policy(true /* allow_cookies */, + false /* allow_third_party_cookies */); + expectFirstPartyAccess(policy, true); + expectThirdPartyAccess(policy, false); +} + +TEST_F(AwStaticCookiePolicyTest, AllowAllCookies) { + AwStaticCookiePolicy policy(true /* allow_cookies */, + true /* allow_third_party_cookies */); + expectFirstPartyAccess(policy, true); + expectThirdPartyAccess(policy, true); +} + diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 900ac95..3d2282f 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java @@ -291,6 +291,11 @@ public class AwContents { } @Override + public boolean shouldAcceptThirdPartyCookies() { + return mSettings.getAcceptThirdPartyCookies(); + } + + @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) { mContentsClient.getCallbackHelper().postOnDownloadStart(url, userAgent, diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsIoThreadClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsIoThreadClient.java index b82cb12..fe59d2b 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContentsIoThreadClient.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContentsIoThreadClient.java @@ -31,6 +31,9 @@ public interface AwContentsIoThreadClient { public boolean shouldBlockNetworkLoads(); @CalledByNative + public boolean shouldAcceptThirdPartyCookies(); + + @CalledByNative public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength); diff --git a/android_webview/java/src/org/chromium/android_webview/AwCookieManager.java b/android_webview/java/src/org/chromium/android_webview/AwCookieManager.java index c7f04aa..a18370e 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwCookieManager.java +++ b/android_webview/java/src/org/chromium/android_webview/AwCookieManager.java @@ -39,7 +39,7 @@ public final class AwCookieManager { * @param accept TRUE if accept cookie */ public void setAcceptCookie(boolean accept) { - nativeSetAcceptCookie(accept); + nativeSetShouldAcceptCookies(accept); } /** @@ -47,23 +47,7 @@ public final class AwCookieManager { * @return TRUE if accept cookie */ public boolean acceptCookie() { - return nativeAcceptCookie(); - } - - /** - * Control whether third party cookies are enabled or disabled - * @param accept TRUE if accept third party cookies - */ - public void setAcceptThirdPartyCookie(boolean accept) { - nativeSetAcceptThirdPartyCookie(accept); - } - - /** - * Return whether third party cookies are enabled - * @return TRUE if accept third party cookies - */ - public boolean acceptThirdPartyCookie() { - return nativeAcceptThirdPartyCookie(); + return nativeGetShouldAcceptCookies(); } /** @@ -228,11 +212,8 @@ public final class AwCookieManager { } } - private native void nativeSetAcceptCookie(boolean accept); - private native boolean nativeAcceptCookie(); - - private native void nativeSetAcceptThirdPartyCookie(boolean accept); - private native boolean nativeAcceptThirdPartyCookie(); + private native void nativeSetShouldAcceptCookies(boolean accept); + private native boolean nativeGetShouldAcceptCookies(); private native void nativeSetCookie(String url, String value, CookieCallback<Boolean> callback); diff --git a/android_webview/java/src/org/chromium/android_webview/AwSettings.java b/android_webview/java/src/org/chromium/android_webview/AwSettings.java index 315e354..3461517 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSettings.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java @@ -96,6 +96,9 @@ public class AwSettings { private int mMixedContentMode = MIXED_CONTENT_NEVER_ALLOW; private boolean mVideoOverlayForEmbeddedVideoEnabled = false; + // Although this bit is stored on AwSettings it is actually controlled via the CookieManager. + private boolean mAcceptThirdPartyCookies; + private final boolean mSupportLegacyQuirks; private final boolean mPasswordEchoEnabled; @@ -307,6 +310,28 @@ public class AwSettings { } /** + * Enable/disable third party cookies for an AwContents + * @param accept true if we should accept third party cookies + */ + public void setAcceptThirdPartyCookies(boolean accept) { + synchronized (mAwSettingsLock) { + if (mAcceptThirdPartyCookies != accept) { + mAcceptThirdPartyCookies = accept; + } + } + } + + /** + * Return whether third party cookies are enabled for an AwContents + * @return true if accept third party cookies + */ + public boolean getAcceptThirdPartyCookies() { + synchronized (mAwSettingsLock) { + return mAcceptThirdPartyCookies; + } + } + + /** * See {@link android.webkit.WebSettings#setAllowFileAccess}. */ public void setAllowFileAccess(boolean allow) { diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java index f9687ee..14ef678 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java @@ -13,6 +13,7 @@ import static org.chromium.android_webview.test.util.CookieUtils.TestValueCallba import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwCookieManager; +import org.chromium.android_webview.AwSettings; import org.chromium.android_webview.test.util.CookieUtils; import org.chromium.android_webview.test.util.JSUtils; import org.chromium.base.test.util.Feature; @@ -372,8 +373,8 @@ public class CookieManagerTest extends AwTestBase { assertTrue(mCookieManager.acceptCookie()); // When third party cookies are disabled... - mCookieManager.setAcceptThirdPartyCookie(false); - assertFalse(mCookieManager.acceptThirdPartyCookie()); + mAwContents.getSettings().setAcceptThirdPartyCookies(false); + assertFalse(mAwContents.getSettings().getAcceptThirdPartyCookies()); // ...we can't set third party cookies. // First on the third party server we create a url which tries to set a cookie. @@ -385,8 +386,8 @@ public class CookieManagerTest extends AwTestBase { assertNull(mCookieManager.getCookie(cookieUrl)); // When third party cookies are enabled... - mCookieManager.setAcceptThirdPartyCookie(true); - assertTrue(mCookieManager.acceptThirdPartyCookie()); + mAwContents.getSettings().setAcceptThirdPartyCookies(true); + assertTrue(mAwContents.getSettings().getAcceptThirdPartyCookies()); // ...we can set third party cookies. cookieUrl = toThirdPartyUrl( @@ -438,40 +439,128 @@ public class CookieManagerTest extends AwTestBase { try { // This test again uses 127.0.0.1/localhost trick to simulate a third party. webServer = new TestWebServer(false); + ThirdPartyCookiesTestHelper thirdParty + = new ThirdPartyCookiesTestHelper(webServer); mCookieManager.setAcceptCookie(true); assertTrue(mCookieManager.acceptCookie()); // When third party cookies are disabled... - mCookieManager.setAcceptThirdPartyCookie(false); - assertFalse(mCookieManager.acceptThirdPartyCookie()); + thirdParty.getSettings().setAcceptThirdPartyCookies(false); + assertFalse(thirdParty.getSettings().getAcceptThirdPartyCookies()); // ...we can't set third party cookies. - // We create a script which tries to set a cookie on a third party. - String cookieUrl = toThirdPartyUrl( - makeCookieScriptUrl(webServer, "/cookie_1.html", "test1", "value1")); - // Then we load it as an iframe. - String url = makeIframeUrl(webServer, "/content_1.html", cookieUrl); - loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url); - assertNull(mCookieManager.getCookie(cookieUrl)); + thirdParty.assertThirdPartyIFrameCookieResult("1", false); // When third party cookies are enabled... - mCookieManager.setAcceptThirdPartyCookie(true); - assertTrue(mCookieManager.acceptThirdPartyCookie()); + thirdParty.getSettings().setAcceptThirdPartyCookies(true); + assertTrue(thirdParty.getSettings().getAcceptThirdPartyCookies()); // ...we can set third party cookies. - cookieUrl = toThirdPartyUrl( - makeCookieScriptUrl(webServer, "/cookie_2.html", "test2", "value2")); - url = makeIframeUrl(webServer, "/content_2.html", cookieUrl); - loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url); - String cookie = mCookieManager.getCookie(cookieUrl); - assertNotNull(cookie); - validateCookies(cookie, "test2"); + thirdParty.assertThirdPartyIFrameCookieResult("2", true); } finally { if (webServer != null) webServer.shutdown(); } } + @MediumTest + @Feature({"AndroidWebView", "Privacy"}) + public void testThirdPartyCookiesArePerWebview() throws Throwable { + TestWebServer webServer = null; + try { + webServer = new TestWebServer(false); + mCookieManager.setAcceptCookie(true); + mCookieManager.removeAllCookie(); + assertTrue(mCookieManager.acceptCookie()); + assertFalse(mCookieManager.hasCookies()); + + ThirdPartyCookiesTestHelper helperOne = new ThirdPartyCookiesTestHelper(webServer); + ThirdPartyCookiesTestHelper helperTwo = new ThirdPartyCookiesTestHelper(webServer); + + helperOne.getSettings().setAcceptThirdPartyCookies(false); + helperTwo.getSettings().setAcceptThirdPartyCookies(false); + assertFalse(helperOne.getSettings().getAcceptThirdPartyCookies()); + assertFalse(helperTwo.getSettings().getAcceptThirdPartyCookies()); + helperOne.assertThirdPartyIFrameCookieResult("1", false); + helperTwo.assertThirdPartyIFrameCookieResult("2", false); + + helperTwo.getSettings().setAcceptThirdPartyCookies(true); + assertFalse(helperOne.getSettings().getAcceptThirdPartyCookies()); + assertTrue(helperTwo.getSettings().getAcceptThirdPartyCookies()); + helperOne.assertThirdPartyIFrameCookieResult("3", false); + helperTwo.assertThirdPartyIFrameCookieResult("4", true); + + helperOne.getSettings().setAcceptThirdPartyCookies(true); + assertTrue(helperOne.getSettings().getAcceptThirdPartyCookies()); + assertTrue(helperTwo.getSettings().getAcceptThirdPartyCookies()); + helperOne.assertThirdPartyIFrameCookieResult("5", true); + helperTwo.assertThirdPartyIFrameCookieResult("6", true); + + helperTwo.getSettings().setAcceptThirdPartyCookies(false); + assertTrue(helperOne.getSettings().getAcceptThirdPartyCookies()); + assertFalse(helperTwo.getSettings().getAcceptThirdPartyCookies()); + helperOne.assertThirdPartyIFrameCookieResult("7", true); + helperTwo.assertThirdPartyIFrameCookieResult("8", false); + } finally { + if (webServer != null) webServer.shutdown(); + } + } + + class ThirdPartyCookiesTestHelper { + protected final AwContents mAwContents; + protected final TestAwContentsClient mContentsClient; + protected final TestWebServer mWebServer; + + ThirdPartyCookiesTestHelper(TestWebServer webServer) throws Throwable { + mWebServer = webServer; + mContentsClient = new TestAwContentsClient(); + final AwTestContainerView containerView = + createAwTestContainerViewOnMainSync(mContentsClient); + mAwContents = containerView.getAwContents(); + mAwContents.getSettings().setJavaScriptEnabled(true); + } + + AwContents getAwContents() { + return mAwContents; + } + + AwSettings getSettings() { + return mAwContents.getSettings(); + } + + TestWebServer getWebServer() { + return mWebServer; + } + + void assertThirdPartyIFrameCookieResult(String suffix, boolean expectedResult) + throws Throwable { + String key = "test" + suffix; + String value = "value" + suffix; + String iframePath = "/iframe_" + suffix + ".html"; + String pagePath = "/content_" + suffix + ".html"; + + // We create a script which tries to set a cookie on a third party. + String cookieUrl = toThirdPartyUrl( + makeCookieScriptUrl(getWebServer(), iframePath, key, value)); + + // Then we load it as an iframe. + String url = makeIframeUrl(getWebServer(), pagePath, cookieUrl); + loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url); + + if (expectedResult) { + String cookie = mCookieManager.getCookie(cookieUrl); + assertNotNull(cookie); + validateCookies(cookie, key); + } else { + assertNull(mCookieManager.getCookie(cookieUrl)); + } + + // Clear the cookies. + clearCookies(); + assertFalse(mCookieManager.hasCookies()); + } + } + /** * Creates a response on the TestWebServer which attempts to set a cookie when fetched. * @param webServer the webServer on which to create the response @@ -503,7 +592,7 @@ public class CookieManagerTest extends AwTestBase { /** * Makes a url look as if it comes from a different host. * @param url the url to fake. - * @return the resulting after faking. + * @return the resulting url after faking. */ private String toThirdPartyUrl(String url) { return url.replace("localhost", "127.0.0.1"); diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index 679ebc8..5521567 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h @@ -160,6 +160,9 @@ class AwContents : public FindHelper::Listener, void ClearMatches(JNIEnv* env, jobject obj); FindHelper* GetFindHelper(); + // Per WebView Cookie Policy + bool AllowThirdPartyCookies(); + // FindHelper::Listener implementation. virtual void OnFindResultReceived(int active_ordinal, int match_count, diff --git a/android_webview/native/aw_contents_io_thread_client_impl.cc b/android_webview/native/aw_contents_io_thread_client_impl.cc index 555cd83..fd47138 100644 --- a/android_webview/native/aw_contents_io_thread_client_impl.cc +++ b/android_webview/native/aw_contents_io_thread_client_impl.cc @@ -273,6 +273,16 @@ bool AwContentsIoThreadClientImpl::ShouldBlockFileUrls() const { env, java_object_.obj()); } +bool AwContentsIoThreadClientImpl::ShouldAcceptThirdPartyCookies() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (java_object_.is_null()) + return false; + + JNIEnv* env = AttachCurrentThread(); + return Java_AwContentsIoThreadClient_shouldAcceptThirdPartyCookies( + env, java_object_.obj()); +} + bool AwContentsIoThreadClientImpl::ShouldBlockNetworkLoads() const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (java_object_.is_null()) diff --git a/android_webview/native/aw_contents_io_thread_client_impl.h b/android_webview/native/aw_contents_io_thread_client_impl.h index e2561af..c783b2b 100644 --- a/android_webview/native/aw_contents_io_thread_client_impl.h +++ b/android_webview/native/aw_contents_io_thread_client_impl.h @@ -51,6 +51,7 @@ class AwContentsIoThreadClientImpl : public AwContentsIoThreadClient { const net::URLRequest* request) OVERRIDE; virtual bool ShouldBlockContentUrls() const OVERRIDE; virtual bool ShouldBlockFileUrls() const OVERRIDE; + virtual bool ShouldAcceptThirdPartyCookies() const OVERRIDE; virtual bool ShouldBlockNetworkLoads() const OVERRIDE; virtual void NewDownload(const GURL& url, const std::string& user_agent, diff --git a/android_webview/native/cookie_manager.cc b/android_webview/native/cookie_manager.cc index f47cf57..5d74418 100644 --- a/android_webview/native/cookie_manager.cc +++ b/android_webview/native/cookie_manager.cc @@ -147,10 +147,8 @@ class CookieManager { scoped_refptr<net::CookieStore> GetCookieStore(); - void SetAcceptCookie(bool accept); - bool AcceptCookie(); - void SetAcceptThirdPartyCookie(bool accept); - bool AcceptThirdPartyCookie(); + void SetShouldAcceptCookies(bool accept); + bool GetShouldAcceptCookies(); void SetCookie(const GURL& host, const std::string& cookie_value, scoped_ptr<BoolCookieCallbackHolder> callback); @@ -330,20 +328,12 @@ scoped_refptr<net::CookieStore> CookieManager::GetCookieStore() { return cookie_monster_; } -void CookieManager::SetAcceptCookie(bool accept) { - AwCookieAccessPolicy::GetInstance()->SetGlobalAllowAccess(accept); +void CookieManager::SetShouldAcceptCookies(bool accept) { + AwCookieAccessPolicy::GetInstance()->SetShouldAcceptCookies(accept); } -bool CookieManager::AcceptCookie() { - return AwCookieAccessPolicy::GetInstance()->GetGlobalAllowAccess(); -} - -void CookieManager::SetAcceptThirdPartyCookie(bool accept) { - AwCookieAccessPolicy::GetInstance()->SetThirdPartyAllowAccess(accept); -} - -bool CookieManager::AcceptThirdPartyCookie() { - return AwCookieAccessPolicy::GetInstance()->GetThirdPartyAllowAccess(); +bool CookieManager::GetShouldAcceptCookies() { + return AwCookieAccessPolicy::GetInstance()->GetShouldAcceptCookies(); } void CookieManager::SetCookie( @@ -529,22 +519,12 @@ void CookieManager::SetAcceptFileSchemeCookiesLocked(bool accept) { } // namespace -static void SetAcceptCookie(JNIEnv* env, jobject obj, jboolean accept) { - CookieManager::GetInstance()->SetAcceptCookie(accept); -} - -static jboolean AcceptCookie(JNIEnv* env, jobject obj) { - return CookieManager::GetInstance()->AcceptCookie(); -} - -static void SetAcceptThirdPartyCookie(JNIEnv* env, - jobject obj, - jboolean accept) { - CookieManager::GetInstance()->SetAcceptThirdPartyCookie(accept); +static void SetShouldAcceptCookies(JNIEnv* env, jobject obj, jboolean accept) { + CookieManager::GetInstance()->SetShouldAcceptCookies(accept); } -static jboolean AcceptThirdPartyCookie(JNIEnv* env, jobject obj) { - return CookieManager::GetInstance()->AcceptThirdPartyCookie(); +static jboolean GetShouldAcceptCookies(JNIEnv* env, jobject obj) { + return CookieManager::GetInstance()->GetShouldAcceptCookies(); } static void SetCookie(JNIEnv* env, diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 6fa1ccf..4364f17 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -663,6 +663,7 @@ void RenderMessageFilter::OnDeleteCookie(const GURL& url, } void RenderMessageFilter::OnCookiesEnabled( + int render_frame_id, const GURL& url, const GURL& first_party_for_cookies, bool* cookies_enabled) { @@ -671,7 +672,7 @@ void RenderMessageFilter::OnCookiesEnabled( // host. *cookies_enabled = GetContentClient()->browser()->AllowGetCookie( url, first_party_for_cookies, net::CookieList(), resource_context_, - render_process_id_, MSG_ROUTING_CONTROL); + render_process_id_, render_frame_id); } #if defined(OS_MACOSX) diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index 038b30a..3682526 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h @@ -148,7 +148,8 @@ class RenderMessageFilter : public BrowserMessageFilter { IPC::Message* reply_msg); void OnDeleteCookie(const GURL& url, const std::string& cookieName); - void OnCookiesEnabled(const GURL& url, + void OnCookiesEnabled(int render_frame_id, + const GURL& url, const GURL& first_party_for_cookies, bool* cookies_enabled); diff --git a/content/common/view_messages.h b/content/common/view_messages.h index fbf7347..9061b50 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -1198,7 +1198,8 @@ IPC_SYNC_MESSAGE_CONTROL2_0(ViewHostMsg_DeleteCookie, // Used to check if cookies are enabled for the given URL. This may block // waiting for a previous SetCookie message to be processed. -IPC_SYNC_MESSAGE_CONTROL2_1(ViewHostMsg_CookiesEnabled, +IPC_SYNC_MESSAGE_CONTROL3_1(ViewHostMsg_CookiesEnabled, + int /* render_frame_id */, GURL /* url */, GURL /* first_party_for_cookies */, bool /* cookies_enabled */) diff --git a/content/renderer/renderer_webcookiejar_impl.cc b/content/renderer/renderer_webcookiejar_impl.cc index 40bef32..93d037a 100644 --- a/content/renderer/renderer_webcookiejar_impl.cc +++ b/content/renderer/renderer_webcookiejar_impl.cc @@ -71,7 +71,7 @@ bool RendererWebCookieJarImpl::cookiesEnabled( const WebURL& url, const WebURL& first_party_for_cookies) { bool cookies_enabled; sender_->Send(new ViewHostMsg_CookiesEnabled( - url, first_party_for_cookies, &cookies_enabled)); + sender_->GetRoutingID(), url, first_party_for_cookies, &cookies_enabled)); return cookies_enabled; } |