blob: 0cf3d095d90bf103c6133bf7b813501ea43bb385 [file] [log] [blame]
// 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.
//
// This file is in maintenance mode, please do NOT add new tests into this file.
//
// policy_browsertests.cc contains lots of tests for multiple policies. However,
// it became huge with hundreds of policies. Instead of adding even more tests
// here, please put new ones with the policy implementation. For example, a
// network policy test can be moved to chrome/browser/net.
//
// Policy component dependency is not necessary for policy test. Most of
// policy values are copied into local state or Profile prefs. They can be used
// to enable policy during test.
//
// Simple policy to prefs mapping can be tested with policy_test_cases.json. If
// the conversion is complicated and requires custom policy handler, we
// recommend to test the handler separately.
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/atomic_ref_count.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/feature_list.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/current_thread.h"
#include "base/task/post_task.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/apps/app_service/browser_app_launcher.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/devtools/devtools_window_testing.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/extensions/api/chrome_extensions_api_client.h"
#include "chrome/browser/policy/policy_test_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/search/ntp_test_utils.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/locale_settings.h"
#include "chrome/test/base/search_test_utils.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/network_time/network_time_tracker.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/policy_constants.h"
#include "components/security_interstitials/content/security_interstitial_page.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/strings/grit/components_strings.h"
#include "components/update_client/update_client_errors.h"
#include "components/version_info/version_info.h"
#include "content/common/content_navigation_policy.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/mock_notification_observer.h"
#include "content/public/test/network_service_test_helper.h"
#include "content/public/test/no_renderer_crashes_assertion.h"
#include "content/public/test/signed_exchange_browser_test_helper.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/messaging/messaging_delegate.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/uninstall_reason.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/switches.h"
#include "media/media_buildflags.h"
#include "net/base/net_errors.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "sandbox/policy/sandbox_type.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"
#include "url/origin.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/public/cpp/ash_pref_names.h"
#include "ash/public/cpp/ash_switches.h"
#include "chrome/browser/ash/login/test/js_checker.h"
#include "chrome/browser/ash/system/timezone_resolver_manager.h"
#include "chrome/browser/chromeos/note_taking_helper.h"
#include "chrome/browser/ui/ash/chrome_screenshot_grabber.h"
#include "chrome/browser/ui/ash/chrome_screenshot_grabber_test_observer.h"
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/user_manager.h"
#include "ui/snapshot/screenshot_grabber.h"
#endif
#if !defined(OS_MAC)
#include "base/compiler_specific.h"
#endif
#if !defined(OS_ANDROID)
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
#endif
using content::BrowserThread;
using testing::_;
using testing::AtLeast;
using testing::Mock;
using testing::Return;
namespace policy {
namespace {
#if BUILDFLAG(IS_CHROMEOS_ASH)
const int kOneHourInMs = 60 * 60 * 1000;
const int kThreeHoursInMs = 180 * 60 * 1000;
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
int CountScreenshots() {
DownloadPrefs* download_prefs =
DownloadPrefs::FromBrowserContext(ProfileManager::GetActiveUserProfile());
base::FileEnumerator enumerator(download_prefs->DownloadPath(), false,
base::FileEnumerator::FILES, "Screenshot*");
int count = 0;
while (!enumerator.Next().empty())
count++;
return count;
}
#endif
// Checks if WebGL is enabled in the given WebContents.
bool IsWebGLEnabled(content::WebContents* contents) {
bool result = false;
EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
contents,
"var canvas = document.createElement('canvas');"
"var context = canvas.getContext('webgl');"
"domAutomationController.send(context != null);",
&result));
return result;
}
} // namespace
// This test is flaky on Windows 10: https://crbug.com/1069558
#if defined(OS_WIN)
#define MAYBE_Disable3DAPIs DISABLED_Disable3DAPIs
#else
#define MAYBE_Disable3DAPIs Disable3DAPIs
#endif
IN_PROC_BROWSER_TEST_F(PolicyTest, MAYBE_Disable3DAPIs) {
// This test assumes Gpu access.
if (!content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled())
return;
ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
// WebGL is enabled by default.
content::WebContents* contents =
browser()->tab_strip_model()->GetActiveWebContents();
EXPECT_TRUE(IsWebGLEnabled(contents));
// Disable with a policy.
PolicyMap policies;
policies.Set(key::kDisable3DAPIs, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
POLICY_SOURCE_CLOUD, base::Value(true), nullptr);
UpdateProviderPolicy(policies);
// Crash and reload the tab to get a new renderer.
content::CrashTab(contents);
EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_RELOAD));
if (content::ShouldSkipEarlyCommitPendingForCrashedFrame())
EXPECT_TRUE(content::WaitForLoadStop(contents));
EXPECT_FALSE(IsWebGLEnabled(contents));
// Enable with a policy.
policies.Set(key::kDisable3DAPIs, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
POLICY_SOURCE_CLOUD, base::Value(false), nullptr);
UpdateProviderPolicy(policies);
content::CrashTab(contents);
EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_RELOAD));
if (content::ShouldSkipEarlyCommitPendingForCrashedFrame())
EXPECT_TRUE(content::WaitForLoadStop(contents));
EXPECT_TRUE(IsWebGLEnabled(contents));
}
#if defined(OS_MAC) && !defined(NDEBUG)
// Times out on mac-debug.
// TODO(crbug.com/1159423): Re-enable
#define MAYBE_HomepageLocation DISABLED_HomepageLocation
#else
#define MAYBE_HomepageLocation HomepageLocation
#endif
IN_PROC_BROWSER_TEST_F(PolicyTest, MAYBE_HomepageLocation) {
// Verifies that the homepage can be configured with policies.
// Set a default, and check that the home button navigates there.
browser()->profile()->GetPrefs()->SetString(prefs::kHomePage,
chrome::kChromeUIPolicyURL);
browser()->profile()->GetPrefs()->SetBoolean(prefs::kHomePageIsNewTabPage,
false);
EXPECT_EQ(GURL(chrome::kChromeUIPolicyURL),
browser()->profile()->GetHomePage());
content::WebContents* contents =
browser()->tab_strip_model()->GetActiveWebContents();
EXPECT_EQ(GURL(url::kAboutBlankURL), contents->GetURL());
EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_HOME));
EXPECT_EQ(GURL(chrome::kChromeUIPolicyURL), contents->GetURL());
// Now override with policy.
PolicyMap policies;
policies.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(chrome::kChromeUICreditsURL), nullptr);
UpdateProviderPolicy(policies);
EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_HOME));
EXPECT_TRUE(content::WaitForLoadStop(contents));
EXPECT_EQ(GURL(chrome::kChromeUICreditsURL), contents->GetURL());
policies.Set(key::kHomepageIsNewTabPage, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(true),
nullptr);
UpdateProviderPolicy(policies);
EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_HOME));
EXPECT_TRUE(content::WaitForLoadStop(contents));
EXPECT_EQ(ntp_test_utils::GetFinalNtpUrl(browser()->profile()),
contents->GetURL());
}
#if defined(OS_MAC) && defined(ADDRESS_SANITIZER)
// Flaky on ASAN on Mac. See https://crbug.com/674497.
#define MAYBE_IncognitoEnabled DISABLED_IncognitoEnabled
#else
#define MAYBE_IncognitoEnabled IncognitoEnabled
#endif
IN_PROC_BROWSER_TEST_F(PolicyTest, MAYBE_IncognitoEnabled) {
// Verifies that incognito windows can't be opened when disabled by policy.
const BrowserList* active_browser_list = BrowserList::GetInstance();
// Disable incognito via policy and verify that incognito windows can't be
// opened.
EXPECT_EQ(1u, active_browser_list->size());
EXPECT_FALSE(BrowserList::IsOffTheRecordBrowserActive());
PolicyMap policies;
policies.Set(key::kIncognitoEnabled, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(false),
nullptr);
UpdateProviderPolicy(policies);
EXPECT_FALSE(chrome::ExecuteCommand(browser(), IDC_NEW_INCOGNITO_WINDOW));
EXPECT_EQ(1u, active_browser_list->size());
EXPECT_FALSE(BrowserList::IsOffTheRecordBrowserActive());
// Enable via policy and verify that incognito windows can be opened.
policies.Set(key::kIncognitoEnabled, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(true),
nullptr);
UpdateProviderPolicy(policies);
EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_NEW_INCOGNITO_WINDOW));
EXPECT_EQ(2u, active_browser_list->size());
EXPECT_TRUE(BrowserList::IsOffTheRecordBrowserActive());
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
// Flaky on MSan (crbug.com/476964) and regular Chrome OS (crbug.com/645769).
IN_PROC_BROWSER_TEST_F(PolicyTest, DISABLED_DisableScreenshotsFile) {
int screenshot_count = CountScreenshots();
// Make sure screenshots are counted correctly.
TestScreenshotFile(true);
ASSERT_EQ(CountScreenshots(), screenshot_count + 1);
// Check if trying to take a screenshot fails when disabled by policy.
TestScreenshotFile(false);
ASSERT_EQ(CountScreenshots(), screenshot_count + 1);
}
// Disabled, see http://crbug.com/554728.
IN_PROC_BROWSER_TEST_F(PolicyTest,
DISABLED_PRE_WaitForInitialUserActivityUnsatisfied) {
// Indicate that the session started 2 hours ago and no user activity has
// occurred yet.
g_browser_process->local_state()->SetInt64(
prefs::kSessionStartTime,
(base::Time::Now() - base::TimeDelta::FromHours(2)).ToInternalValue());
}
// Disabled, see http://crbug.com/554728.
IN_PROC_BROWSER_TEST_F(PolicyTest,
DISABLED_WaitForInitialUserActivityUnsatisfied) {
content::MockNotificationObserver observer;
content::NotificationRegistrar registrar;
registrar.Add(&observer, chrome::NOTIFICATION_APP_TERMINATING,
content::NotificationService::AllSources());
// Require initial user activity.
PolicyMap policies;
policies.Set(key::kWaitForInitialUserActivity, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(true),
nullptr);
UpdateProviderPolicy(policies);
base::RunLoop().RunUntilIdle();
// Set the session length limit to 1 hour. Verify that the session is not
// terminated.
EXPECT_CALL(observer, Observe(chrome::NOTIFICATION_APP_TERMINATING, _, _))
.Times(0);
policies.Set(key::kSessionLengthLimit, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(kOneHourInMs), nullptr);
UpdateProviderPolicy(policies);
base::RunLoop().RunUntilIdle();
Mock::VerifyAndClearExpectations(&observer);
}
IN_PROC_BROWSER_TEST_F(PolicyTest, PRE_WaitForInitialUserActivitySatisfied) {
// Indicate that initial user activity in this session occurred 2 hours ago.
g_browser_process->local_state()->SetInt64(
prefs::kSessionStartTime,
(base::Time::Now() - base::TimeDelta::FromHours(2)).ToInternalValue());
g_browser_process->local_state()->SetBoolean(prefs::kSessionUserActivitySeen,
true);
}
IN_PROC_BROWSER_TEST_F(PolicyTest, WaitForInitialUserActivitySatisfied) {
content::MockNotificationObserver observer;
content::NotificationRegistrar registrar;
registrar.Add(&observer, chrome::NOTIFICATION_APP_TERMINATING,
content::NotificationService::AllSources());
// Require initial user activity and set the session length limit to 3 hours.
// Verify that the session is not terminated.
EXPECT_CALL(observer, Observe(chrome::NOTIFICATION_APP_TERMINATING, _, _))
.Times(0);
PolicyMap policies;
policies.Set(key::kWaitForInitialUserActivity, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(true),
nullptr);
policies.Set(key::kSessionLengthLimit, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(kThreeHoursInMs), nullptr);
UpdateProviderPolicy(policies);
base::RunLoop().RunUntilIdle();
Mock::VerifyAndClearExpectations(&observer);
// Decrease the session length limit to 1 hour. Verify that the session is
// terminated immediately.
EXPECT_CALL(observer, Observe(chrome::NOTIFICATION_APP_TERMINATING, _, _));
policies.Set(key::kSessionLengthLimit, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
base::Value(kOneHourInMs), nullptr);
UpdateProviderPolicy(policies);
base::RunLoop().RunUntilIdle();
Mock::VerifyAndClearExpectations(&observer);
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
class NetworkTimePolicyTest : public PolicyTest {
public:
NetworkTimePolicyTest() {}
~NetworkTimePolicyTest() override {}
void SetUpOnMainThread() override {
std::map<std::string, std::string> parameters;
parameters["FetchBehavior"] = "on-demand-only";
scoped_feature_list_.InitAndEnableFeatureWithParameters(
network_time::kNetworkTimeServiceQuerying, parameters);
PolicyTest::SetUpOnMainThread();
}
// A request handler that returns a dummy response and counts the number of
// times it is called.
std::unique_ptr<net::test_server::HttpResponse> CountingRequestHandler(
const net::test_server::HttpRequest& request) {
net::test_server::BasicHttpResponse* response =
new net::test_server::BasicHttpResponse();
num_requests_++;
response->set_code(net::HTTP_OK);
response->set_content(
")]}'\n"
"{\"current_time_millis\":1461621971825,\"server_nonce\":-6."
"006853099049523E85}");
response->AddCustomHeader("x-cup-server-proof", "dead:beef");
return std::unique_ptr<net::test_server::HttpResponse>(response);
}
uint32_t num_requests() { return num_requests_; }
private:
base::test::ScopedFeatureList scoped_feature_list_;
uint32_t num_requests_ = 0;
DISALLOW_COPY_AND_ASSIGN(NetworkTimePolicyTest);
};
// TODO(https://crbug.com/1012853): This test is using ScopedFeatureList
// incorrectly, and fixing it causes conflicts with PolicyTest's use of the
// deprecated variations API.
IN_PROC_BROWSER_TEST_F(NetworkTimePolicyTest,
DISABLED_NetworkTimeQueriesDisabled) {
// Set a policy to disable network time queries.
PolicyMap policies;
policies.Set(key::kBrowserNetworkTimeQueriesEnabled, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(false),
nullptr);
UpdateProviderPolicy(policies);
embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
&NetworkTimePolicyTest::CountingRequestHandler, base::Unretained(this)));
ASSERT_TRUE(embedded_test_server()->Start());
g_browser_process->network_time_tracker()->SetTimeServerURLForTesting(
embedded_test_server()->GetURL("/"));
net::EmbeddedTestServer https_server_expired_(
net::EmbeddedTestServer::TYPE_HTTPS);
https_server_expired_.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
ASSERT_TRUE(https_server_expired_.Start());
// Navigate to a page with a certificate date error and then check that a
// network time query was not sent.
ui_test_utils::NavigateToURL(browser(), https_server_expired_.GetURL("/"));
content::WebContents* tab =
browser()->tab_strip_model()->GetActiveWebContents();
WaitForInterstitial(tab);
EXPECT_EQ(0u, num_requests());
// Now enable the policy and check that a network time query is sent.
policies.Set(key::kBrowserNetworkTimeQueriesEnabled, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(true),
nullptr);
UpdateProviderPolicy(policies);
ui_test_utils::NavigateToURL(browser(), https_server_expired_.GetURL("/"));
EXPECT_TRUE(IsShowingInterstitial(tab));
EXPECT_EQ(1u, num_requests());
}
#undef MAYBE_RunTest
} // namespace policy