OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <memory> | 5 #include <memory> |
6 | 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/files/dir_reader_posix.h" |
| 9 #include "base/files/file_path.h" |
7 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/memory/ref_counted.h" |
| 12 #include "base/path_service.h" |
| 13 #include "base/run_loop.h" |
| 14 #include "base/test/null_task_runner.h" |
8 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
9 #include "chrome/browser/browser_process_platform_part.h" | 16 #include "chrome/browser/browser_process_platform_part.h" |
10 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 17 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
11 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" | 18 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" |
| 19 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" |
| 20 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 21 #include "chrome/browser/extensions/extension_service.h" |
| 22 #include "chrome/browser/extensions/unpacked_installer.h" |
| 23 #include "chrome/browser/policy/test/local_policy_test_server.h" |
| 24 #include "chrome/browser/profiles/profile.h" |
| 25 #include "chrome/browser/ui/browser.h" |
| 26 #include "chrome/common/chrome_constants.cc" |
| 27 #include "chrome/common/chrome_paths.h" |
| 28 #include "chrome/common/chrome_switches.h" |
12 #include "chrome/test/base/in_process_browser_test.h" | 29 #include "chrome/test/base/in_process_browser_test.h" |
| 30 #include "chrome/test/base/ui_test_utils.h" |
| 31 #include "chromeos/chromeos_paths.h" |
| 32 #include "chromeos/chromeos_switches.h" |
| 33 #include "chromeos/dbus/fake_session_manager_client.h" |
13 #include "components/policy/core/common/cloud/cloud_policy_client.h" | 34 #include "components/policy/core/common/cloud/cloud_policy_client.h" |
| 35 #include "components/policy/core/common/cloud/device_management_service.h" |
14 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" | 36 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" |
| 37 #include "components/policy/core/common/cloud/policy_builder.h" |
| 38 #include "components/policy/core/common/cloud/resource_cache.h" |
| 39 #include "components/policy/core/common/policy_switches.h" |
| 40 #include "components/policy/proto/chrome_extension_policy.pb.h" |
| 41 #include "components/policy/proto/device_management_backend.pb.h" |
| 42 #include "crypto/rsa_private_key.h" |
| 43 #include "crypto/sha2.h" |
| 44 #include "extensions/browser/extension_registry.h" |
| 45 #include "extensions/browser/extension_system.h" |
| 46 #include "extensions/common/constants.h" |
| 47 #include "extensions/common/extension.h" |
| 48 #include "extensions/test/extension_test_notification_observer.h" |
| 49 #include "extensions/test/result_catcher.h" |
| 50 #include "net/http/http_status_code.h" |
| 51 #include "net/url_request/test_url_fetcher_factory.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 52 #include "testing/gtest/include/gtest/gtest.h" |
| 53 #include "url/gurl.h" |
16 | 54 |
17 namespace policy { | 55 namespace policy { |
18 | 56 |
19 class DeviceCloudPolicyBrowserTest : public InProcessBrowserTest { | 57 class DeviceCloudPolicyBrowserTest : public InProcessBrowserTest { |
20 public: | 58 public: |
21 DeviceCloudPolicyBrowserTest() : mock_client_(new MockCloudPolicyClient) { | 59 DeviceCloudPolicyBrowserTest() : mock_client_(new MockCloudPolicyClient) { |
22 } | 60 } |
23 | 61 |
24 MockCloudPolicyClient* mock_client_; | 62 MockCloudPolicyClient* mock_client_; |
25 }; | 63 }; |
26 | 64 |
27 IN_PROC_BROWSER_TEST_F(DeviceCloudPolicyBrowserTest, Initializer) { | 65 IN_PROC_BROWSER_TEST_F(DeviceCloudPolicyBrowserTest, Initializer) { |
28 BrowserPolicyConnectorChromeOS* connector = | 66 BrowserPolicyConnectorChromeOS* connector = |
29 g_browser_process->platform_part()->browser_policy_connector_chromeos(); | 67 g_browser_process->platform_part()->browser_policy_connector_chromeos(); |
30 // Initializer exists at first. | 68 // Initializer exists at first. |
31 EXPECT_TRUE(connector->GetDeviceCloudPolicyInitializer()); | 69 EXPECT_TRUE(connector->GetDeviceCloudPolicyInitializer()); |
32 | 70 |
33 // Initializer is deleted when the manager connects. | 71 // Initializer is deleted when the manager connects. |
34 connector->GetDeviceCloudPolicyManager()->StartConnection( | 72 connector->GetDeviceCloudPolicyManager()->StartConnection( |
35 base::WrapUnique(mock_client_), connector->GetInstallAttributes()); | 73 base::WrapUnique(mock_client_), connector->GetInstallAttributes()); |
36 EXPECT_FALSE(connector->GetDeviceCloudPolicyInitializer()); | 74 EXPECT_FALSE(connector->GetDeviceCloudPolicyInitializer()); |
37 | 75 |
38 // Initializer is restarted when the manager disconnects. | 76 // Initializer is restarted when the manager disconnects. |
39 connector->GetDeviceCloudPolicyManager()->Disconnect(); | 77 connector->GetDeviceCloudPolicyManager()->Disconnect(); |
40 EXPECT_TRUE(connector->GetDeviceCloudPolicyInitializer()); | 78 EXPECT_TRUE(connector->GetDeviceCloudPolicyInitializer()); |
41 } | 79 } |
42 | 80 |
| 81 // This class is the base class for the tests of the behavior regarding |
| 82 // extensions installed on the signin screen (which is generally possible only |
| 83 // through an admin policy, but the tests may install the extensions directly |
| 84 // for the test purposes). |
| 85 class SigninExtensionsDeviceCloudPolicyBrowserTestBase |
| 86 : public DevicePolicyCrosBrowserTest { |
| 87 protected: |
| 88 constexpr static const char* kTestExtensionId = |
| 89 "baogpbmpccplckhhehfipokjaflkmbno"; |
| 90 constexpr static const char* kTestExtensionSourceDir = |
| 91 "extensions/signin_screen_managed_storage"; |
| 92 constexpr static const char* kTestExtensionVersion = "1.0"; |
| 93 constexpr static const char* kTestExtensionTestPage = "test.html"; |
| 94 constexpr static const char* kFakePolicyUrl = |
| 95 "http://example.org/test-policy.json"; |
| 96 constexpr static const char* kFakePolicy = |
| 97 "{\"string-policy\": {\"Value\": \"value\"}}"; |
| 98 constexpr static const char* kPolicyProtoCacheKey = "signinextension-policy"; |
| 99 constexpr static const char* kPolicyDataCacheKey = |
| 100 "signinextension-policy-data"; |
| 101 |
| 102 SigninExtensionsDeviceCloudPolicyBrowserTestBase() {} |
| 103 |
| 104 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 105 DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line); |
| 106 command_line->AppendSwitch(chromeos::switches::kLoginManager); |
| 107 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); |
| 108 // This flag is required for the successful installation of the test |
| 109 // extension into the signin profile, due to some checks in |
| 110 // |ExtensionService|. |
| 111 command_line->AppendSwitchASCII(::switches::kDisableExtensionsExcept, |
| 112 GetTestExtensionSourcePath().value()); |
| 113 } |
| 114 |
| 115 void SetUpInProcessBrowserTestFixture() override { |
| 116 DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); |
| 117 InstallOwnerKey(); |
| 118 MarkAsEnterpriseOwned(); |
| 119 SetFakeDevicePolicy(); |
| 120 } |
| 121 |
| 122 void SetUpOnMainThread() override { |
| 123 DevicePolicyCrosBrowserTest::SetUpOnMainThread(); |
| 124 |
| 125 BrowserPolicyConnectorChromeOS* connector = |
| 126 g_browser_process->platform_part()->browser_policy_connector_chromeos(); |
| 127 connector->device_management_service()->ScheduleInitialization(0); |
| 128 |
| 129 ExtensionService* service = |
| 130 extensions::ExtensionSystem::Get(GetSigninProfile()) |
| 131 ->extension_service(); |
| 132 service->set_extensions_enabled(true); |
| 133 } |
| 134 |
| 135 static base::FilePath GetTestExtensionSourcePath() { |
| 136 base::FilePath test_data_dir; |
| 137 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); |
| 138 return test_data_dir.AppendASCII(kTestExtensionSourceDir); |
| 139 } |
| 140 |
| 141 static Profile* GetSigninProfile() { |
| 142 Profile* signin_profile = |
| 143 chromeos::ProfileHelper::GetSigninProfile()->GetOriginalProfile(); |
| 144 EXPECT_TRUE(signin_profile); |
| 145 return signin_profile; |
| 146 } |
| 147 |
| 148 static const extensions::Extension* GetTestExtension() { |
| 149 extensions::ExtensionRegistry* registry = |
| 150 extensions::ExtensionRegistry::Get(GetSigninProfile()); |
| 151 const extensions::Extension* extension = |
| 152 registry->enabled_extensions().GetByID(kTestExtensionId); |
| 153 EXPECT_TRUE(extension); |
| 154 return extension; |
| 155 } |
| 156 |
| 157 enterprise_management::PolicyFetchResponse BuildTestComponentPolicy() { |
| 158 ComponentPolicyBuilder builder; |
| 159 MakeTestComponentPolicyBuilder(&builder); |
| 160 return builder.policy(); |
| 161 } |
| 162 |
| 163 enterprise_management::ExternalPolicyData BuildTestComponentPolicyPayload() { |
| 164 ComponentPolicyBuilder builder; |
| 165 MakeTestComponentPolicyBuilder(&builder); |
| 166 return builder.payload(); |
| 167 } |
| 168 |
| 169 private: |
| 170 void SetFakeDevicePolicy() { |
| 171 device_policy()->policy_data().set_username(PolicyBuilder::kFakeUsername); |
| 172 device_policy()->SetDefaultSigningKey(); |
| 173 device_policy()->Build(); |
| 174 session_manager_client()->set_device_policy(device_policy()->GetBlob()); |
| 175 } |
| 176 |
| 177 void MakeTestComponentPolicyBuilder(ComponentPolicyBuilder* builder) { |
| 178 builder->policy_data().set_policy_type( |
| 179 dm_protocol::kChromeSigninExtensionPolicyType); |
| 180 builder->policy_data().set_username( |
| 181 device_policy()->policy_data().username()); |
| 182 builder->policy_data().set_settings_entity_id(kTestExtensionId); |
| 183 builder->policy_data().set_public_key_version(1); |
| 184 builder->payload().set_download_url(kFakePolicyUrl); |
| 185 builder->payload().set_secure_hash(crypto::SHA256HashString(kFakePolicy)); |
| 186 builder->SetDefaultSigningKey(); |
| 187 builder->Build(); |
| 188 } |
| 189 |
| 190 DISALLOW_COPY_AND_ASSIGN(SigninExtensionsDeviceCloudPolicyBrowserTestBase); |
| 191 }; |
| 192 |
| 193 // This class tests whether the component policy is successfully processed and |
| 194 // passed to the extension that is installed into the signin profile after the |
| 195 // initialization finishes. |
| 196 // |
| 197 // The fake component policy is injected by using the local policy test server. |
| 198 // The test extension is installed into the profile manually by the test code |
| 199 // (i.e. this class doesn't test the installation of the signin screen |
| 200 // extensions through the admin policy). |
| 201 class SigninExtensionsDeviceCloudPolicyBrowserTest |
| 202 : public SigninExtensionsDeviceCloudPolicyBrowserTestBase { |
| 203 protected: |
| 204 SigninExtensionsDeviceCloudPolicyBrowserTest() |
| 205 : fetcher_factory_(&fetcher_impl_factory_) {} |
| 206 |
| 207 const extensions::Extension* InstallAndLoadTestExtension() const { |
| 208 Profile* signin_profile = GetSigninProfile(); |
| 209 ExtensionService* service = |
| 210 extensions::ExtensionSystem::Get(signin_profile)->extension_service(); |
| 211 scoped_refptr<extensions::UnpackedInstaller> installer( |
| 212 extensions::UnpackedInstaller::Create(service)); |
| 213 ExtensionTestNotificationObserver observer(signin_profile); |
| 214 installer->Load(GetTestExtensionSourcePath()); |
| 215 observer.WaitForExtensionLoad(); |
| 216 return GetTestExtension(); |
| 217 } |
| 218 |
| 219 private: |
| 220 void SetUp() override { |
| 221 StartPolicyTestServer(); |
| 222 DevicePolicyCrosBrowserTest::SetUp(); |
| 223 } |
| 224 |
| 225 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 226 SigninExtensionsDeviceCloudPolicyBrowserTestBase::SetUpCommandLine( |
| 227 command_line); |
| 228 command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, |
| 229 policy_test_server_.GetServiceURL().spec()); |
| 230 } |
| 231 |
| 232 void SetUpInProcessBrowserTestFixture() override { |
| 233 SigninExtensionsDeviceCloudPolicyBrowserTestBase:: |
| 234 SetUpInProcessBrowserTestFixture(); |
| 235 EXPECT_TRUE(PathService::Get(chromeos::DIR_SIGNIN_PROFILE_COMPONENT_POLICY, |
| 236 &component_policy_cache_dir_)); |
| 237 PrepareFakeComponentPolicyResponse(); |
| 238 } |
| 239 |
| 240 void TearDownInProcessBrowserTestFixture() override { |
| 241 // Check that the component policy cache was not cleared during browser |
| 242 // teardown. |
| 243 ResourceCache cache(component_policy_cache_dir_, new base::NullTaskRunner); |
| 244 std::string stub; |
| 245 EXPECT_TRUE(cache.Load(kPolicyProtoCacheKey, kTestExtensionId, &stub)); |
| 246 EXPECT_TRUE(cache.Load(kPolicyDataCacheKey, kTestExtensionId, &stub)); |
| 247 |
| 248 SigninExtensionsDeviceCloudPolicyBrowserTestBase:: |
| 249 TearDownInProcessBrowserTestFixture(); |
| 250 } |
| 251 |
| 252 void StartPolicyTestServer() { |
| 253 std::unique_ptr<crypto::RSAPrivateKey> signing_key( |
| 254 PolicyBuilder::CreateTestSigningKey()); |
| 255 EXPECT_TRUE(policy_test_server_.SetSigningKeyAndSignature( |
| 256 signing_key.get(), PolicyBuilder::GetTestSigningKeySignature())); |
| 257 policy_test_server_.RegisterClient(PolicyBuilder::kFakeToken, |
| 258 PolicyBuilder::kFakeDeviceId); |
| 259 EXPECT_TRUE(policy_test_server_.Start()); |
| 260 } |
| 261 |
| 262 void PrepareFakeComponentPolicyResponse() { |
| 263 EXPECT_TRUE(policy_test_server_.UpdatePolicy( |
| 264 dm_protocol::kChromeSigninExtensionPolicyType, kTestExtensionId, |
| 265 BuildTestComponentPolicyPayload().SerializeAsString())); |
| 266 fetcher_factory_.SetFakeResponse(GURL(kFakePolicyUrl), kFakePolicy, |
| 267 net::HTTP_OK, |
| 268 net::URLRequestStatus::SUCCESS); |
| 269 } |
| 270 |
| 271 LocalPolicyTestServer policy_test_server_; |
| 272 net::URLFetcherImplFactory fetcher_impl_factory_; |
| 273 net::FakeURLFetcherFactory fetcher_factory_; |
| 274 base::FilePath component_policy_cache_dir_; |
| 275 }; |
| 276 |
| 277 IN_PROC_BROWSER_TEST_F(SigninExtensionsDeviceCloudPolicyBrowserTest, |
| 278 InstallAndRunInWindow) { |
| 279 const extensions::Extension* extension = InstallAndLoadTestExtension(); |
| 280 ASSERT_TRUE(extension); |
| 281 Browser* browser = CreateBrowser(GetSigninProfile()); |
| 282 extensions::ResultCatcher result_catcher; |
| 283 ui_test_utils::NavigateToURL( |
| 284 browser, extension->GetResourceURL(kTestExtensionTestPage)); |
| 285 EXPECT_TRUE(result_catcher.GetNextResult()); |
| 286 CloseBrowserSynchronously(browser); |
| 287 } |
| 288 |
| 289 // This class tests that the cached component policy is successfully loaded and |
| 290 // passed to the extension that is already installed into the signin profile. |
| 291 // |
| 292 // To accomplish this, the class prefills the signin profile with, first, the |
| 293 // installed test extension, and, second, with the cached component policy. |
| 294 class PreinstalledSigninExtensionsDeviceCloudPolicyBrowserTest |
| 295 : public SigninExtensionsDeviceCloudPolicyBrowserTestBase { |
| 296 protected: |
| 297 constexpr static const char* kFakeProfileSourceDir = |
| 298 "extensions/profiles/signin_screen_managed_storage"; |
| 299 |
| 300 private: |
| 301 bool SetUpUserDataDirectory() override { |
| 302 PrefillSigninProfile(); |
| 303 PrefillComponentPolicyCache(); |
| 304 return DevicePolicyCrosBrowserTest::SetUpUserDataDirectory(); |
| 305 } |
| 306 |
| 307 static void PrefillSigninProfile() { |
| 308 base::FilePath profile_source_path; |
| 309 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &profile_source_path)); |
| 310 profile_source_path = profile_source_path.AppendASCII(kFakeProfileSourceDir) |
| 311 .AppendASCII(chrome::kInitialProfile); |
| 312 |
| 313 base::FilePath profile_target_path; |
| 314 EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &profile_target_path)); |
| 315 |
| 316 EXPECT_TRUE( |
| 317 base::CopyDirectory(profile_source_path, profile_target_path, true)); |
| 318 |
| 319 base::FilePath extension_target_path = |
| 320 profile_target_path.AppendASCII(chrome::kInitialProfile) |
| 321 .AppendASCII(extensions::kInstallDirectoryName) |
| 322 .AppendASCII(kTestExtensionId) |
| 323 .AppendASCII(kTestExtensionVersion); |
| 324 EXPECT_TRUE(base::CopyDirectory(GetTestExtensionSourcePath(), |
| 325 extension_target_path, true)); |
| 326 } |
| 327 |
| 328 void PrefillComponentPolicyCache() { |
| 329 base::FilePath user_data_dir; |
| 330 EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); |
| 331 chromeos::RegisterStubPathOverrides(user_data_dir); |
| 332 |
| 333 base::FilePath cache_dir; |
| 334 EXPECT_TRUE(PathService::Get(chromeos::DIR_SIGNIN_PROFILE_COMPONENT_POLICY, |
| 335 &cache_dir)); |
| 336 |
| 337 ResourceCache cache(cache_dir, new base::NullTaskRunner); |
| 338 EXPECT_TRUE(cache.Store(kPolicyProtoCacheKey, kTestExtensionId, |
| 339 BuildTestComponentPolicy().SerializeAsString())); |
| 340 EXPECT_TRUE( |
| 341 cache.Store(kPolicyDataCacheKey, kTestExtensionId, kFakePolicy)); |
| 342 } |
| 343 }; |
| 344 |
| 345 IN_PROC_BROWSER_TEST_F(PreinstalledSigninExtensionsDeviceCloudPolicyBrowserTest, |
| 346 OfflineStart) { |
| 347 const extensions::Extension* extension = GetTestExtension(); |
| 348 ASSERT_TRUE(extension); |
| 349 Browser* browser = CreateBrowser(GetSigninProfile()); |
| 350 extensions::ResultCatcher result_catcher; |
| 351 ui_test_utils::NavigateToURL( |
| 352 browser, extension->GetResourceURL(kTestExtensionTestPage)); |
| 353 EXPECT_TRUE(result_catcher.GetNextResult()); |
| 354 CloseBrowserSynchronously(browser); |
| 355 } |
| 356 |
43 } // namespace policy | 357 } // namespace policy |
OLD | NEW |