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