| // Copyright (c) 2012 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_network_delegate.h" |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/command_line.h" |
| #include "base/macros.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/run_loop.h" |
| #include "base/test/histogram_tester.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/content_settings/cookie_settings_factory.h" |
| #include "chrome/browser/net/reporting_permissions_checker.h" |
| #include "chrome/browser/net/safe_search_util.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/test/base/testing_browser_process.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "chrome/test/base/testing_profile_manager.h" |
| #include "components/content_settings/core/browser/cookie_settings.h" |
| #include "components/content_settings/core/common/pref_names.h" |
| #include "components/data_usage/core/data_use_aggregator.h" |
| #include "components/data_usage/core/data_use_amortizer.h" |
| #include "components/data_usage/core/data_use_annotator.h" |
| #include "components/prefs/pref_member.h" |
| #include "components/sync_preferences/testing_pref_service_syncable.h" |
| #include "content/public/browser/resource_request_info.h" |
| #include "content/public/common/content_switches.h" |
| #include "content/public/common/previews_state.h" |
| #include "content/public/common/resource_type.h" |
| #include "content/public/test/mock_permission_manager.h" |
| #include "content/public/test/test_browser_thread_bundle.h" |
| #include "content/public/test/test_utils.h" |
| #include "extensions/buildflags/buildflags.h" |
| #include "net/base/request_priority.h" |
| #include "net/http/http_request_headers.h" |
| #include "net/socket/socket_test_util.h" |
| #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" |
| #include "net/url_request/url_request.h" |
| #include "net/url_request/url_request_test_util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| #include "chrome/browser/extensions/event_router_forwarder.h" |
| #endif |
| |
| namespace { |
| |
| // This function requests a URL, and makes it return a known response. |
| // ResourceRequestInfo is attached to the URLRequest, to represent this request |
| // as an user initiated. |
| std::unique_ptr<net::URLRequest> RequestURL( |
| net::URLRequestContext* context, |
| net::MockClientSocketFactory* socket_factory) { |
| net::MockRead redirect_mock_reads[] = { |
| net::MockRead("HTTP/1.1 302 Found\r\n" |
| "Location: http://bar.com/\r\n\r\n"), |
| net::MockRead(net::SYNCHRONOUS, net::OK), |
| }; |
| net::StaticSocketDataProvider redirect_socket_data_provider( |
| redirect_mock_reads, base::span<net::MockWrite>()); |
| |
| net::MockRead response_mock_reads[] = { |
| net::MockRead("HTTP/1.1 200 OK\r\n\r\n"), net::MockRead("response body"), |
| net::MockRead(net::SYNCHRONOUS, net::OK), |
| }; |
| net::StaticSocketDataProvider response_socket_data_provider( |
| response_mock_reads, base::span<net::MockWrite>()); |
| socket_factory->AddSocketDataProvider(&response_socket_data_provider); |
| net::TestDelegate test_delegate; |
| test_delegate.set_quit_on_complete(true); |
| std::unique_ptr<net::URLRequest> request( |
| context->CreateRequest(GURL("http://example.com"), net::DEFAULT_PRIORITY, |
| &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); |
| |
| content::ResourceRequestInfo::AllocateForTesting( |
| request.get(), content::RESOURCE_TYPE_MAIN_FRAME, nullptr, -2, -2, -2, |
| true, true, true, content::PREVIEWS_OFF, nullptr); |
| |
| request->Start(); |
| base::RunLoop().RunUntilIdle(); |
| return request; |
| } |
| |
| // A fake DataUseAggregator for testing that only counts how many times its |
| // respective methods have been called. |
| class FakeDataUseAggregator : public data_usage::DataUseAggregator { |
| public: |
| FakeDataUseAggregator() |
| : data_usage::DataUseAggregator( |
| std::unique_ptr<data_usage::DataUseAnnotator>(), |
| std::unique_ptr<data_usage::DataUseAmortizer>()), |
| on_the_record_tx_bytes_(0), |
| on_the_record_rx_bytes_(0), |
| off_the_record_tx_bytes_(0), |
| off_the_record_rx_bytes_(0) {} |
| ~FakeDataUseAggregator() override {} |
| |
| void ReportDataUse(net::URLRequest* request, |
| int64_t tx_bytes, |
| int64_t rx_bytes) override { |
| on_the_record_tx_bytes_ += tx_bytes; |
| on_the_record_rx_bytes_ += rx_bytes; |
| } |
| |
| void ReportOffTheRecordDataUse(int64_t tx_bytes, int64_t rx_bytes) override { |
| off_the_record_tx_bytes_ += tx_bytes; |
| off_the_record_rx_bytes_ += rx_bytes; |
| } |
| |
| int64_t on_the_record_tx_bytes() const { return on_the_record_tx_bytes_; } |
| int64_t on_the_record_rx_bytes() const { return on_the_record_rx_bytes_; } |
| int64_t off_the_record_tx_bytes() const { return off_the_record_tx_bytes_; } |
| int64_t off_the_record_rx_bytes() const { return off_the_record_rx_bytes_; } |
| |
| private: |
| int64_t on_the_record_tx_bytes_; |
| int64_t on_the_record_rx_bytes_; |
| int64_t off_the_record_tx_bytes_; |
| int64_t off_the_record_rx_bytes_; |
| }; |
| |
| // Helper function to make the IsAccessAllowed test concise. |
| bool IsAccessAllowed(const std::string& path, |
| const std::string& profile_path) { |
| return ChromeNetworkDelegate::IsAccessAllowed( |
| base::FilePath::FromUTF8Unsafe(path), |
| base::FilePath::FromUTF8Unsafe(profile_path)); |
| } |
| |
| } // namespace |
| |
| class ChromeNetworkDelegateTest : public testing::Test { |
| public: |
| ChromeNetworkDelegateTest() |
| : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
| context_(new net::TestURLRequestContext(true)) { |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| forwarder_ = new extensions::EventRouterForwarder(); |
| #endif |
| } |
| |
| void SetUp() override { |
| ChromeNetworkDelegate::InitializePrefsOnUIThread( |
| &enable_referrers_, nullptr, nullptr, nullptr, |
| profile_.GetTestingPrefService()); |
| profile_manager_.reset( |
| new TestingProfileManager(TestingBrowserProcess::GetGlobal())); |
| ASSERT_TRUE(profile_manager_->SetUp()); |
| } |
| |
| virtual void Initialize() { |
| network_delegate_.reset( |
| new ChromeNetworkDelegate(forwarder(), &enable_referrers_)); |
| context_->set_client_socket_factory(&socket_factory_); |
| context_->set_network_delegate(network_delegate_.get()); |
| context_->Init(); |
| } |
| |
| net::TestURLRequestContext* context() { return context_.get(); } |
| net::NetworkDelegate* network_delegate() { return network_delegate_.get(); } |
| net::MockClientSocketFactory* socket_factory() { return &socket_factory_; } |
| |
| ChromeNetworkDelegate* chrome_network_delegate() { |
| return network_delegate_.get(); |
| } |
| |
| extensions::EventRouterForwarder* forwarder() { |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| return forwarder_.get(); |
| #else |
| return nullptr; |
| #endif |
| } |
| |
| private: |
| std::unique_ptr<TestingProfileManager> profile_manager_; |
| content::TestBrowserThreadBundle thread_bundle_; |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| scoped_refptr<extensions::EventRouterForwarder> forwarder_; |
| #endif |
| TestingProfile profile_; |
| BooleanPrefMember enable_referrers_; |
| std::unique_ptr<ChromeNetworkDelegate> network_delegate_; |
| net::MockClientSocketFactory socket_factory_; |
| std::unique_ptr<net::TestURLRequestContext> context_; |
| }; |
| |
| TEST_F(ChromeNetworkDelegateTest, DisableSameSiteCookiesIffFlagDisabled) { |
| Initialize(); |
| EXPECT_FALSE(network_delegate()->AreExperimentalCookieFeaturesEnabled()); |
| } |
| |
| TEST_F(ChromeNetworkDelegateTest, EnableSameSiteCookiesIffFlagEnabled) { |
| base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| switches::kEnableExperimentalWebPlatformFeatures); |
| Initialize(); |
| EXPECT_TRUE(network_delegate()->AreExperimentalCookieFeaturesEnabled()); |
| } |
| |
| TEST_F(ChromeNetworkDelegateTest, ReportDataUseToAggregator) { |
| FakeDataUseAggregator fake_aggregator; |
| Initialize(); |
| |
| chrome_network_delegate()->set_data_use_aggregator( |
| &fake_aggregator, false /* is_data_usage_off_the_record */); |
| |
| std::unique_ptr<net::URLRequest> request = |
| RequestURL(context(), socket_factory()); |
| EXPECT_EQ(request->GetTotalSentBytes(), |
| fake_aggregator.on_the_record_tx_bytes()); |
| EXPECT_EQ(request->GetTotalReceivedBytes(), |
| fake_aggregator.on_the_record_rx_bytes()); |
| EXPECT_EQ(0, fake_aggregator.off_the_record_tx_bytes()); |
| EXPECT_EQ(0, fake_aggregator.off_the_record_rx_bytes()); |
| } |
| |
| TEST_F(ChromeNetworkDelegateTest, ReportOffTheRecordDataUseToAggregator) { |
| FakeDataUseAggregator fake_aggregator; |
| Initialize(); |
| |
| chrome_network_delegate()->set_data_use_aggregator( |
| &fake_aggregator, true /* is_data_usage_off_the_record */); |
| std::unique_ptr<net::URLRequest> request = |
| RequestURL(context(), socket_factory()); |
| |
| EXPECT_EQ(0, fake_aggregator.on_the_record_tx_bytes()); |
| EXPECT_EQ(0, fake_aggregator.on_the_record_rx_bytes()); |
| EXPECT_EQ(request->GetTotalSentBytes(), |
| fake_aggregator.off_the_record_tx_bytes()); |
| EXPECT_EQ(request->GetTotalReceivedBytes(), |
| fake_aggregator.off_the_record_rx_bytes()); |
| } |
| |
| TEST_F(ChromeNetworkDelegateTest, HttpRequestCompletionErrorCodes) { |
| Initialize(); |
| |
| const struct { |
| const GURL url; |
| int net_error; |
| bool is_main_frame; |
| int expected_sample_bucket; |
| int expected_request_completion_count; |
| int expected_request_completion_main_frame_count; |
| } kTests[] = { |
| {GURL("http://example.com"), net::OK, true, std::abs(net::OK), 1, 1}, |
| {GURL("http://example.com"), net::ERR_ABORTED, true, |
| std::abs(net::ERR_ABORTED), 1, 1}, |
| {GURL("http://example.com"), net::OK, false, std::abs(net::OK), 1, 0}, |
| {GURL("https://example.com"), net::OK, true, std::abs(net::OK), 0, 0}, |
| }; |
| |
| const char kHttpRequestCompletionErrorCode[] = |
| "Net.HttpRequestCompletionErrorCodes"; |
| const char kHttpRequestCompletionErrorCodeMainFrame[] = |
| "Net.HttpRequestCompletionErrorCodes.MainFrame"; |
| |
| for (const auto& test : kTests) { |
| base::HistogramTester histograms; |
| |
| net::TestDelegate test_delegate; |
| std::unique_ptr<net::URLRequest> request( |
| context()->CreateRequest(test.url, net::DEFAULT_PRIORITY, |
| &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); |
| if (test.is_main_frame) { |
| request->SetLoadFlags(request->load_flags() | |
| net::LOAD_MAIN_FRAME_DEPRECATED); |
| } |
| network_delegate()->NotifyCompleted(request.get(), false, test.net_error); |
| |
| histograms.ExpectTotalCount(kHttpRequestCompletionErrorCode, |
| test.expected_request_completion_count); |
| histograms.ExpectUniqueSample(kHttpRequestCompletionErrorCode, |
| test.expected_sample_bucket, |
| test.expected_request_completion_count); |
| histograms.ExpectTotalCount( |
| kHttpRequestCompletionErrorCodeMainFrame, |
| test.expected_request_completion_main_frame_count); |
| histograms.ExpectUniqueSample( |
| kHttpRequestCompletionErrorCodeMainFrame, test.expected_sample_bucket, |
| test.expected_request_completion_main_frame_count); |
| } |
| } |
| |
| class ChromeNetworkDelegatePolicyTest : public testing::Test { |
| public: |
| ChromeNetworkDelegatePolicyTest() |
| : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) { |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| forwarder_ = new extensions::EventRouterForwarder(); |
| #endif |
| } |
| |
| protected: |
| void SetDelegate(net::NetworkDelegate* delegate) { |
| context_.set_network_delegate(delegate); |
| } |
| |
| extensions::EventRouterForwarder* forwarder() { |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| return forwarder_.get(); |
| #else |
| return nullptr; |
| #endif |
| } |
| |
| content::TestBrowserThreadBundle thread_bundle_; |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| scoped_refptr<extensions::EventRouterForwarder> forwarder_; |
| #endif |
| TestingProfile profile_; |
| BooleanPrefMember enable_referrers_; |
| net::TestURLRequestContext context_; |
| net::TestDelegate delegate_; |
| DISALLOW_COPY_AND_ASSIGN(ChromeNetworkDelegatePolicyTest); |
| }; |
| |
| class ChromeNetworkDelegateSafeSearchTest : |
| public ChromeNetworkDelegatePolicyTest { |
| public: |
| void SetUp() override { |
| ChromeNetworkDelegate::InitializePrefsOnUIThread( |
| &enable_referrers_, |
| &force_google_safe_search_, |
| &force_youtube_restrict_, |
| nullptr, |
| profile_.GetTestingPrefService()); |
| } |
| |
| protected: |
| std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() { |
| std::unique_ptr<ChromeNetworkDelegate> network_delegate( |
| new ChromeNetworkDelegate(forwarder(), &enable_referrers_)); |
| network_delegate->set_force_google_safe_search(&force_google_safe_search_); |
| network_delegate->set_force_youtube_restrict(&force_youtube_restrict_); |
| return std::move(network_delegate); |
| } |
| |
| void SetSafeSearch(bool google_safe_search, int youtube_restrict) { |
| force_google_safe_search_.SetValue(google_safe_search); |
| force_youtube_restrict_.SetValue(youtube_restrict); |
| } |
| |
| // Does a request to an arbitrary URL and verifies that the SafeSearch |
| // enforcement utility functions were called/not called as expected. |
| void QueryURL(bool expect_google_safe_search, bool expect_youtube_restrict) { |
| safe_search_util::ClearForceGoogleSafeSearchCountForTesting(); |
| safe_search_util::ClearForceYouTubeRestrictCountForTesting(); |
| |
| std::unique_ptr<net::URLRequest> request( |
| context_.CreateRequest(GURL("http://anyurl.com"), net::DEFAULT_PRIORITY, |
| &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS)); |
| |
| request->Start(); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(expect_google_safe_search ? 1 : 0, |
| safe_search_util::GetForceGoogleSafeSearchCountForTesting()); |
| EXPECT_EQ(expect_youtube_restrict ? 1 : 0, |
| safe_search_util::GetForceYouTubeRestrictCountForTesting()); |
| } |
| |
| private: |
| BooleanPrefMember force_google_safe_search_; |
| IntegerPrefMember force_youtube_restrict_; |
| }; |
| |
| TEST_F(ChromeNetworkDelegateSafeSearchTest, SafeSearch) { |
| std::unique_ptr<net::NetworkDelegate> delegate(CreateNetworkDelegate()); |
| SetDelegate(delegate.get()); |
| |
| static_assert(safe_search_util::YOUTUBE_RESTRICT_OFF == 0 && |
| safe_search_util::YOUTUBE_RESTRICT_MODERATE == 1 && |
| safe_search_util::YOUTUBE_RESTRICT_STRICT == 2 && |
| safe_search_util::YOUTUBE_RESTRICT_COUNT == 3, |
| "This test relies on mapping ints to enum values."); |
| |
| // Loop over all combinations of the two policies. |
| for (int i = 0; i < 6; i++) { |
| bool google_safe_search = (i / 3) != 0; |
| int youtube_restrict = i % 3; |
| SetSafeSearch(google_safe_search, youtube_restrict); |
| |
| QueryURL(google_safe_search, youtube_restrict != 0); |
| } |
| } |
| |
| class ChromeNetworkDelegateAllowedDomainsTest : |
| public ChromeNetworkDelegatePolicyTest { |
| public: |
| |
| void SetUp() override { |
| ChromeNetworkDelegate::InitializePrefsOnUIThread( |
| &enable_referrers_, |
| nullptr, |
| nullptr, |
| &allowed_domains_for_apps_, |
| profile_.GetTestingPrefService()); |
| } |
| |
| protected: |
| std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() { |
| std::unique_ptr<ChromeNetworkDelegate> network_delegate( |
| new ChromeNetworkDelegate(forwarder(), &enable_referrers_)); |
| network_delegate->set_allowed_domains_for_apps(&allowed_domains_for_apps_); |
| return std::move(network_delegate); |
| } |
| |
| // Will set the AllowedDomainsForApps policy to have the value of |allowed|. |
| // Will make a request to |url| and check the headers in request. |
| // If |expected| is passed as false, this routine verifies that no |
| // X-GoogApps-Allowed-Domains header is set. If |expected| is passed as true, |
| // this routine verifies that the X-GoogApps-Allowed-Domains header is set and |
| // the value is identical to |allowed|. |
| void CheckAllowedDomainsHeaders(const std::string& allowed, |
| const GURL& url, |
| bool expected) { |
| allowed_domains_for_apps_.SetValue(allowed); |
| |
| std::unique_ptr<net::URLRequest> request(context_.CreateRequest( |
| url, net::DEFAULT_PRIORITY, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS)); |
| |
| request->Start(); |
| base::RunLoop().RunUntilIdle(); |
| |
| net::HttpRequestHeaders request_headers = request->extra_request_headers(); |
| |
| const char allowed_domains_header_name[] = "X-GoogApps-Allowed-Domains"; |
| EXPECT_EQ(expected, request_headers.HasHeader(allowed_domains_header_name)); |
| |
| if (expected) { |
| std::string header_value; |
| request_headers.GetHeader(allowed_domains_header_name, &header_value); |
| EXPECT_EQ(allowed, header_value); |
| } |
| } |
| |
| private: |
| StringPrefMember allowed_domains_for_apps_; |
| }; |
| |
| // Test the use case when the AllowedDomainsForApps policy is set and |
| // a request is done to Google servers. We expect the request |
| // headers to contain X-GoogApps-Allowed-Domains key and its value to be equal |
| // to the value from the policy. |
| TEST_F(ChromeNetworkDelegateAllowedDomainsTest, AllowedDomainsIncluded) { |
| std::unique_ptr<net::NetworkDelegate> delegate(CreateNetworkDelegate()); |
| SetDelegate(delegate.get()); |
| |
| CheckAllowedDomainsHeaders("gmail.com,mit.edu", GURL("http://google.com"), |
| true); |
| } |
| |
| // Test the use case when the AllowedDomainsForApps policy is empty and |
| // a request is done to Google servers. We expect the request |
| // headers to not contain X-GoogApps-Allowed-Domains key because the policy |
| // is not set. |
| TEST_F(ChromeNetworkDelegateAllowedDomainsTest, AllowedDomainsEmpty) { |
| std::unique_ptr<net::NetworkDelegate> delegate(CreateNetworkDelegate()); |
| SetDelegate(delegate.get()); |
| CheckAllowedDomainsHeaders("", GURL("http://google.com"), false); |
| } |
| |
| // Test the use case when the AllowedDomainsForApps policy is set and |
| // a request is done to a non-Google domain. We expect the request |
| // headers to not contain X-GoogApps-Allowed-Domains key because the |
| // accessed URL is not from google.com domain. |
| TEST_F(ChromeNetworkDelegateAllowedDomainsTest, AllowedDomainsNonGoogleUrl) { |
| std::unique_ptr<net::NetworkDelegate> delegate(CreateNetworkDelegate()); |
| SetDelegate(delegate.get()); |
| CheckAllowedDomainsHeaders("google.com", GURL("http://example.com"), false); |
| } |
| |
| // Privacy Mode disables Channel Id if cookies are blocked (cr223191) |
| class ChromeNetworkDelegatePrivacyModeTest : public testing::Test { |
| public: |
| ChromeNetworkDelegatePrivacyModeTest() |
| : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| forwarder_(new extensions::EventRouterForwarder()), |
| #endif |
| cookie_settings_(CookieSettingsFactory::GetForProfile(&profile_).get()), |
| kBlockedSite("http://ads.thirdparty.com"), |
| kAllowedSite("http://good.allays.com"), |
| kFirstPartySite("http://cool.things.com"), |
| kBlockedFirstPartySite("http://no.thirdparties.com") { |
| } |
| |
| void SetUp() override { |
| ChromeNetworkDelegate::InitializePrefsOnUIThread( |
| &enable_referrers_, nullptr, nullptr, nullptr, |
| profile_.GetTestingPrefService()); |
| } |
| |
| protected: |
| std::unique_ptr<ChromeNetworkDelegate> CreateNetworkDelegate() { |
| std::unique_ptr<ChromeNetworkDelegate> network_delegate( |
| new ChromeNetworkDelegate(forwarder(), &enable_referrers_)); |
| network_delegate->set_cookie_settings(cookie_settings_); |
| return network_delegate; |
| } |
| |
| void SetDelegate(net::NetworkDelegate* delegate) { |
| network_delegate_ = delegate; |
| context_.set_network_delegate(network_delegate_); |
| } |
| |
| protected: |
| extensions::EventRouterForwarder* forwarder() { |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| return forwarder_.get(); |
| #else |
| return NULL; |
| #endif |
| } |
| |
| content::TestBrowserThreadBundle thread_bundle_; |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| scoped_refptr<extensions::EventRouterForwarder> forwarder_; |
| #endif |
| TestingProfile profile_; |
| content_settings::CookieSettings* cookie_settings_; |
| BooleanPrefMember enable_referrers_; |
| std::unique_ptr<net::URLRequest> request_; |
| net::TestURLRequestContext context_; |
| net::NetworkDelegate* network_delegate_; |
| |
| const GURL kBlockedSite; |
| const GURL kAllowedSite; |
| const GURL kEmptyFirstPartySite; |
| const GURL kFirstPartySite; |
| const GURL kBlockedFirstPartySite; |
| }; |
| |
| TEST_F(ChromeNetworkDelegatePrivacyModeTest, DisablePrivacyIfCookiesAllowed) { |
| std::unique_ptr<ChromeNetworkDelegate> delegate(CreateNetworkDelegate()); |
| SetDelegate(delegate.get()); |
| |
| EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, |
| kEmptyFirstPartySite)); |
| } |
| |
| |
| TEST_F(ChromeNetworkDelegatePrivacyModeTest, EnablePrivacyIfCookiesBlocked) { |
| std::unique_ptr<ChromeNetworkDelegate> delegate(CreateNetworkDelegate()); |
| SetDelegate(delegate.get()); |
| |
| EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kBlockedSite, |
| kEmptyFirstPartySite)); |
| |
| cookie_settings_->SetCookieSetting(kBlockedSite, CONTENT_SETTING_BLOCK); |
| EXPECT_TRUE(network_delegate_->CanEnablePrivacyMode(kBlockedSite, |
| kEmptyFirstPartySite)); |
| } |
| |
| TEST_F(ChromeNetworkDelegatePrivacyModeTest, EnablePrivacyIfThirdPartyBlocked) { |
| std::unique_ptr<ChromeNetworkDelegate> delegate(CreateNetworkDelegate()); |
| SetDelegate(delegate.get()); |
| |
| EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, |
| kFirstPartySite)); |
| |
| profile_.GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, true); |
| EXPECT_TRUE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, |
| kFirstPartySite)); |
| profile_.GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, false); |
| EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, |
| kFirstPartySite)); |
| } |
| |
| TEST_F(ChromeNetworkDelegatePrivacyModeTest, |
| DisablePrivacyIfOnlyFirstPartyBlocked) { |
| std::unique_ptr<ChromeNetworkDelegate> delegate(CreateNetworkDelegate()); |
| SetDelegate(delegate.get()); |
| |
| EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, |
| kBlockedFirstPartySite)); |
| |
| cookie_settings_->SetCookieSetting(kBlockedFirstPartySite, |
| CONTENT_SETTING_BLOCK); |
| // Privacy mode is disabled as kAllowedSite is still getting cookies |
| EXPECT_FALSE(network_delegate_->CanEnablePrivacyMode(kAllowedSite, |
| kBlockedFirstPartySite)); |
| } |
| |
| TEST(ChromeNetworkDelegateStaticTest, IsAccessAllowed) { |
| #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) |
| // Platforms other than Chrome OS and Android have access to any files. |
| EXPECT_TRUE(IsAccessAllowed("/", "")); |
| EXPECT_TRUE(IsAccessAllowed("/foo.txt", "")); |
| #endif |
| |
| #if defined(OS_CHROMEOS) || defined(OS_ANDROID) |
| // Chrome OS and Android don't have access to random files. |
| EXPECT_FALSE(IsAccessAllowed("/", "")); |
| EXPECT_FALSE(IsAccessAllowed("/foo.txt", "")); |
| // Empty path should not be allowed. |
| EXPECT_FALSE(IsAccessAllowed("", "")); |
| #endif |
| |
| #if defined(OS_CHROMEOS) |
| base::FilePath temp_dir; |
| ASSERT_TRUE(base::PathService::Get(base::DIR_TEMP, &temp_dir)); |
| // Chrome OS allows the following directories. |
| EXPECT_TRUE(IsAccessAllowed("/home/chronos/user/Downloads", "")); |
| EXPECT_TRUE(IsAccessAllowed("/home/chronos/user/log", "")); |
| EXPECT_TRUE(IsAccessAllowed("/home/chronos/user/WebRTC Logs", "")); |
| EXPECT_TRUE(IsAccessAllowed("/media", "")); |
| EXPECT_TRUE(IsAccessAllowed("/opt/oem", "")); |
| EXPECT_TRUE(IsAccessAllowed("/usr/share/chromeos-assets", "")); |
| EXPECT_TRUE(IsAccessAllowed(temp_dir.AsUTF8Unsafe(), "")); |
| EXPECT_TRUE(IsAccessAllowed("/var/log", "")); |
| // Files under the directories are allowed. |
| EXPECT_TRUE(IsAccessAllowed("/var/log/foo.txt", "")); |
| // Make sure similar paths are not allowed. |
| EXPECT_FALSE(IsAccessAllowed("/home/chronos/user/log.txt", "")); |
| EXPECT_FALSE(IsAccessAllowed("/home/chronos/user", "")); |
| EXPECT_FALSE(IsAccessAllowed("/home/chronos", "")); |
| |
| // If profile path is given, the following additional paths are allowed. |
| EXPECT_TRUE(IsAccessAllowed("/profile/Downloads", "/profile")); |
| EXPECT_TRUE(IsAccessAllowed("/profile/WebRTC Logs", "/profile")); |
| |
| #elif defined(OS_ANDROID) |
| // Android allows the following directories. |
| EXPECT_TRUE(IsAccessAllowed("/sdcard", "")); |
| EXPECT_TRUE(IsAccessAllowed("/mnt/sdcard", "")); |
| // Files under the directories are allowed. |
| EXPECT_TRUE(IsAccessAllowed("/sdcard/foo.txt", "")); |
| // Make sure similar paths are not allowed. |
| EXPECT_FALSE(IsAccessAllowed("/mnt/sdcard.txt", "")); |
| EXPECT_FALSE(IsAccessAllowed("/mnt", "")); |
| |
| // Files in external storage are allowed. |
| base::FilePath external_storage_path; |
| base::PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE, |
| &external_storage_path); |
| EXPECT_TRUE(IsAccessAllowed( |
| external_storage_path.AppendASCII("foo.txt").AsUTF8Unsafe(), "")); |
| // The external storage root itself is not allowed. |
| EXPECT_FALSE(IsAccessAllowed(external_storage_path.AsUTF8Unsafe(), "")); |
| #endif |
| } |
| |
| namespace { |
| |
| class TestingPermissionProfile : public TestingProfile { |
| public: |
| TestingPermissionProfile() = default; |
| |
| content::MockPermissionManager* mock_permission_manager() { |
| return &mock_permission_manager_; |
| } |
| |
| content::PermissionManager* GetPermissionManager() override { |
| return &mock_permission_manager_; |
| } |
| |
| private: |
| content::MockPermissionManager mock_permission_manager_; |
| }; |
| |
| } // namespace |
| |
| class ChromeNetworkDelegateReportingTest : public ChromeNetworkDelegateTest { |
| public: |
| ChromeNetworkDelegateReportingTest() = default; |
| |
| content::MockPermissionManager* mock_permission_manager() { |
| return profile_.mock_permission_manager(); |
| } |
| |
| void Initialize() override { |
| ChromeNetworkDelegateTest::Initialize(); |
| chrome_network_delegate()->set_reporting_permissions_checker( |
| std::make_unique<ReportingPermissionsChecker>(&profile_)); |
| } |
| |
| protected: |
| TestingPermissionProfile profile_; |
| DISALLOW_COPY_AND_ASSIGN(ChromeNetworkDelegateReportingTest); |
| }; |
| |
| TEST_F(ChromeNetworkDelegateReportingTest, ChecksReportingPermissions) { |
| using testing::_; |
| using testing::Return; |
| |
| Initialize(); |
| |
| auto origin1 = url::Origin::Create(GURL("https://example.com/")); |
| auto origin2 = url::Origin::Create(GURL("https://foo.example.com/")); |
| |
| std::set<url::Origin> origins = {origin1, origin2}; |
| |
| EXPECT_CALL(*mock_permission_manager(), |
| GetPermissionStatus(_, origin1.GetURL(), _)) |
| .WillOnce(Return(blink::mojom::PermissionStatus::GRANTED)); |
| EXPECT_CALL(*mock_permission_manager(), |
| GetPermissionStatus(_, origin2.GetURL(), _)) |
| .WillOnce(Return(blink::mojom::PermissionStatus::DENIED)); |
| |
| std::set<url::Origin> allowed_origins; |
| chrome_network_delegate()->CanSendReportingReports( |
| std::move(origins), |
| base::BindOnce( |
| [](std::set<url::Origin>* dest, std::set<url::Origin> result) { |
| *dest = std::move(result); |
| }, |
| &allowed_origins)); |
| content::RunAllTasksUntilIdle(); |
| |
| ASSERT_EQ(1u, allowed_origins.size()); |
| EXPECT_EQ(origin1, *allowed_origins.begin()); |
| } |