Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / policy / cloud / component_cloud_policy_browsertest.cc
blobdfccc44ecbf4bb041cd2a667e4f5b84ed1380e5c
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <string>
7 #include "base/base64.h"
8 #include "base/command_line.h"
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/path_service.h"
13 #include "base/run_loop.h"
14 #include "base/strings/string_util.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/extensions/extension_browsertest.h"
17 #include "chrome/browser/extensions/extension_test_message_listener.h"
18 #include "chrome/browser/policy/browser_policy_connector.h"
19 #include "chrome/browser/policy/profile_policy_connector.h"
20 #include "chrome/browser/policy/profile_policy_connector_factory.h"
21 #include "chrome/browser/policy/test/local_policy_test_server.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
27 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
28 #include "components/policy/core/common/policy_service.h"
29 #include "components/policy/core/common/policy_switches.h"
30 #include "components/policy/core/common/policy_test_utils.h"
31 #include "extensions/common/extension.h"
32 #include "net/url_request/url_request_context_getter.h"
33 #include "policy/proto/chrome_extension_policy.pb.h"
34 #include "policy/proto/cloud_policy.pb.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
38 #if defined(OS_CHROMEOS)
39 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
40 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
41 #include "chromeos/chromeos_switches.h"
42 #else
43 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
44 #include "chrome/browser/signin/signin_manager.h"
45 #include "chrome/browser/signin/signin_manager_factory.h"
46 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
47 #endif
49 using testing::InvokeWithoutArgs;
50 using testing::Mock;
51 using testing::Return;
52 using testing::_;
54 namespace em = enterprise_management;
56 namespace policy {
58 const char kDMToken[] = "dmtoken";
59 const char kDeviceID[] = "deviceid";
61 const char kTestExtension[] = "kjmkgkdkpedkejedfhmfcenooemhbpbo";
63 const base::FilePath::CharType kTestExtensionPath[] =
64 FILE_PATH_LITERAL("extensions/managed_extension");
66 const char kTestPolicy[] =
67 "{"
68 " \"Name\": {"
69 " \"Value\": \"disable_all_the_things\""
70 " }"
71 "}";
73 const char kTestExtension2[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
74 const base::FilePath::CharType kTestExtension2Path[] =
75 FILE_PATH_LITERAL("extensions/managed_extension2");
77 const char kTestPolicyJSON[] = "{\"Name\":\"disable_all_the_things\"}";
79 const char kTestPolicy2[] =
80 "{"
81 " \"Another\": {"
82 " \"Value\": \"turn_it_off\""
83 " }"
84 "}";
86 const char kTestPolicy2JSON[] = "{\"Another\":\"turn_it_off\"}";
88 // Same encoding as ResourceCache does for its keys.
89 bool Base64Encode(const std::string& value, std::string* encoded) {
90 if (value.empty())
91 return false;
92 base::Base64Encode(value, encoded);
93 base::ReplaceChars(*encoded, "+", "-", encoded);
94 base::ReplaceChars(*encoded, "/", "_", encoded);
95 return true;
98 class ComponentCloudPolicyTest : public ExtensionBrowserTest {
99 protected:
100 ComponentCloudPolicyTest() {}
101 virtual ~ComponentCloudPolicyTest() {}
103 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
104 ExtensionBrowserTest::SetUpCommandLine(command_line);
105 #if defined(OS_CHROMEOS)
106 // ExtensionBrowserTest sets the login users to a non-managed value;
107 // replace it. This is the default username sent in policy blobs from the
108 // testserver.
109 command_line->AppendSwitchASCII(
110 ::chromeos::switches::kLoginUser, "user@example.com");
111 #endif
114 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
115 test_server_.RegisterClient(kDMToken, kDeviceID);
116 EXPECT_TRUE(test_server_.UpdatePolicyData(
117 dm_protocol::kChromeExtensionPolicyType, kTestExtension, kTestPolicy));
118 ASSERT_TRUE(test_server_.Start());
120 std::string url = test_server_.GetServiceURL().spec();
121 CommandLine* command_line = CommandLine::ForCurrentProcess();
122 command_line->AppendSwitchASCII(::switches::kDeviceManagementUrl, url);
123 command_line->AppendSwitch(switches::kEnableComponentCloudPolicy);
125 ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
128 virtual void SetUpOnMainThread() OVERRIDE {
129 ASSERT_TRUE(PolicyServiceIsEmpty(g_browser_process->policy_service()))
130 << "Pre-existing policies in this machine will make this test fail.";
132 // Install the initial extension.
133 ExtensionTestMessageListener ready_listener("ready", true);
134 event_listener_.reset(new ExtensionTestMessageListener("event", true));
135 extension_ = LoadExtension(kTestExtensionPath);
136 ASSERT_TRUE(extension_.get());
137 ASSERT_EQ(kTestExtension, extension_->id());
138 EXPECT_TRUE(ready_listener.WaitUntilSatisfied());
140 // And start with a signed-in user.
141 SignInAndRegister();
143 // The extension will receive an update event.
144 EXPECT_TRUE(event_listener_->WaitUntilSatisfied());
146 ExtensionBrowserTest::SetUpOnMainThread();
149 scoped_refptr<const extensions::Extension> LoadExtension(
150 const base::FilePath::CharType* path) {
151 base::FilePath full_path;
152 if (!PathService::Get(chrome::DIR_TEST_DATA, &full_path)) {
153 ADD_FAILURE();
154 return NULL;
156 scoped_refptr<const extensions::Extension> extension(
157 ExtensionBrowserTest::LoadExtension(full_path.Append(path)));
158 if (!extension.get()) {
159 ADD_FAILURE();
160 return NULL;
162 return extension;
165 void SignInAndRegister() {
166 BrowserPolicyConnector* connector =
167 g_browser_process->browser_policy_connector();
168 connector->ScheduleServiceInitialization(0);
170 #if defined(OS_CHROMEOS)
171 UserCloudPolicyManagerChromeOS* policy_manager =
172 UserCloudPolicyManagerFactoryChromeOS::GetForProfile(
173 browser()->profile());
174 ASSERT_TRUE(policy_manager);
175 #else
176 // Mock a signed-in user. This is used by the UserCloudPolicyStore to pass
177 // the username to the UserCloudPolicyValidator.
178 SigninManager* signin_manager =
179 SigninManagerFactory::GetForProfile(browser()->profile());
180 ASSERT_TRUE(signin_manager);
181 signin_manager->SetAuthenticatedUsername("user@example.com");
183 UserCloudPolicyManager* policy_manager =
184 UserCloudPolicyManagerFactory::GetForBrowserContext(
185 browser()->profile());
186 ASSERT_TRUE(policy_manager);
187 policy_manager->Connect(
188 g_browser_process->local_state(),
189 g_browser_process->system_request_context(),
190 UserCloudPolicyManager::CreateCloudPolicyClient(
191 connector->device_management_service(),
192 g_browser_process->system_request_context()).Pass());
193 #endif // defined(OS_CHROMEOS)
195 // Register the cloud policy client.
196 ASSERT_TRUE(policy_manager->core()->client());
197 base::RunLoop run_loop;
198 MockCloudPolicyClientObserver observer;
199 EXPECT_CALL(observer, OnRegistrationStateChanged(_))
200 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
201 policy_manager->core()->client()->AddObserver(&observer);
202 policy_manager->core()->client()->SetupRegistration(kDMToken, kDeviceID);
203 run_loop.Run();
204 Mock::VerifyAndClearExpectations(&observer);
205 policy_manager->core()->client()->RemoveObserver(&observer);
208 #if !defined(OS_CHROMEOS)
209 void SignOut() {
210 SigninManager* signin_manager =
211 SigninManagerFactory::GetForProfile(browser()->profile());
212 ASSERT_TRUE(signin_manager);
213 signin_manager->SignOut();
215 #endif
217 void RefreshPolicies() {
218 ProfilePolicyConnector* profile_connector =
219 ProfilePolicyConnectorFactory::GetForProfile(browser()->profile());
220 PolicyService* policy_service = profile_connector->policy_service();
221 base::RunLoop run_loop;
222 policy_service->RefreshPolicies(run_loop.QuitClosure());
223 run_loop.Run();
226 LocalPolicyTestServer test_server_;
227 scoped_refptr<const extensions::Extension> extension_;
228 scoped_ptr<ExtensionTestMessageListener> event_listener_;
231 IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, FetchExtensionPolicy) {
232 // Read the initial policy.
233 ExtensionTestMessageListener policy_listener(kTestPolicyJSON, true);
234 event_listener_->Reply("get-policy-Name");
235 EXPECT_TRUE(policy_listener.WaitUntilSatisfied());
238 IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, UpdateExtensionPolicy) {
239 // Read the initial policy.
240 ExtensionTestMessageListener policy_listener(kTestPolicyJSON, true);
241 event_listener_->Reply("get-policy-Name");
242 EXPECT_TRUE(policy_listener.WaitUntilSatisfied());
244 // Update the policy at the server and reload policy.
245 event_listener_.reset(new ExtensionTestMessageListener("event", true));
246 policy_listener.Reply("idle");
247 EXPECT_TRUE(test_server_.UpdatePolicyData(
248 dm_protocol::kChromeExtensionPolicyType, kTestExtension, kTestPolicy2));
249 RefreshPolicies();
251 // Check that the update event was received, and verify the new policy
252 // values.
253 EXPECT_TRUE(event_listener_->WaitUntilSatisfied());
255 // This policy was removed.
256 ExtensionTestMessageListener policy_listener1("{}", true);
257 event_listener_->Reply("get-policy-Name");
258 EXPECT_TRUE(policy_listener1.WaitUntilSatisfied());
260 ExtensionTestMessageListener policy_listener2(kTestPolicy2JSON, true);
261 policy_listener1.Reply("get-policy-Another");
262 EXPECT_TRUE(policy_listener2.WaitUntilSatisfied());
265 IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, InstallNewExtension) {
266 EXPECT_TRUE(test_server_.UpdatePolicyData(
267 dm_protocol::kChromeExtensionPolicyType, kTestExtension2, kTestPolicy2));
269 ExtensionTestMessageListener result_listener("ok", true);
270 result_listener.AlsoListenForFailureMessage("fail");
271 scoped_refptr<const extensions::Extension> extension2 =
272 LoadExtension(kTestExtension2Path);
273 ASSERT_TRUE(extension2.get());
274 ASSERT_EQ(kTestExtension2, extension2->id());
276 // This extension only sends the 'policy' signal once it receives the policy,
277 // and after verifying it has the expected value. Otherwise it sends 'fail'.
278 EXPECT_TRUE(result_listener.WaitUntilSatisfied());
281 // Signing out on Chrome OS is a different process from signing out on the
282 // Desktop platforms. On Chrome OS the session is ended, and the user goes back
283 // to the sign-in screen; the Profile data is not affected. On the Desktop the
284 // session goes on though, and all the signed-in services are disconnected;
285 // in particular, the policy caches are dropped if the user signs out.
286 // This test verifies that when the user signs out then any existing component
287 // policy caches are dropped, and that it's still possible to sign back in and
288 // get policy for components working again.
289 #if !defined(OS_CHROMEOS)
290 IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, SignOutAndBackIn) {
291 // Read the initial policy.
292 ExtensionTestMessageListener initial_policy_listener(kTestPolicyJSON, true);
293 event_listener_->Reply("get-policy-Name");
294 EXPECT_TRUE(initial_policy_listener.WaitUntilSatisfied());
296 // Verify that the policy cache exists.
297 std::string cache_key;
298 ASSERT_TRUE(Base64Encode("extension-policy", &cache_key));
299 std::string cache_subkey;
300 ASSERT_TRUE(Base64Encode(kTestExtension, &cache_subkey));
301 base::FilePath cache_path = browser()->profile()->GetPath()
302 .Append(FILE_PATH_LITERAL("Policy"))
303 .Append(FILE_PATH_LITERAL("Components"))
304 .AppendASCII(cache_key)
305 .AppendASCII(cache_subkey);
306 EXPECT_TRUE(base::PathExists(cache_path));
308 // Now sign-out. The policy cache should be removed, and the extension should
309 // get an empty policy update.
310 ExtensionTestMessageListener event_listener("event", true);
311 initial_policy_listener.Reply("idle");
312 SignOut();
313 EXPECT_TRUE(event_listener.WaitUntilSatisfied());
315 // The extension got an update event; verify that the policy was empty.
316 ExtensionTestMessageListener signout_policy_listener("{}", true);
317 event_listener.Reply("get-policy-Name");
318 EXPECT_TRUE(signout_policy_listener.WaitUntilSatisfied());
320 // Verify that the cache is gone.
321 EXPECT_FALSE(base::PathExists(cache_path));
323 // Verify that the policy is fetched again if the user signs back in.
324 ExtensionTestMessageListener event_listener2("event", true);
325 SignInAndRegister();
326 EXPECT_TRUE(event_listener2.WaitUntilSatisfied());
328 // The extension got updated policy; verify it.
329 ExtensionTestMessageListener signin_policy_listener(kTestPolicyJSON, true);
330 event_listener2.Reply("get-policy-Name");
331 EXPECT_TRUE(signin_policy_listener.WaitUntilSatisfied());
333 // And the cache is back.
334 EXPECT_TRUE(base::PathExists(cache_path));
336 #endif
338 } // namespace policy