Index: chrome/browser/chromeos/policy/device_cloud_policy_browsertest.cc |
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_browsertest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_browsertest.cc |
index d7b0316f350404847b4b569e0e189615216fd3e4..e3b6edeffc7d9cd123008a10a9af4b59f7d68391 100644 |
--- a/chrome/browser/chromeos/policy/device_cloud_policy_browsertest.cc |
+++ b/chrome/browser/chromeos/policy/device_cloud_policy_browsertest.cc |
@@ -4,15 +4,53 @@ |
#include <memory> |
+#include "base/command_line.h" |
+#include "base/files/dir_reader_posix.h" |
+#include "base/files/file_path.h" |
#include "base/memory/ptr_util.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/path_service.h" |
+#include "base/run_loop.h" |
+#include "base/test/null_task_runner.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/browser_process_platform_part.h" |
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" |
+#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" |
+#include "chrome/browser/chromeos/profiles/profile_helper.h" |
+#include "chrome/browser/extensions/extension_service.h" |
+#include "chrome/browser/extensions/unpacked_installer.h" |
+#include "chrome/browser/policy/test/local_policy_test_server.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/ui/browser.h" |
+#include "chrome/common/chrome_constants.cc" |
+#include "chrome/common/chrome_paths.h" |
+#include "chrome/common/chrome_switches.h" |
#include "chrome/test/base/in_process_browser_test.h" |
+#include "chrome/test/base/ui_test_utils.h" |
+#include "chromeos/chromeos_paths.h" |
+#include "chromeos/chromeos_switches.h" |
+#include "chromeos/dbus/fake_session_manager_client.h" |
#include "components/policy/core/common/cloud/cloud_policy_client.h" |
+#include "components/policy/core/common/cloud/device_management_service.h" |
#include "components/policy/core/common/cloud/mock_cloud_policy_client.h" |
+#include "components/policy/core/common/cloud/policy_builder.h" |
+#include "components/policy/core/common/cloud/resource_cache.h" |
+#include "components/policy/core/common/policy_switches.h" |
+#include "components/policy/proto/chrome_extension_policy.pb.h" |
+#include "components/policy/proto/device_management_backend.pb.h" |
+#include "crypto/rsa_private_key.h" |
+#include "crypto/sha2.h" |
+#include "extensions/browser/extension_registry.h" |
+#include "extensions/browser/extension_system.h" |
+#include "extensions/common/constants.h" |
+#include "extensions/common/extension.h" |
+#include "extensions/test/extension_test_notification_observer.h" |
+#include "extensions/test/result_catcher.h" |
+#include "net/http/http_status_code.h" |
+#include "net/url_request/test_url_fetcher_factory.h" |
#include "testing/gtest/include/gtest/gtest.h" |
+#include "url/gurl.h" |
namespace policy { |
@@ -40,4 +78,280 @@ IN_PROC_BROWSER_TEST_F(DeviceCloudPolicyBrowserTest, Initializer) { |
EXPECT_TRUE(connector->GetDeviceCloudPolicyInitializer()); |
} |
+// This class is the base class for the tests of the behavior regarding |
+// extensions installed on the signin screen (which is generally possible only |
+// through an admin policy, but the tests may install the extensions directly |
+// for the test purposes). |
+class SigninExtensionsDeviceCloudPolicyBrowserTestBase |
+ : public DevicePolicyCrosBrowserTest { |
+ protected: |
+ constexpr static const char* kTestExtensionId = |
+ "baogpbmpccplckhhehfipokjaflkmbno"; |
+ constexpr static const char* kTestExtensionSourceDir = |
+ "extensions/signin_screen_managed_storage"; |
+ constexpr static const char* kTestExtensionVersion = "1.0"; |
+ constexpr static const char* kTestExtensionTestPage = "test.html"; |
+ constexpr static const char* kFakePolicyUrl = |
+ "http://example.org/test-policy.json"; |
+ constexpr static const char* kFakePolicy = |
+ "{\"string-policy\": {\"Value\": \"value\"}}"; |
+ constexpr static const char* kPolicyProtoCacheKey = "signinextension-policy"; |
+ constexpr static const char* kPolicyDataCacheKey = |
+ "signinextension-policy-data"; |
+ |
+ SigninExtensionsDeviceCloudPolicyBrowserTestBase() {} |
+ |
+ void SetUpCommandLine(base::CommandLine* command_line) override { |
+ DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line); |
+ command_line->AppendSwitch(chromeos::switches::kLoginManager); |
+ command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); |
+ // This flag is required for the successful installation of the test |
+ // extension into the signin profile, due to some checks in |
+ // |ExtensionService|. |
+ command_line->AppendSwitchASCII(::switches::kDisableExtensionsExcept, |
+ GetTestExtensionSourcePath().value()); |
+ } |
+ |
+ void SetUpInProcessBrowserTestFixture() override { |
+ DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); |
+ InstallOwnerKey(); |
+ MarkAsEnterpriseOwned(); |
+ SetFakeDevicePolicy(); |
+ } |
+ |
+ void SetUpOnMainThread() override { |
+ DevicePolicyCrosBrowserTest::SetUpOnMainThread(); |
+ |
+ BrowserPolicyConnectorChromeOS* connector = |
+ g_browser_process->platform_part()->browser_policy_connector_chromeos(); |
+ connector->device_management_service()->ScheduleInitialization(0); |
+ |
+ ExtensionService* service = |
+ extensions::ExtensionSystem::Get(GetSigninProfile()) |
+ ->extension_service(); |
+ service->set_extensions_enabled(true); |
+ } |
+ |
+ static base::FilePath GetTestExtensionSourcePath() { |
+ base::FilePath test_data_dir; |
+ EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); |
+ return test_data_dir.AppendASCII(kTestExtensionSourceDir); |
+ } |
+ |
+ static Profile* GetSigninProfile() { |
+ Profile* signin_profile = |
+ chromeos::ProfileHelper::GetSigninProfile()->GetOriginalProfile(); |
+ EXPECT_TRUE(signin_profile); |
+ return signin_profile; |
+ } |
+ |
+ static const extensions::Extension* GetTestExtension() { |
+ extensions::ExtensionRegistry* registry = |
+ extensions::ExtensionRegistry::Get(GetSigninProfile()); |
+ const extensions::Extension* extension = |
+ registry->enabled_extensions().GetByID(kTestExtensionId); |
+ EXPECT_TRUE(extension); |
+ return extension; |
+ } |
+ |
+ enterprise_management::PolicyFetchResponse BuildTestComponentPolicy() { |
+ ComponentPolicyBuilder builder; |
+ MakeTestComponentPolicyBuilder(&builder); |
+ return builder.policy(); |
+ } |
+ |
+ enterprise_management::ExternalPolicyData BuildTestComponentPolicyPayload() { |
+ ComponentPolicyBuilder builder; |
+ MakeTestComponentPolicyBuilder(&builder); |
+ return builder.payload(); |
+ } |
+ |
+ private: |
+ void SetFakeDevicePolicy() { |
+ device_policy()->policy_data().set_username(PolicyBuilder::kFakeUsername); |
+ device_policy()->SetDefaultSigningKey(); |
+ device_policy()->Build(); |
+ session_manager_client()->set_device_policy(device_policy()->GetBlob()); |
+ } |
+ |
+ void MakeTestComponentPolicyBuilder(ComponentPolicyBuilder* builder) { |
+ builder->policy_data().set_policy_type( |
+ dm_protocol::kChromeSigninExtensionPolicyType); |
+ builder->policy_data().set_username( |
+ device_policy()->policy_data().username()); |
+ builder->policy_data().set_settings_entity_id(kTestExtensionId); |
+ builder->policy_data().set_public_key_version(1); |
+ builder->payload().set_download_url(kFakePolicyUrl); |
+ builder->payload().set_secure_hash(crypto::SHA256HashString(kFakePolicy)); |
+ builder->SetDefaultSigningKey(); |
+ builder->Build(); |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SigninExtensionsDeviceCloudPolicyBrowserTestBase); |
+}; |
+ |
+// This class tests whether the component policy is successfully processed and |
+// passed to the extension that is installed into the signin profile after the |
+// initialization finishes. |
+// |
+// The fake component policy is injected by using the local policy test server. |
+// The test extension is installed into the profile manually by the test code |
+// (i.e. this class doesn't test the installation of the signin screen |
+// extensions through the admin policy). |
+class SigninExtensionsDeviceCloudPolicyBrowserTest |
+ : public SigninExtensionsDeviceCloudPolicyBrowserTestBase { |
+ protected: |
+ SigninExtensionsDeviceCloudPolicyBrowserTest() |
+ : fetcher_factory_(&fetcher_impl_factory_) {} |
+ |
+ const extensions::Extension* InstallAndLoadTestExtension() const { |
+ Profile* signin_profile = GetSigninProfile(); |
+ ExtensionService* service = |
+ extensions::ExtensionSystem::Get(signin_profile)->extension_service(); |
+ scoped_refptr<extensions::UnpackedInstaller> installer( |
+ extensions::UnpackedInstaller::Create(service)); |
+ ExtensionTestNotificationObserver observer(signin_profile); |
+ installer->Load(GetTestExtensionSourcePath()); |
+ observer.WaitForExtensionLoad(); |
+ return GetTestExtension(); |
+ } |
+ |
+ private: |
+ void SetUp() override { |
+ StartPolicyTestServer(); |
+ DevicePolicyCrosBrowserTest::SetUp(); |
+ } |
+ |
+ void SetUpCommandLine(base::CommandLine* command_line) override { |
+ SigninExtensionsDeviceCloudPolicyBrowserTestBase::SetUpCommandLine( |
+ command_line); |
+ command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, |
+ policy_test_server_.GetServiceURL().spec()); |
+ } |
+ |
+ void SetUpInProcessBrowserTestFixture() override { |
+ SigninExtensionsDeviceCloudPolicyBrowserTestBase:: |
+ SetUpInProcessBrowserTestFixture(); |
+ EXPECT_TRUE(PathService::Get(chromeos::DIR_SIGNIN_PROFILE_COMPONENT_POLICY, |
+ &component_policy_cache_dir_)); |
+ PrepareFakeComponentPolicyResponse(); |
+ } |
+ |
+ void TearDownInProcessBrowserTestFixture() override { |
+ // Check that the component policy cache was not cleared during browser |
+ // teardown. |
+ ResourceCache cache(component_policy_cache_dir_, new base::NullTaskRunner); |
+ std::string stub; |
+ EXPECT_TRUE(cache.Load(kPolicyProtoCacheKey, kTestExtensionId, &stub)); |
+ EXPECT_TRUE(cache.Load(kPolicyDataCacheKey, kTestExtensionId, &stub)); |
+ |
+ SigninExtensionsDeviceCloudPolicyBrowserTestBase:: |
+ TearDownInProcessBrowserTestFixture(); |
+ } |
+ |
+ void StartPolicyTestServer() { |
+ std::unique_ptr<crypto::RSAPrivateKey> signing_key( |
+ PolicyBuilder::CreateTestSigningKey()); |
+ EXPECT_TRUE(policy_test_server_.SetSigningKeyAndSignature( |
+ signing_key.get(), PolicyBuilder::GetTestSigningKeySignature())); |
+ policy_test_server_.RegisterClient(PolicyBuilder::kFakeToken, |
+ PolicyBuilder::kFakeDeviceId); |
+ EXPECT_TRUE(policy_test_server_.Start()); |
+ } |
+ |
+ void PrepareFakeComponentPolicyResponse() { |
+ EXPECT_TRUE(policy_test_server_.UpdatePolicy( |
+ dm_protocol::kChromeSigninExtensionPolicyType, kTestExtensionId, |
+ BuildTestComponentPolicyPayload().SerializeAsString())); |
+ fetcher_factory_.SetFakeResponse(GURL(kFakePolicyUrl), kFakePolicy, |
+ net::HTTP_OK, |
+ net::URLRequestStatus::SUCCESS); |
+ } |
+ |
+ LocalPolicyTestServer policy_test_server_; |
+ net::URLFetcherImplFactory fetcher_impl_factory_; |
+ net::FakeURLFetcherFactory fetcher_factory_; |
+ base::FilePath component_policy_cache_dir_; |
+}; |
+ |
+IN_PROC_BROWSER_TEST_F(SigninExtensionsDeviceCloudPolicyBrowserTest, |
+ InstallAndRunInWindow) { |
+ const extensions::Extension* extension = InstallAndLoadTestExtension(); |
+ ASSERT_TRUE(extension); |
+ Browser* browser = CreateBrowser(GetSigninProfile()); |
+ extensions::ResultCatcher result_catcher; |
+ ui_test_utils::NavigateToURL( |
+ browser, extension->GetResourceURL(kTestExtensionTestPage)); |
+ EXPECT_TRUE(result_catcher.GetNextResult()); |
+ CloseBrowserSynchronously(browser); |
+} |
+ |
+// This class tests that the cached component policy is successfully loaded and |
+// passed to the extension that is already installed into the signin profile. |
+// |
+// To accomplish this, the class prefills the signin profile with, first, the |
+// installed test extension, and, second, with the cached component policy. |
+class PreinstalledSigninExtensionsDeviceCloudPolicyBrowserTest |
+ : public SigninExtensionsDeviceCloudPolicyBrowserTestBase { |
+ protected: |
+ constexpr static const char* kFakeProfileSourceDir = |
+ "extensions/profiles/signin_screen_managed_storage"; |
+ |
+ private: |
+ bool SetUpUserDataDirectory() override { |
+ PrefillSigninProfile(); |
+ PrefillComponentPolicyCache(); |
+ return DevicePolicyCrosBrowserTest::SetUpUserDataDirectory(); |
+ } |
+ |
+ static void PrefillSigninProfile() { |
+ base::FilePath profile_source_path; |
+ EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &profile_source_path)); |
+ profile_source_path = profile_source_path.AppendASCII(kFakeProfileSourceDir) |
+ .AppendASCII(chrome::kInitialProfile); |
+ |
+ base::FilePath profile_target_path; |
+ EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &profile_target_path)); |
+ |
+ EXPECT_TRUE( |
+ base::CopyDirectory(profile_source_path, profile_target_path, true)); |
+ |
+ base::FilePath extension_target_path = |
+ profile_target_path.AppendASCII(chrome::kInitialProfile) |
+ .AppendASCII(extensions::kInstallDirectoryName) |
+ .AppendASCII(kTestExtensionId) |
+ .AppendASCII(kTestExtensionVersion); |
+ EXPECT_TRUE(base::CopyDirectory(GetTestExtensionSourcePath(), |
+ extension_target_path, true)); |
+ } |
+ |
+ void PrefillComponentPolicyCache() { |
+ base::FilePath user_data_dir; |
+ EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); |
+ chromeos::RegisterStubPathOverrides(user_data_dir); |
+ |
+ base::FilePath cache_dir; |
+ EXPECT_TRUE(PathService::Get(chromeos::DIR_SIGNIN_PROFILE_COMPONENT_POLICY, |
+ &cache_dir)); |
+ |
+ ResourceCache cache(cache_dir, new base::NullTaskRunner); |
+ EXPECT_TRUE(cache.Store(kPolicyProtoCacheKey, kTestExtensionId, |
+ BuildTestComponentPolicy().SerializeAsString())); |
+ EXPECT_TRUE( |
+ cache.Store(kPolicyDataCacheKey, kTestExtensionId, kFakePolicy)); |
+ } |
+}; |
+ |
+IN_PROC_BROWSER_TEST_F(PreinstalledSigninExtensionsDeviceCloudPolicyBrowserTest, |
+ OfflineStart) { |
+ const extensions::Extension* extension = GetTestExtension(); |
+ ASSERT_TRUE(extension); |
+ Browser* browser = CreateBrowser(GetSigninProfile()); |
+ extensions::ResultCatcher result_catcher; |
+ ui_test_utils::NavigateToURL( |
+ browser, extension->GetResourceURL(kTestExtensionTestPage)); |
+ EXPECT_TRUE(result_catcher.GetNextResult()); |
+ CloseBrowserSynchronously(browser); |
+} |
+ |
} // namespace policy |