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 command_line->AppendSwitchASCII(::switches::kDisableExtensionsExcept, | |
Andrew T Wilson (Slow)
2016/10/28 14:49:56
Why is this required? Maybe add a comment here?
emaxx
2016/10/31 15:51:19
I'll add a comment that without this switch the te
| |
109 GetTestExtensionSourcePath().value()); | |
110 } | |
111 | |
112 void SetUpInProcessBrowserTestFixture() override { | |
113 DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); | |
114 InstallOwnerKey(); | |
115 MarkAsEnterpriseOwned(); | |
116 SetFakeDevicePolicy(); | |
117 } | |
118 | |
119 void SetUpOnMainThread() override { | |
120 DevicePolicyCrosBrowserTest::SetUpOnMainThread(); | |
121 | |
122 BrowserPolicyConnectorChromeOS* connector = | |
123 g_browser_process->platform_part()->browser_policy_connector_chromeos(); | |
124 connector->device_management_service()->ScheduleInitialization(0); | |
125 | |
126 ExtensionService* service = | |
127 extensions::ExtensionSystem::Get(GetSigninProfile()) | |
128 ->extension_service(); | |
129 service->set_extensions_enabled(true); // TODO(emaxx): Replace this with | |
130 // enabling a special command line | |
131 // switch once it's added (see | |
132 // crbug.com/576464). | |
Andrew T Wilson (Slow)
2016/10/28 14:49:56
This bug doesn't talk about a command line switch.
emaxx
2016/10/31 15:51:19
Good catch, that's true. I'll remove this TODO.
T
| |
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 StartPolicyTestService(); | |
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 StartPolicyTestService() { | |
emaxx
2016/10/31 15:51:19
nit (for myself): s/Service/Server/.
| |
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 |