1// Copyright 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 "base/callback.h"
6#include "base/command_line.h"
7#include "chrome/browser/browser_process.h"
8#include "chrome/browser/chromeos/login/user.h"
9#include "chrome/browser/chromeos/login/user_manager.h"
10#include "chrome/browser/extensions/extension_apitest.h"
11#include "chrome/browser/policy/browser_policy_connector.h"
12#include "chrome/browser/policy/external_data_fetcher.h"
13#include "chrome/browser/policy/mock_configuration_policy_provider.h"
14#include "chrome/browser/policy/policy_map.h"
15#include "chrome/browser/policy/policy_types.h"
16#include "chrome/common/chrome_switches.h"
17#include "chrome/test/base/ui_test_utils.h"
18
19#if defined(OS_CHROMEOS)
20#include "chromeos/chromeos_switches.h"
21#include "chromeos/dbus/cryptohome_client.h"
22#include "chromeos/dbus/dbus_thread_manager.h"
23#include "chromeos/dbus/shill_device_client.h"
24#include "chromeos/dbus/shill_manager_client.h"
25#include "chromeos/dbus/shill_profile_client.h"
26#include "chromeos/dbus/shill_service_client.h"
27#include "chromeos/network/onc/onc_constants.h"
28#include "chromeos/network/onc/onc_utils.h"
29#include "policy/policy_constants.h"
30#include "third_party/cros_system_api/dbus/service_constants.h"
31#endif  // OS_CHROMEOS
32using testing::AnyNumber;
33using testing::Return;
34using testing::_;
35
36namespace chromeos {
37
38namespace {
39
40const char kUser1ProfilePath[] = "/profile/user1/shill";
41const char kUserIdStubHashSuffix[] = "-hash";
42
43}  // namespace
44
45class ExtensionNetworkingPrivateApiTest :
46    public ExtensionApiTest,
47    public testing::WithParamInterface<bool> {
48 public:
49  bool RunNetworkingSubtest(const std::string& subtest) {
50    return RunExtensionSubtest(
51        "networking", "main.html?" + subtest,
52        kFlagEnableFileAccess | kFlagLoadAsComponent);
53  }
54
55  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
56    EXPECT_CALL(provider_, IsInitializationComplete(_))
57        .WillRepeatedly(Return(true));
58    EXPECT_CALL(provider_, RegisterPolicyDomain(_)).Times(AnyNumber());
59    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
60
61    ExtensionApiTest::SetUpInProcessBrowserTestFixture();
62  }
63
64#if defined(OS_CHROMEOS)
65  static void AssignString(std::string* out,
66                    DBusMethodCallStatus call_status,
67                    const std::string& result) {
68    CHECK_EQ(call_status, DBUS_METHOD_CALL_SUCCESS);
69    *out = result;
70  }
71
72  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
73    ExtensionApiTest::SetUpCommandLine(command_line);
74    // Whitelist the extension ID of the test extension.
75    command_line->AppendSwitchASCII(::switches::kWhitelistedExtensionID,
76                                    "epcifkihnkjgphfkloaaleeakhpmgdmn");
77    command_line->AppendSwitch(switches::kUseNewNetworkConfigurationHandlers);
78
79    // TODO(pneubeck): Remove the following hack, once the NetworkingPrivateAPI
80    // uses the ProfileHelper to obtain the userhash crbug/238623.
81    std::string login_user =
82        command_line->GetSwitchValueNative(switches::kLoginUser);
83    // Do the same as CryptohomeClientStubImpl::GetSanitizedUsername
84    std::string sanitized_user = login_user + kUserIdStubHashSuffix;
85    command_line->AppendSwitchASCII(switches::kLoginProfile, sanitized_user);
86    if (GetParam())
87      command_line->AppendSwitch(::switches::kMultiProfiles);
88  }
89
90  void InitializeSanitizedUsername() {
91    chromeos::UserManager* user_manager = chromeos::UserManager::Get();
92    chromeos::User* user = user_manager->GetActiveUser();
93    CHECK(user);
94    std::string userhash;
95    DBusThreadManager::Get()->GetCryptohomeClient()->GetSanitizedUsername(
96        user->email(),
97        base::Bind(&AssignString, &userhash_));
98    content::RunAllPendingInMessageLoop();
99    CHECK(!userhash_.empty());
100  }
101
102  virtual void SetUpOnMainThread() OVERRIDE {
103    ExtensionApiTest::SetUpOnMainThread();
104    content::RunAllPendingInMessageLoop();
105
106    InitializeSanitizedUsername();
107
108    ShillManagerClient::TestInterface* manager_test =
109        DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
110    ShillDeviceClient::TestInterface* device_test =
111        DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
112    ShillProfileClient::TestInterface* profile_test =
113        DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
114    ShillServiceClient::TestInterface* service_test =
115        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
116
117    device_test->ClearDevices();
118    service_test->ClearServices();
119
120    // Sends a notification about the added profile.
121    profile_test->AddProfile(kUser1ProfilePath, userhash_);
122
123    device_test->AddDevice("/device/stub_wifi_device1",
124                           flimflam::kTypeWifi, "stub_wifi_device1");
125    device_test->AddDevice("/device/stub_cellular_device1",
126                           flimflam::kTypeCellular, "stub_cellular_device1");
127
128    const bool add_to_watchlist = true;
129    const bool add_to_visible = true;
130    service_test->AddService("stub_ethernet", "eth0",
131                             flimflam::kTypeEthernet, flimflam::kStateOnline,
132                             add_to_visible, add_to_watchlist);
133
134    service_test->AddService("stub_wifi1", "wifi1",
135                             flimflam::kTypeWifi, flimflam::kStateOnline,
136                             add_to_visible, add_to_watchlist);
137    service_test->SetServiceProperty("stub_wifi1",
138                                     flimflam::kSecurityProperty,
139                                     base::StringValue(flimflam::kSecurityWep));
140    base::ListValue frequencies1;
141    frequencies1.AppendInteger(2400);
142    service_test->SetServiceProperty("stub_wifi1",
143                                     shill::kWifiFrequencyListProperty,
144                                     frequencies1);
145    service_test->SetServiceProperty("stub_wifi1",
146                                     flimflam::kWifiFrequency,
147                                     base::FundamentalValue(2400));
148
149    service_test->AddService("stub_wifi2", "wifi2_PSK",
150                             flimflam::kTypeWifi, flimflam::kStateIdle,
151                             add_to_visible, add_to_watchlist);
152    service_test->SetServiceProperty("stub_wifi2",
153                                     flimflam::kGuidProperty,
154                                     base::StringValue("stub_wifi2"));
155    service_test->SetServiceProperty("stub_wifi2",
156                                     flimflam::kSecurityProperty,
157                                     base::StringValue(flimflam::kSecurityPsk));
158    service_test->SetServiceProperty("stub_wifi2",
159                                     flimflam::kSignalStrengthProperty,
160                                     base::FundamentalValue(80));
161    service_test->SetServiceProperty("stub_wifi2",
162                                     flimflam::kConnectableProperty,
163                                     base::FundamentalValue(true));
164
165    base::ListValue frequencies2;
166    frequencies2.AppendInteger(2400);
167    frequencies2.AppendInteger(5000);
168    service_test->SetServiceProperty("stub_wifi2",
169                                     shill::kWifiFrequencyListProperty,
170                                     frequencies2);
171    service_test->SetServiceProperty("stub_wifi2",
172                                     flimflam::kWifiFrequency,
173                                     base::FundamentalValue(5000));
174    service_test->SetServiceProperty("stub_wifi2",
175                                     flimflam::kProfileProperty,
176                                     base::StringValue(kUser1ProfilePath));
177    profile_test->AddService(kUser1ProfilePath, "stub_wifi2");
178
179    service_test->AddService("stub_cellular1", "cellular1",
180                             flimflam::kTypeCellular, flimflam::kStateIdle,
181                             add_to_visible, add_to_watchlist);
182    service_test->SetServiceProperty(
183        "stub_cellular1",
184        flimflam::kNetworkTechnologyProperty,
185        base::StringValue(flimflam::kNetworkTechnologyGsm));
186    service_test->SetServiceProperty(
187        "stub_cellular1",
188        flimflam::kActivationStateProperty,
189        base::StringValue(flimflam::kActivationStateNotActivated));
190    service_test->SetServiceProperty(
191        "stub_cellular1",
192        flimflam::kRoamingStateProperty,
193        base::StringValue(flimflam::kRoamingStateHome));
194
195    service_test->AddService("stub_vpn1", "vpn1",
196                             flimflam::kTypeVPN,
197                             flimflam::kStateOnline,
198                             add_to_visible, add_to_watchlist);
199
200    manager_test->SortManagerServices();
201
202    content::RunAllPendingInMessageLoop();
203  }
204#else  // !defined(OS_CHROMEOS)
205  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
206    ExtensionApiTest::SetUpCommandLine(command_line);
207    // Whitelist the extension ID of the test extension.
208    command_line->AppendSwitchASCII(::switches::kWhitelistedExtensionID,
209                                    "epcifkihnkjgphfkloaaleeakhpmgdmn");
210  }
211
212  virtual void SetUpOnMainThread() OVERRIDE {
213    ExtensionApiTest::SetUpOnMainThread();
214    content::RunAllPendingInMessageLoop();
215  }
216#endif  // OS_CHROMEOS
217
218 protected:
219  policy::MockConfigurationPolicyProvider provider_;
220  std::string userhash_;
221};
222
223// Place each subtest into a separate browser test so that the stub networking
224// library state is reset for each subtest run. This way they won't affect each
225// other.
226
227IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, StartConnect) {
228  EXPECT_TRUE(RunNetworkingSubtest("startConnect")) << message_;
229}
230
231IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, StartDisconnect) {
232  EXPECT_TRUE(RunNetworkingSubtest("startDisconnect")) << message_;
233}
234
235IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
236                       StartConnectNonexistent) {
237  EXPECT_TRUE(RunNetworkingSubtest("startConnectNonexistent")) << message_;
238}
239
240IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
241                       StartDisconnectNonexistent) {
242  EXPECT_TRUE(RunNetworkingSubtest("startDisconnectNonexistent")) << message_;
243}
244
245IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
246                       StartGetPropertiesNonexistent) {
247  EXPECT_TRUE(RunNetworkingSubtest("startGetPropertiesNonexistent"))
248      << message_;
249}
250
251IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, GetVisibleNetworks) {
252  EXPECT_TRUE(RunNetworkingSubtest("getVisibleNetworks")) << message_;
253}
254
255IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
256                       GetVisibleNetworksWifi) {
257  EXPECT_TRUE(RunNetworkingSubtest("getVisibleNetworksWifi")) << message_;
258}
259
260IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, RequestNetworkScan) {
261  EXPECT_TRUE(RunNetworkingSubtest("requestNetworkScan")) << message_;
262}
263
264// Properties are filtered and translated through
265// ShillToONCTranslator::TranslateWiFiWithState
266IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, GetProperties) {
267  EXPECT_TRUE(RunNetworkingSubtest("getProperties")) << message_;
268}
269
270IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, GetState) {
271  EXPECT_TRUE(RunNetworkingSubtest("getState")) << message_;
272}
273
274IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, SetProperties) {
275  EXPECT_TRUE(RunNetworkingSubtest("setProperties")) << message_;
276}
277
278#if defined(OS_CHROMEOS)
279IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, GetStateNonExistent) {
280  EXPECT_TRUE(RunNetworkingSubtest("getStateNonExistent")) << message_;
281}
282
283IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
284                       GetManagedProperties) {
285  ShillServiceClient::TestInterface* service_test =
286      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
287  const std::string uidata_blob =
288      "{ \"user_settings\": {"
289      "      \"WiFi\": {"
290      "        \"Passphrase\": \"FAKE_CREDENTIAL_VPaJDV9x\" }"
291      "    }"
292      "}";
293  service_test->SetServiceProperty("stub_wifi2",
294                                   flimflam::kUIDataProperty,
295                                   base::StringValue(uidata_blob));
296  service_test->SetServiceProperty("stub_wifi2",
297                                   flimflam::kAutoConnectProperty,
298                                   base::FundamentalValue(false));
299
300  ShillProfileClient::TestInterface* profile_test =
301      DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
302  // Update the profile entry.
303  profile_test->AddService(kUser1ProfilePath, "stub_wifi2");
304
305  content::RunAllPendingInMessageLoop();
306
307  const std::string user_policy_blob =
308      "{ \"NetworkConfigurations\": ["
309      "    { \"GUID\": \"stub_wifi2\","
310      "      \"Type\": \"WiFi\","
311      "      \"Name\": \"My WiFi Network\","
312      "      \"WiFi\": {"
313      "        \"Passphrase\": \"passphrase\","
314      "        \"Recommended\": [ \"AutoConnect\", \"Passphrase\" ],"
315      "        \"SSID\": \"stub_wifi2\","
316      "        \"Security\": \"WPA-PSK\" }"
317      "    }"
318      "  ],"
319      "  \"Certificates\": [],"
320      "  \"Type\": \"UnencryptedConfiguration\""
321      "}";
322
323  policy::PolicyMap policy;
324  policy.Set(policy::key::kOpenNetworkConfiguration,
325             policy::POLICY_LEVEL_MANDATORY,
326             policy::POLICY_SCOPE_USER,
327             Value::CreateStringValue(user_policy_blob),
328             NULL);
329  provider_.UpdateChromePolicy(policy);
330
331  content::RunAllPendingInMessageLoop();
332
333  EXPECT_TRUE(RunNetworkingSubtest("getManagedProperties")) << message_;
334}
335#endif  // OS_CHROMEOS
336
337IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
338                       OnNetworksChangedEventConnect) {
339  EXPECT_TRUE(RunNetworkingSubtest("onNetworksChangedEventConnect"))
340      << message_;
341}
342
343IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
344                       OnNetworksChangedEventDisconnect) {
345  EXPECT_TRUE(RunNetworkingSubtest("onNetworksChangedEventDisconnect"))
346      << message_;
347}
348
349IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
350                       OnNetworkListChangedEvent) {
351  EXPECT_TRUE(RunNetworkingSubtest("onNetworkListChangedEvent")) << message_;
352}
353
354IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
355                       VerifyDestination) {
356  EXPECT_TRUE(RunNetworkingSubtest("verifyDestination")) << message_;
357}
358
359IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
360                       VerifyAndEncryptCredentials) {
361  EXPECT_TRUE(RunNetworkingSubtest("verifyAndEncryptCredentials")) << message_;
362}
363
364IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
365                       VerifyAndEncryptData) {
366  EXPECT_TRUE(RunNetworkingSubtest("verifyAndEncryptData")) << message_;
367}
368
369INSTANTIATE_TEST_CASE_P(ExtensionNetworkingPrivateApiTestInstantiation,
370                        ExtensionNetworkingPrivateApiTest,
371                        testing::Bool());
372
373}  // namespace chromeos
374