1 // Copyright 2015 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 "base/strings/string_number_conversions.h"
6 #include "chrome/browser/chromeos/profiles/profile_helper.h"
7 #include "chrome/browser/extensions/extension_apitest.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chromeos/dbus/dbus_thread_manager.h"
10 #include "chromeos/dbus/fake_shill_profile_client.h"
11 #include "chromeos/dbus/fake_shill_service_client.h"
12 #include "chromeos/dbus/fake_shill_third_party_vpn_driver_client.h"
13 #include "chromeos/network/network_configuration_handler.h"
14 #include "chromeos/network/network_configuration_observer.h"
15 #include "chromeos/network/network_profile_handler.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/test/test_utils.h"
18 #include "extensions/browser/api/vpn_provider/vpn_provider_api.h"
19 #include "extensions/browser/api/vpn_provider/vpn_service.h"
20 #include "extensions/browser/api/vpn_provider/vpn_service_factory.h"
21 #include "extensions/browser/api_test_utils.h"
22 #include "extensions/common/extension.h"
23 #include "extensions/test/result_catcher.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "third_party/cros_system_api/dbus/service_constants.h"
28 using testing::Invoke
;
34 namespace api_vpn
= extensions::api::vpn_provider
;
36 const char kNetworkProfilePath
[] = "/network/test";
37 const char kTestConfig
[] = "testconfig";
38 const char* kParameterValues
[] = {"10.10.10.10",
40 "63.145.213.129/32 63.145.212.0/24",
41 "0.0.0.0/0 63.145.212.128/25",
46 const char* kParameterKeys
[] = {shill::kAddressParameterThirdPartyVpn
,
47 shill::kSubnetPrefixParameterThirdPartyVpn
,
48 shill::kExclusionListParameterThirdPartyVpn
,
49 shill::kInclusionListParameterThirdPartyVpn
,
50 shill::kDnsServersParameterThirdPartyVpn
,
51 shill::kMtuParameterThirdPartyVpn
,
52 shill::kBroadcastAddressParameterThirdPartyVpn
,
53 shill::kDomainSearchParameterThirdPartyVpn
};
55 void DoNothingFailureCallback(const std::string
& error_name
,
56 scoped_ptr
<base::DictionaryValue
> error_data
) {
57 EXPECT_EQ(true, false);
60 void DoNothingSuccessCallback(const std::string
& service_path
) {
65 // Records the number of calls and their parameters. Always replies successfully
67 class TestShillThirdPartyVpnDriverClient
68 : public FakeShillThirdPartyVpnDriverClient
{
71 const std::string
& object_path_value
,
72 const base::DictionaryValue
& parameters
,
73 const ShillClientHelper::StringCallback
& callback
,
74 const ShillClientHelper::ErrorCallback
& error_callback
) override
{
75 set_parameters_counter_
++;
76 parameters_
= parameters
.DeepCopy();
77 FakeShillThirdPartyVpnDriverClient::SetParameters(
78 object_path_value
, parameters
, callback
, error_callback
);
81 void UpdateConnectionState(
82 const std::string
& object_path_value
,
83 const uint32_t connection_state
,
84 const base::Closure
& callback
,
85 const ShillClientHelper::ErrorCallback
& error_callback
) override
{
86 update_connection_state_counter_
++;
87 connection_state_
= connection_state
;
88 FakeShillThirdPartyVpnDriverClient::UpdateConnectionState(
89 object_path_value
, connection_state
, callback
, error_callback
);
93 const std::string
& object_path_value
,
94 const std::vector
<char>& ip_packet
,
95 const base::Closure
& callback
,
96 const ShillClientHelper::ErrorCallback
& error_callback
) override
{
97 send_packet_counter_
++;
98 ip_packet_
= ip_packet
;
99 FakeShillThirdPartyVpnDriverClient::SendPacket(object_path_value
, ip_packet
,
100 callback
, error_callback
);
103 int set_parameters_counter_
= 0;
104 base::DictionaryValue
* parameters_
= nullptr;
105 int update_connection_state_counter_
= 0;
106 uint32_t connection_state_
;
107 int send_packet_counter_
= 0;
108 std::vector
<char> ip_packet_
;
111 class VpnProviderApiTest
: public ExtensionApiTest
,
112 public NetworkConfigurationObserver
{
114 VpnProviderApiTest() {}
115 ~VpnProviderApiTest() override
{}
117 void SetUpInProcessBrowserTestFixture() override
{
118 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
119 test_client_
= new TestShillThirdPartyVpnDriverClient();
120 DBusThreadManager::GetSetterForTesting()->SetShillThirdPartyVpnDriverClient(
121 make_scoped_ptr(test_client_
));
124 void AddNetworkProfileForUser() {
125 static_cast<FakeShillProfileClient
*>(
126 DBusThreadManager::Get()->GetShillProfileClient())
129 chromeos::ProfileHelper::GetUserIdHashFromProfile(profile()));
130 content::RunAllPendingInMessageLoop();
133 void LoadVpnExtension() {
134 NetworkHandler::Get()->network_configuration_handler()->AddObserver(this);
135 extension_
= LoadExtension(test_data_dir_
.AppendASCII("vpn_provider"));
136 extension_id_
= extension_
->id();
137 service_
= VpnServiceFactory::GetForBrowserContext(profile());
138 content::RunAllPendingInMessageLoop();
141 bool RunExtensionTest(const std::string
& test_name
) {
142 GURL url
= extension_
->GetResourceURL("basic.html?#" + test_name
);
143 return RunExtensionSubtest("vpn_provider", url
.spec());
146 std::string
GetKey(const std::string
& config_name
) {
147 return service_
->GetKey(extension_id_
, config_name
);
150 bool DoesConfigExist(const std::string
& config_name
) {
151 return service_
->VerifyConfigExistsForTesting(extension_id_
, config_name
);
154 bool IsConfigConnected() {
155 return service_
->VerifyConfigIsConnectedForTesting(extension_id_
);
158 std::string
GetSingleServicePath() {
159 EXPECT_FALSE(service_path_
.empty());
160 return service_path_
;
163 bool CreateConfigForTest(const std::string
& name
) {
164 scoped_refptr
<extensions::VpnProviderCreateConfigFunction
> create(
165 new extensions::VpnProviderCreateConfigFunction());
167 create
->set_extension(GetSingleLoadedExtension());
168 return extensions::api_test_utils::RunFunction(
169 create
.get(), "[\"" + name
+ "\"]", profile());
172 bool DestroyConfigForTest(const std::string
& name
) {
173 scoped_refptr
<extensions::VpnProviderDestroyConfigFunction
> destroy(
174 new extensions::VpnProviderDestroyConfigFunction());
176 destroy
->set_extension(GetSingleLoadedExtension());
177 return extensions::api_test_utils::RunFunction(
178 destroy
.get(), "[\"" + name
+ "\"]", profile());
181 void TriggerInternalRemove() {
182 NetworkHandler::Get()->network_configuration_handler()->RemoveConfiguration(
183 GetSingleServicePath(),
184 NetworkConfigurationObserver::SOURCE_USER_ACTION
,
185 base::Bind(base::DoNothing
), base::Bind(DoNothingFailureCallback
));
188 // NetworkConfigurationObserver:
189 void OnConfigurationCreated(const std::string
& service_path
,
190 const std::string
& profile_path
,
191 const base::DictionaryValue
& properties
,
192 Source source
) override
{
193 service_path_
= service_path
;
196 void OnConfigurationRemoved(const std::string
& service_path
,
197 const std::string
& guid
,
198 Source source
) override
{}
200 void OnPropertiesSet(const std::string
& service_path
,
201 const std::string
& guid
,
202 const base::DictionaryValue
& set_properties
,
203 Source source
) override
{}
205 void OnConfigurationProfileChanged(const std::string
& service_path
,
206 const std::string
& profile_path
,
207 Source source
) override
{}
210 TestShillThirdPartyVpnDriverClient
* test_client_
= nullptr;
211 VpnService
* service_
= nullptr;
212 std::string extension_id_
;
213 std::string service_path_
;
214 const extensions::Extension
* extension_
= nullptr;
217 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, ComboSuite
) {
219 AddNetworkProfileForUser();
220 EXPECT_TRUE(RunExtensionTest("comboSuite"));
223 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, CreateConfigWithoutNetworkProfile
) {
225 EXPECT_TRUE(RunExtensionTest("createConfigWithoutNetworkProfile"));
228 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, CreateConfig
) {
230 AddNetworkProfileForUser();
231 EXPECT_TRUE(RunExtensionTest("createConfigSuccess"));
232 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
233 const std::string service_path
= GetSingleServicePath();
234 std::string profile_path
;
235 base::DictionaryValue properties
;
236 EXPECT_TRUE(DBusThreadManager::Get()
237 ->GetShillProfileClient()
239 ->GetService(service_path
, &profile_path
, &properties
));
242 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, DestroyConfig
) {
244 AddNetworkProfileForUser();
245 EXPECT_TRUE(CreateConfigForTest(kTestConfig
));
246 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
247 const std::string service_path
= GetSingleServicePath();
248 std::string profile_path
;
249 base::DictionaryValue properties
;
250 EXPECT_TRUE(DBusThreadManager::Get()
251 ->GetShillProfileClient()
253 ->GetService(service_path
, &profile_path
, &properties
));
255 EXPECT_TRUE(RunExtensionTest("destroyConfigSuccess"));
256 EXPECT_FALSE(DoesConfigExist(kTestConfig
));
257 EXPECT_FALSE(DBusThreadManager::Get()
258 ->GetShillProfileClient()
260 ->GetService(service_path
, &profile_path
, &properties
));
263 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, DestroyConnectedConfig
) {
265 AddNetworkProfileForUser();
267 EXPECT_TRUE(CreateConfigForTest(kTestConfig
));
268 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
269 const std::string service_path
= GetSingleServicePath();
270 std::string profile_path
;
271 base::DictionaryValue properties
;
272 EXPECT_TRUE(DBusThreadManager::Get()
273 ->GetShillProfileClient()
275 ->GetService(service_path
, &profile_path
, &properties
));
276 EXPECT_FALSE(IsConfigConnected());
278 const std::string object_path
= shill::kObjectPathBase
+ GetKey(kTestConfig
);
279 test_client_
->OnPlatformMessage(object_path
,
280 api_vpn::PLATFORM_MESSAGE_CONNECTED
);
281 EXPECT_TRUE(IsConfigConnected());
283 EXPECT_TRUE(RunExtensionTest("destroyConnectedConfigSetup"));
285 EXPECT_TRUE(DestroyConfigForTest(kTestConfig
));
286 EXPECT_FALSE(DoesConfigExist(kTestConfig
));
287 EXPECT_FALSE(DBusThreadManager::Get()
288 ->GetShillProfileClient()
290 ->GetService(service_path
, &profile_path
, &properties
));
292 extensions::ResultCatcher catcher
;
293 ASSERT_TRUE(catcher
.GetNextResult());
296 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, VpnSuccess
) {
298 AddNetworkProfileForUser();
299 EXPECT_TRUE(RunExtensionTest("createConfigConnectAndDisconnect"));
300 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
301 const std::string service_path
= GetSingleServicePath();
302 std::string profile_path
;
303 base::DictionaryValue properties
;
304 EXPECT_TRUE(DBusThreadManager::Get()
305 ->GetShillProfileClient()
307 ->GetService(service_path
, &profile_path
, &properties
));
308 EXPECT_FALSE(IsConfigConnected());
310 const std::string object_path
= shill::kObjectPathBase
+ GetKey(kTestConfig
);
312 extensions::ResultCatcher catcher
;
313 EXPECT_EQ(0, test_client_
->set_parameters_counter_
);
314 EXPECT_EQ(0, test_client_
->update_connection_state_counter_
);
315 EXPECT_EQ(0, test_client_
->send_packet_counter_
);
316 test_client_
->OnPlatformMessage(object_path
,
317 api_vpn::PLATFORM_MESSAGE_CONNECTED
);
318 EXPECT_TRUE(IsConfigConnected());
319 ASSERT_TRUE(catcher
.GetNextResult());
320 EXPECT_EQ(1, test_client_
->set_parameters_counter_
);
321 EXPECT_EQ(1, test_client_
->update_connection_state_counter_
);
322 EXPECT_EQ(1, test_client_
->send_packet_counter_
);
323 EXPECT_EQ(api_vpn::VPN_CONNECTION_STATE_CONNECTED
,
324 test_client_
->update_connection_state_counter_
);
325 for (size_t i
= 0; i
< arraysize(kParameterValues
); ++i
) {
328 test_client_
->parameters_
->GetString(kParameterKeys
[i
], &value
));
329 EXPECT_EQ(kParameterValues
[i
], value
);
331 const char kPacket
[] = "feebdaed";
332 std::vector
<char> packet(&kPacket
[0], &kPacket
[8]);
333 EXPECT_EQ(packet
, test_client_
->ip_packet_
);
335 packet
.assign(test_client_
->ip_packet_
.rbegin(),
336 test_client_
->ip_packet_
.rend());
337 test_client_
->OnPacketReceived(object_path
, packet
);
338 ASSERT_TRUE(catcher
.GetNextResult());
340 test_client_
->OnPlatformMessage(object_path
,
341 api_vpn::PLATFORM_MESSAGE_DISCONNECTED
);
342 ASSERT_TRUE(catcher
.GetNextResult());
343 EXPECT_FALSE(IsConfigConnected());
346 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, ConfigInternalRemove
) {
348 AddNetworkProfileForUser();
349 EXPECT_TRUE(RunExtensionTest("configInternalRemove"));
350 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
352 extensions::ResultCatcher catcher
;
353 TriggerInternalRemove();
354 ASSERT_TRUE(catcher
.GetNextResult());
355 EXPECT_FALSE(DoesConfigExist(kTestConfig
));
358 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, CheckEvents
) {
360 AddNetworkProfileForUser();
361 EXPECT_TRUE(RunExtensionTest("expectEvents"));
362 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
364 extensions::ResultCatcher catcher
;
365 service_
->SendPlatformError(extension_id_
, kTestConfig
, "error_message");
366 service_
->SendShowAddDialogToExtension(extension_id_
);
367 service_
->SendShowConfigureDialogToExtension(extension_id_
, kTestConfig
);
368 EXPECT_TRUE(catcher
.GetNextResult());
371 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, ConfigPersistence
) {
373 AddNetworkProfileForUser();
374 EXPECT_FALSE(DoesConfigExist(kTestConfig
));
376 base::DictionaryValue properties
;
377 properties
.SetStringWithoutPathExpansion(shill::kTypeProperty
,
379 properties
.SetStringWithoutPathExpansion(shill::kNameProperty
, kTestConfig
);
380 properties
.SetStringWithoutPathExpansion(shill::kProviderHostProperty
,
382 properties
.SetStringWithoutPathExpansion(shill::kObjectPathSuffixProperty
,
383 GetKey(kTestConfig
));
384 properties
.SetStringWithoutPathExpansion(shill::kProviderTypeProperty
,
385 shill::kProviderThirdPartyVpn
);
386 properties
.SetStringWithoutPathExpansion(shill::kProfileProperty
,
387 kNetworkProfilePath
);
388 NetworkHandler::Get()
389 ->network_configuration_handler()
390 ->CreateShillConfiguration(
391 properties
, NetworkConfigurationObserver::SOURCE_EXTENSION_INSTALL
,
392 base::Bind(DoNothingSuccessCallback
),
393 base::Bind(DoNothingFailureCallback
));
394 content::RunAllPendingInMessageLoop();
395 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
398 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, CreateUninstall
) {
400 AddNetworkProfileForUser();
401 EXPECT_TRUE(RunExtensionTest("createConfigSuccess"));
402 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
404 const std::string service_path
= GetSingleServicePath();
405 std::string profile_path
;
406 base::DictionaryValue properties
;
407 EXPECT_TRUE(DBusThreadManager::Get()
408 ->GetShillProfileClient()
410 ->GetService(service_path
, &profile_path
, &properties
));
412 UninstallExtension(extension_id_
);
413 content::RunAllPendingInMessageLoop();
414 EXPECT_FALSE(DoesConfigExist(kTestConfig
));
415 EXPECT_FALSE(DBusThreadManager::Get()
416 ->GetShillProfileClient()
418 ->GetService(service_path
, &profile_path
, &properties
));
421 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, CreateDisable
) {
423 AddNetworkProfileForUser();
424 EXPECT_TRUE(RunExtensionTest("createConfigSuccess"));
425 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
427 const std::string service_path
= GetSingleServicePath();
428 std::string profile_path
;
429 base::DictionaryValue properties
;
430 EXPECT_TRUE(DBusThreadManager::Get()
431 ->GetShillProfileClient()
433 ->GetService(service_path
, &profile_path
, &properties
));
435 ExtensionService
* extension_service
=
436 extensions::ExtensionSystem::Get(profile())->extension_service();
437 extension_service
->DisableExtension(extension_id_
,
438 extensions::Extension::DISABLE_NONE
);
439 content::RunAllPendingInMessageLoop();
440 EXPECT_FALSE(DoesConfigExist(kTestConfig
));
441 EXPECT_FALSE(DBusThreadManager::Get()
442 ->GetShillProfileClient()
444 ->GetService(service_path
, &profile_path
, &properties
));
447 IN_PROC_BROWSER_TEST_F(VpnProviderApiTest
, CreateBlacklist
) {
449 AddNetworkProfileForUser();
450 EXPECT_TRUE(RunExtensionTest("createConfigSuccess"));
451 EXPECT_TRUE(DoesConfigExist(kTestConfig
));
453 const std::string service_path
= GetSingleServicePath();
454 std::string profile_path
;
455 base::DictionaryValue properties
;
456 EXPECT_TRUE(DBusThreadManager::Get()
457 ->GetShillProfileClient()
459 ->GetService(service_path
, &profile_path
, &properties
));
461 ExtensionService
* extension_service
=
462 extensions::ExtensionSystem::Get(profile())->extension_service();
463 extension_service
->BlacklistExtensionForTest(extension_id_
);
464 content::RunAllPendingInMessageLoop();
465 EXPECT_FALSE(DoesConfigExist(kTestConfig
));
466 EXPECT_FALSE(DBusThreadManager::Get()
467 ->GetShillProfileClient()
469 ->GetService(service_path
, &profile_path
, &properties
));
472 } // namespace chromeos