Home | History | Annotate | Download | only in cloud
      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/command_line.h"
      8 #include "base/files/file_path.h"
      9 #include "base/memory/ref_counted.h"
     10 #include "base/path_service.h"
     11 #include "base/run_loop.h"
     12 #include "chrome/browser/browser_process.h"
     13 #include "chrome/browser/extensions/extension_browsertest.h"
     14 #include "chrome/browser/extensions/extension_test_message_listener.h"
     15 #include "chrome/browser/policy/browser_policy_connector.h"
     16 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
     17 #include "chrome/browser/policy/cloud/mock_cloud_policy_client.h"
     18 #include "chrome/browser/policy/policy_service.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/proto/cloud/chrome_extension_policy.pb.h"
     22 #include "chrome/browser/policy/test/local_policy_test_server.h"
     23 #include "chrome/browser/policy/test_utils.h"
     24 #include "chrome/browser/profiles/profile.h"
     25 #include "chrome/common/chrome_paths.h"
     26 #include "chrome/common/chrome_switches.h"
     27 #include "chrome/common/extensions/extension.h"
     28 #include "policy/proto/cloud_policy.pb.h"
     29 #include "testing/gmock/include/gmock/gmock.h"
     30 #include "testing/gtest/include/gtest/gtest.h"
     31 
     32 #if defined(OS_CHROMEOS)
     33 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
     34 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
     35 #include "chrome/common/chrome_paths.h"
     36 #include "chromeos/chromeos_switches.h"
     37 #else
     38 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
     39 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
     40 #include "chrome/browser/signin/signin_manager.h"
     41 #include "chrome/browser/signin/signin_manager_factory.h"
     42 #endif
     43 
     44 using testing::InvokeWithoutArgs;
     45 using testing::Mock;
     46 using testing::Return;
     47 using testing::_;
     48 
     49 namespace em = enterprise_management;
     50 
     51 namespace policy {
     52 
     53 namespace {
     54 
     55 const char kDMToken[] = "dmtoken";
     56 const char kDeviceID[] = "deviceid";
     57 
     58 const char kTestExtension[] = "kjmkgkdkpedkejedfhmfcenooemhbpbo";
     59 const char kTestExtension2[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
     60 
     61 const base::FilePath::CharType kTestExtensionPath[] =
     62     FILE_PATH_LITERAL("extensions/managed_extension");
     63 const base::FilePath::CharType kTestExtension2Path[] =
     64     FILE_PATH_LITERAL("extensions/managed_extension2");
     65 
     66 const char kTestPolicy[] =
     67     "{"
     68     "  \"Name\": {"
     69     "    \"Value\": \"disable_all_the_things\""
     70     "  }"
     71     "}";
     72 
     73 const char kTestPolicyJSON[] = "{\"Name\":\"disable_all_the_things\"}";
     74 
     75 const char kTestPolicy2[] =
     76     "{"
     77     "  \"Another\": {"
     78     "    \"Value\": \"turn_it_off\""
     79     "  }"
     80     "}";
     81 
     82 const char kTestPolicy2JSON[] = "{\"Another\":\"turn_it_off\"}";
     83 
     84 }  // namespace
     85 
     86 class ComponentCloudPolicyTest : public ExtensionBrowserTest {
     87  protected:
     88   ComponentCloudPolicyTest() {}
     89   virtual ~ComponentCloudPolicyTest() {}
     90 
     91   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     92     ExtensionBrowserTest::SetUpCommandLine(command_line);
     93 #if defined(OS_CHROMEOS)
     94     // ExtensionBrowserTest sets the login users to a non-managed value;
     95     // replace it. This is the default username sent in policy blobs from the
     96     // testserver.
     97     command_line->AppendSwitchASCII(
     98         chromeos::switches::kLoginUser, "user (at) example.com");
     99 #endif
    100   }
    101 
    102   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    103     test_server_.RegisterClient(kDMToken, kDeviceID);
    104     EXPECT_TRUE(test_server_.UpdatePolicyData(
    105         dm_protocol::kChromeExtensionPolicyType, kTestExtension, kTestPolicy));
    106     ASSERT_TRUE(test_server_.Start());
    107 
    108     std::string url = test_server_.GetServiceURL().spec();
    109     CommandLine* command_line = CommandLine::ForCurrentProcess();
    110     command_line->AppendSwitchASCII(switches::kDeviceManagementUrl, url);
    111     command_line->AppendSwitch(switches::kEnableComponentCloudPolicy);
    112 
    113     ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
    114   }
    115 
    116   virtual void SetUpOnMainThread() OVERRIDE {
    117     ASSERT_TRUE(PolicyServiceIsEmpty(g_browser_process->policy_service()))
    118         << "Pre-existing policies in this machine will make this test fail.";
    119 
    120     // Install the initial extension.
    121     ExtensionTestMessageListener ready_listener("ready", true);
    122     event_listener_.reset(new ExtensionTestMessageListener("event", true));
    123     extension_ = LoadExtension(kTestExtensionPath);
    124     ASSERT_TRUE(extension_.get());
    125     ASSERT_EQ(kTestExtension, extension_->id());
    126     EXPECT_TRUE(ready_listener.WaitUntilSatisfied());
    127 
    128     BrowserPolicyConnector* connector =
    129         g_browser_process->browser_policy_connector();
    130     connector->ScheduleServiceInitialization(0);
    131 
    132 #if defined(OS_CHROMEOS)
    133     UserCloudPolicyManagerChromeOS* policy_manager =
    134         UserCloudPolicyManagerFactoryChromeOS::GetForProfile(
    135             browser()->profile());
    136     ASSERT_TRUE(policy_manager);
    137 #else
    138     // Mock a signed-in user. This is used by the UserCloudPolicyStore to pass
    139     // the username to the UserCloudPolicyValidator.
    140     SigninManager* signin_manager =
    141         SigninManagerFactory::GetForProfile(browser()->profile());
    142     ASSERT_TRUE(signin_manager);
    143     signin_manager->SetAuthenticatedUsername("user (at) example.com");
    144 
    145     UserCloudPolicyManager* policy_manager =
    146         UserCloudPolicyManagerFactory::GetForProfile(browser()->profile());
    147     ASSERT_TRUE(policy_manager);
    148     policy_manager->Connect(g_browser_process->local_state(),
    149                             UserCloudPolicyManager::CreateCloudPolicyClient(
    150                                 connector->device_management_service()).Pass());
    151 #endif  // defined(OS_CHROMEOS)
    152 
    153     // Register the cloud policy client.
    154     ASSERT_TRUE(policy_manager->core()->client());
    155     base::RunLoop run_loop;
    156     MockCloudPolicyClientObserver observer;
    157     EXPECT_CALL(observer, OnRegistrationStateChanged(_))
    158         .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
    159     policy_manager->core()->client()->AddObserver(&observer);
    160     policy_manager->core()->client()->SetupRegistration(kDMToken, kDeviceID);
    161     run_loop.Run();
    162     Mock::VerifyAndClearExpectations(&observer);
    163     policy_manager->core()->client()->RemoveObserver(&observer);
    164 
    165     // The extension will receive an update event.
    166     EXPECT_TRUE(event_listener_->WaitUntilSatisfied());
    167 
    168     ExtensionBrowserTest::SetUpOnMainThread();
    169   }
    170 
    171   scoped_refptr<const extensions::Extension> LoadExtension(
    172       const base::FilePath::CharType* path) {
    173     base::FilePath full_path;
    174     if (!PathService::Get(chrome::DIR_TEST_DATA, &full_path)) {
    175       ADD_FAILURE();
    176       return NULL;
    177     }
    178     scoped_refptr<const extensions::Extension> extension(
    179         ExtensionBrowserTest::LoadExtension(full_path.Append(path)));
    180     if (!extension.get()) {
    181       ADD_FAILURE();
    182       return NULL;
    183     }
    184     return extension;
    185   }
    186 
    187   void RefreshPolicies() {
    188     ProfilePolicyConnector* profile_connector =
    189         ProfilePolicyConnectorFactory::GetForProfile(browser()->profile());
    190     PolicyService* policy_service = profile_connector->policy_service();
    191     base::RunLoop run_loop;
    192     policy_service->RefreshPolicies(run_loop.QuitClosure());
    193     run_loop.Run();
    194   }
    195 
    196   LocalPolicyTestServer test_server_;
    197   scoped_refptr<const extensions::Extension> extension_;
    198   scoped_ptr<ExtensionTestMessageListener> event_listener_;
    199 };
    200 
    201 // TODO(joaodasilva): enable these for other platforms once ready.
    202 #if defined(OS_CHROMEOS)
    203 
    204 IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, FetchExtensionPolicy) {
    205   // Read the initial policy.
    206   ExtensionTestMessageListener policy_listener(kTestPolicyJSON, true);
    207   event_listener_->Reply("get-policy-Name");
    208   EXPECT_TRUE(policy_listener.WaitUntilSatisfied());
    209 }
    210 
    211 IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, UpdateExtensionPolicy) {
    212   // Read the initial policy.
    213   ExtensionTestMessageListener policy_listener(kTestPolicyJSON, true);
    214   event_listener_->Reply("get-policy-Name");
    215   EXPECT_TRUE(policy_listener.WaitUntilSatisfied());
    216 
    217   // Update the policy at the server and reload policy.
    218   event_listener_.reset(new ExtensionTestMessageListener("event", true));
    219   policy_listener.Reply("idle");
    220   EXPECT_TRUE(test_server_.UpdatePolicyData(
    221       dm_protocol::kChromeExtensionPolicyType, kTestExtension, kTestPolicy2));
    222   RefreshPolicies();
    223 
    224   // Check that the update event was received, and verify the new policy
    225   // values.
    226   EXPECT_TRUE(event_listener_->WaitUntilSatisfied());
    227 
    228   // This policy was removed.
    229   ExtensionTestMessageListener policy_listener1("{}", true);
    230   event_listener_->Reply("get-policy-Name");
    231   EXPECT_TRUE(policy_listener1.WaitUntilSatisfied());
    232 
    233   ExtensionTestMessageListener policy_listener2(kTestPolicy2JSON, true);
    234   policy_listener1.Reply("get-policy-Another");
    235   EXPECT_TRUE(policy_listener2.WaitUntilSatisfied());
    236 }
    237 
    238 IN_PROC_BROWSER_TEST_F(ComponentCloudPolicyTest, InstallNewExtension) {
    239   EXPECT_TRUE(test_server_.UpdatePolicyData(
    240       dm_protocol::kChromeExtensionPolicyType, kTestExtension2, kTestPolicy2));
    241 
    242   ExtensionTestMessageListener result_listener("ok", true);
    243   result_listener.AlsoListenForFailureMessage("fail");
    244   scoped_refptr<const extensions::Extension> extension2 =
    245       LoadExtension(kTestExtension2Path);
    246   ASSERT_TRUE(extension2.get());
    247   ASSERT_EQ(kTestExtension2, extension2->id());
    248 
    249   // This extension only sends the 'policy' signal once it receives the policy,
    250   // and after verifying it has the expected value. Otherwise it sends 'fail'.
    251   EXPECT_TRUE(result_listener.WaitUntilSatisfied());
    252 }
    253 
    254 #endif  // OS_CHROMEOS
    255 
    256 }  // namespace policy
    257