1 // Copyright 2019 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 "chromeos/services/network_config/cros_network_config.h"
6 
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/json/json_reader.h"
10 #include "base/memory/ptr_util.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/test/task_environment.h"
14 #include "chromeos/dbus/shill/fake_shill_device_client.h"
15 #include "chromeos/login/login_state/login_state.h"
16 #include "chromeos/network/managed_network_configuration_handler.h"
17 #include "chromeos/network/network_cert_loader.h"
18 #include "chromeos/network/network_certificate_handler.h"
19 #include "chromeos/network/network_configuration_handler.h"
20 #include "chromeos/network/network_connection_handler.h"
21 #include "chromeos/network/network_device_handler.h"
22 #include "chromeos/network/network_metadata_store.h"
23 #include "chromeos/network/network_profile_handler.h"
24 #include "chromeos/network/network_state_handler.h"
25 #include "chromeos/network/network_state_test_helper.h"
26 #include "chromeos/network/network_type_pattern.h"
27 #include "chromeos/network/onc/onc_utils.h"
28 #include "chromeos/network/proxy/ui_proxy_config_service.h"
29 #include "chromeos/services/network_config/public/cpp/cros_network_config_test_observer.h"
30 #include "components/onc/onc_constants.h"
31 #include "components/onc/onc_pref_names.h"
32 #include "components/prefs/testing_pref_service.h"
33 #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
34 #include "components/proxy_config/proxy_config_pref_names.h"
35 #include "components/sync_preferences/testing_pref_service_syncable.h"
36 #include "net/base/ip_address.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
39 
40 namespace chromeos {
41 namespace network_config {
42 
43 namespace {
44 
45 const int kSimRetriesLeft = 3;
46 const char kCellularDevicePath[] = "/device/stub_cellular_device";
47 
48 const char kCellularTestApn1[] = "TEST.APN1";
49 const char kCellularTestApnName1[] = "Test Apn 1";
50 const char kCellularTestApnUsername1[] = "Test User";
51 const char kCellularTestApnPassword1[] = "Test Pass";
52 
53 const char kCellularTestApn2[] = "TEST.APN2";
54 const char kCellularTestApnName2[] = "Test Apn 2";
55 const char kCellularTestApnUsername2[] = "Test User";
56 const char kCellularTestApnPassword2[] = "Test Pass";
57 
58 const char kCellularTestApn3[] = "TEST.APN3";
59 const char kCellularTestApnName3[] = "Test Apn 3";
60 const char kCellularTestApnUsername3[] = "Test User";
61 const char kCellularTestApnPassword3[] = "Test Pass";
62 
63 }  // namespace
64 
65 class CrosNetworkConfigTest : public testing::Test {
66  public:
CrosNetworkConfigTest()67   CrosNetworkConfigTest() {
68     LoginState::Initialize();
69     NetworkCertLoader::Initialize();
70     NetworkHandler::Initialize();
71     network_profile_handler_ = NetworkProfileHandler::InitializeForTesting();
72     network_device_handler_ = NetworkDeviceHandler::InitializeForTesting(
73         helper_.network_state_handler());
74     network_configuration_handler_ =
75         base::WrapUnique<NetworkConfigurationHandler>(
76             NetworkConfigurationHandler::InitializeForTest(
77                 helper_.network_state_handler(),
78                 network_device_handler_.get()));
79 
80     PrefProxyConfigTrackerImpl::RegisterProfilePrefs(user_prefs_.registry());
81     PrefProxyConfigTrackerImpl::RegisterPrefs(local_state_.registry());
82     ::onc::RegisterProfilePrefs(user_prefs_.registry());
83     ::onc::RegisterPrefs(local_state_.registry());
84     NetworkMetadataStore::RegisterPrefs(user_prefs_.registry());
85     NetworkMetadataStore::RegisterPrefs(local_state_.registry());
86     NetworkHandler::Get()->InitializePrefServices(&user_prefs_, &local_state_);
87 
88     ui_proxy_config_service_ = std::make_unique<chromeos::UIProxyConfigService>(
89         &user_prefs_, &local_state_, helper_.network_state_handler(),
90         network_profile_handler_.get());
91 
92     managed_network_configuration_handler_ =
93         ManagedNetworkConfigurationHandler::InitializeForTesting(
94             helper_.network_state_handler(), network_profile_handler_.get(),
95             network_device_handler_.get(), network_configuration_handler_.get(),
96             ui_proxy_config_service_.get());
97     network_connection_handler_ =
98         NetworkConnectionHandler::InitializeForTesting(
99             helper_.network_state_handler(),
100             network_configuration_handler_.get(),
101             managed_network_configuration_handler_.get());
102     network_certificate_handler_ =
103         std::make_unique<NetworkCertificateHandler>();
104     cros_network_config_ = std::make_unique<CrosNetworkConfig>(
105         helper_.network_state_handler(), network_device_handler_.get(),
106         managed_network_configuration_handler_.get(),
107         network_connection_handler_.get(), network_certificate_handler_.get());
108     SetupPolicy();
109     SetupNetworks();
110   }
111 
~CrosNetworkConfigTest()112   ~CrosNetworkConfigTest() override {
113     cros_network_config_.reset();
114     network_certificate_handler_.reset();
115     network_connection_handler_.reset();
116     managed_network_configuration_handler_.reset();
117     network_configuration_handler_.reset();
118     network_device_handler_.reset();
119     network_profile_handler_.reset();
120     ui_proxy_config_service_.reset();
121     NetworkHandler::Shutdown();
122     NetworkCertLoader::Shutdown();
123     LoginState::Shutdown();
124   }
125 
SetupPolicy()126   void SetupPolicy() {
127     managed_network_configuration_handler_->SetPolicy(
128         ::onc::ONC_SOURCE_DEVICE_POLICY,
129         /*userhash=*/std::string(),
130         /*network_configs_onc=*/base::ListValue(),
131         /*global_network_config=*/base::DictionaryValue());
132 
133     const std::string user_policy_ssid = "wifi2";
134     base::Value wifi2_onc = onc::ReadDictionaryFromJson(base::StringPrintf(
135         R"({"GUID": "wifi2_guid", "Type": "WiFi",
136                 "Name": "wifi2", "Priority": 0,
137                 "WiFi": { "Passphrase": "fake", "SSID": "%s", "HexSSID": "%s",
138                           "Security": "WPA-PSK", "AutoConnect": true}})",
139         user_policy_ssid.c_str(),
140         base::HexEncode(user_policy_ssid.c_str(), user_policy_ssid.size())
141             .c_str()));
142     base::ListValue user_policy_onc;
143     user_policy_onc.Append(std::move(wifi2_onc));
144     managed_network_configuration_handler_->SetPolicy(
145         ::onc::ONC_SOURCE_USER_POLICY, helper().UserHash(), user_policy_onc,
146         /*global_network_config=*/base::DictionaryValue());
147     base::RunLoop().RunUntilIdle();
148   }
149 
SetupNetworks()150   void SetupNetworks() {
151     // Wifi device exists by default, add Ethernet and Cellular.
152     helper().device_test()->AddDevice("/device/stub_eth_device",
153                                       shill::kTypeEthernet, "stub_eth_device");
154     helper().manager_test()->AddTechnology(shill::kTypeCellular,
155                                            true /* enabled */);
156     helper().device_test()->AddDevice(kCellularDevicePath, shill::kTypeCellular,
157                                       "stub_cellular_device");
158     base::Value sim_value(base::Value::Type::DICTIONARY);
159     sim_value.SetKey(shill::kSIMLockEnabledProperty, base::Value(true));
160     sim_value.SetKey(shill::kSIMLockTypeProperty,
161                      base::Value(shill::kSIMLockPin));
162     sim_value.SetKey(shill::kSIMLockRetriesLeftProperty,
163                      base::Value(kSimRetriesLeft));
164     helper().device_test()->SetDeviceProperty(
165         kCellularDevicePath, shill::kSIMLockStatusProperty, sim_value,
166         /*notify_changed=*/false);
167     helper().device_test()->SetDeviceProperty(
168         kCellularDevicePath, shill::kSIMPresentProperty, base::Value(true),
169         /*notify_changed=*/false);
170 
171     // Note: These are Shill dictionaries, not ONC.
172     helper().ConfigureService(
173         R"({"GUID": "eth_guid", "Type": "ethernet", "State": "online"})");
174     wifi1_path_ = helper().ConfigureService(
175         R"({"GUID": "wifi1_guid", "Type": "wifi", "State": "ready",
176             "Strength": 50, "AutoConnect": true})");
177     helper().ConfigureService(
178         R"({"GUID": "wifi2_guid", "Type": "wifi", "SSID": "wifi2",
179             "State": "idle", "SecurityClass": "psk", "Strength": 100,
180             "Profile": "user_profile_path"})");
181     helper().ConfigureService(base::StringPrintf(
182         R"({"GUID": "cellular_guid", "Type": "cellular",  "State": "idle",
183             "Strength": 0, "Cellular.NetworkTechnology": "LTE",
184             "Cellular.ActivationState": "activated",
185             "Profile": "%s"})",
186         NetworkProfileHandler::GetSharedProfilePath().c_str()));
187     helper().ConfigureService(
188         R"({"GUID": "vpn_guid", "Type": "vpn", "State": "association",
189             "Provider": {"Type": "l2tpipsec"}})");
190 
191     // Add a non visible configured wifi service.
192     std::string wifi3_path = helper().ConfigureService(
193         R"({"GUID": "wifi3_guid", "Type": "wifi", "SecurityClass": "psk",
194             "Visible": false})");
195     helper().profile_test()->AddService(
196         NetworkProfileHandler::GetSharedProfilePath(), wifi3_path);
197 
198     // Syncable wifi network:
199     std::string service_path = helper().ConfigureService(
200         R"({"GUID": "wifi4_guid", "Type": "wifi", "SSID": "wifi4",
201             "State": "idle", "SecurityClass": "psk", "Strength": 100,
202             "Profile": "user_profile_path", "Connectable": true})");
203     NetworkHandler::Get()->network_metadata_store()->ConnectSucceeded(
204         service_path);
205 
206     base::RunLoop().RunUntilIdle();
207   }
208 
SetupAPNList()209   void SetupAPNList() {
210     base::Value apn_list(base::Value::Type::LIST);
211     base::Value apn_entry1(base::Value::Type::DICTIONARY);
212     apn_entry1.SetStringKey(shill::kApnNameProperty, kCellularTestApnName1);
213     apn_entry1.SetStringKey(shill::kApnProperty, kCellularTestApn1);
214     apn_entry1.SetStringKey(shill::kApnUsernameProperty,
215                             kCellularTestApnUsername1);
216     apn_entry1.SetStringKey(shill::kApnPasswordProperty,
217                             kCellularTestApnPassword1);
218     apn_list.Append(std::move(apn_entry1));
219     base::Value apn_entry2(base::Value::Type::DICTIONARY);
220     apn_entry2.SetStringKey(shill::kApnNameProperty, kCellularTestApnName2);
221     apn_entry2.SetStringKey(shill::kApnProperty, kCellularTestApn2);
222     apn_entry2.SetStringKey(shill::kApnUsernameProperty,
223                             kCellularTestApnUsername2);
224     apn_entry2.SetStringKey(shill::kApnPasswordProperty,
225                             kCellularTestApnPassword2);
226     apn_list.Append(std::move(apn_entry2));
227 
228     helper().device_test()->SetDeviceProperty(
229         kCellularDevicePath, shill::kCellularApnListProperty, apn_list,
230         /*notify_changed=*/true);
231     base::RunLoop().RunUntilIdle();
232   }
233 
SetupEthernetEAP()234   void SetupEthernetEAP() {
235     std::string eap_path = helper().ConfigureService(
236         R"({"GUID": "eth_eap_guid", "Type": "etherneteap",
237             "State": "online", "EAP.EAP": "TTLS", "EAP.Identity": "user1"})");
238     helper().profile_test()->AddService(
239         NetworkProfileHandler::GetSharedProfilePath(), eap_path);
240     base::RunLoop().RunUntilIdle();
241   }
242 
SetupObserver()243   void SetupObserver() {
244     observer_ = std::make_unique<CrosNetworkConfigTestObserver>();
245     cros_network_config_->AddObserver(observer_->GenerateRemote());
246   }
247 
GetNetworkState(const std::string & guid)248   mojom::NetworkStatePropertiesPtr GetNetworkState(const std::string& guid) {
249     mojom::NetworkStatePropertiesPtr result;
250     base::RunLoop run_loop;
251     cros_network_config()->GetNetworkState(
252         guid, base::BindOnce(
253                   [](mojom::NetworkStatePropertiesPtr* result,
254                      base::OnceClosure quit_closure,
255                      mojom::NetworkStatePropertiesPtr network) {
256                     *result = std::move(network);
257                     std::move(quit_closure).Run();
258                   },
259                   &result, run_loop.QuitClosure()));
260     run_loop.Run();
261     return result;
262   }
263 
GetNetworkStateList(mojom::NetworkFilterPtr filter)264   std::vector<mojom::NetworkStatePropertiesPtr> GetNetworkStateList(
265       mojom::NetworkFilterPtr filter) {
266     std::vector<mojom::NetworkStatePropertiesPtr> result;
267     base::RunLoop run_loop;
268     cros_network_config()->GetNetworkStateList(
269         std::move(filter),
270         base::BindOnce(
271             [](std::vector<mojom::NetworkStatePropertiesPtr>* result,
272                base::OnceClosure quit_closure,
273                std::vector<mojom::NetworkStatePropertiesPtr> networks) {
274               for (auto& network : networks)
275                 result->push_back(std::move(network));
276               std::move(quit_closure).Run();
277             },
278             &result, run_loop.QuitClosure()));
279     run_loop.Run();
280     return result;
281   }
282 
GetDeviceStateList()283   std::vector<mojom::DeviceStatePropertiesPtr> GetDeviceStateList() {
284     std::vector<mojom::DeviceStatePropertiesPtr> result;
285     base::RunLoop run_loop;
286     cros_network_config()->GetDeviceStateList(base::BindOnce(
287         [](std::vector<mojom::DeviceStatePropertiesPtr>* result,
288            base::OnceClosure quit_closure,
289            std::vector<mojom::DeviceStatePropertiesPtr> devices) {
290           for (auto& device : devices)
291             result->push_back(std::move(device));
292           std::move(quit_closure).Run();
293         },
294         &result, run_loop.QuitClosure()));
295     run_loop.Run();
296     return result;
297   }
298 
GetDeviceStateFromList(mojom::NetworkType type)299   mojom::DeviceStatePropertiesPtr GetDeviceStateFromList(
300       mojom::NetworkType type) {
301     std::vector<mojom::DeviceStatePropertiesPtr> devices = GetDeviceStateList();
302     for (auto& device : devices) {
303       if (device->type == type)
304         return std::move(device);
305     }
306     return nullptr;
307   }
308 
GetManagedProperties(const std::string & guid)309   mojom::ManagedPropertiesPtr GetManagedProperties(const std::string& guid) {
310     mojom::ManagedPropertiesPtr result;
311     base::RunLoop run_loop;
312     cros_network_config()->GetManagedProperties(
313         guid, base::BindOnce(
314                   [](mojom::ManagedPropertiesPtr* result,
315                      base::OnceClosure quit_closure,
316                      mojom::ManagedPropertiesPtr properties) {
317                     *result = std::move(properties);
318                     std::move(quit_closure).Run();
319                   },
320                   &result, run_loop.QuitClosure()));
321     run_loop.Run();
322     return result;
323   }
324 
SetProperties(const std::string & guid,mojom::ConfigPropertiesPtr properties)325   bool SetProperties(const std::string& guid,
326                      mojom::ConfigPropertiesPtr properties) {
327     bool success = false;
328     base::RunLoop run_loop;
329     cros_network_config()->SetProperties(
330         guid, std::move(properties),
331         base::BindOnce(
332             [](bool* successp, base::OnceClosure quit_closure, bool success,
333                const std::string& message) {
334               *successp = success;
335               std::move(quit_closure).Run();
336             },
337             &success, run_loop.QuitClosure()));
338     run_loop.Run();
339     return success;
340   }
341 
ConfigureNetwork(mojom::ConfigPropertiesPtr properties,bool shared)342   std::string ConfigureNetwork(mojom::ConfigPropertiesPtr properties,
343                                bool shared) {
344     std::string guid;
345     base::RunLoop run_loop;
346     cros_network_config()->ConfigureNetwork(
347         std::move(properties), shared,
348         base::BindOnce(
349             [](std::string* guidp, base::OnceClosure quit_closure,
350                const base::Optional<std::string>& guid,
351                const std::string& message) {
352               if (guid)
353                 *guidp = *guid;
354               std::move(quit_closure).Run();
355             },
356             &guid, run_loop.QuitClosure()));
357     run_loop.Run();
358     return guid;
359   }
360 
ForgetNetwork(const std::string & guid)361   bool ForgetNetwork(const std::string& guid) {
362     bool success = false;
363     base::RunLoop run_loop;
364     cros_network_config()->ForgetNetwork(
365         guid,
366         base::BindOnce(
367             [](bool* successp, base::OnceClosure quit_closure, bool success) {
368               *successp = success;
369               std::move(quit_closure).Run();
370             },
371             &success, run_loop.QuitClosure()));
372     run_loop.Run();
373     return success;
374   }
375 
SetCellularSimState(const std::string & current_pin_or_puk,base::Optional<std::string> new_pin,bool require_pin)376   bool SetCellularSimState(const std::string& current_pin_or_puk,
377                            base::Optional<std::string> new_pin,
378                            bool require_pin) {
379     bool success = false;
380     base::RunLoop run_loop;
381     cros_network_config()->SetCellularSimState(
382         mojom::CellularSimState::New(current_pin_or_puk, new_pin, require_pin),
383         base::BindOnce(
384             [](bool* successp, base::OnceClosure quit_closure, bool success) {
385               *successp = success;
386               std::move(quit_closure).Run();
387             },
388             &success, run_loop.QuitClosure()));
389     run_loop.Run();
390     return success;
391   }
392 
SelectCellularMobileNetwork(const std::string & guid,const std::string & network_id)393   bool SelectCellularMobileNetwork(const std::string& guid,
394                                    const std::string& network_id) {
395     bool success = false;
396     base::RunLoop run_loop;
397     cros_network_config()->SelectCellularMobileNetwork(
398         guid, network_id,
399         base::BindOnce(
400             [](bool* successp, base::OnceClosure quit_closure, bool success) {
401               *successp = success;
402               std::move(quit_closure).Run();
403             },
404             &success, run_loop.QuitClosure()));
405     run_loop.Run();
406     return success;
407   }
408 
GetGlobalPolicy()409   mojom::GlobalPolicyPtr GetGlobalPolicy() {
410     mojom::GlobalPolicyPtr result;
411     base::RunLoop run_loop;
412     cros_network_config()->GetGlobalPolicy(base::BindOnce(
413         [](mojom::GlobalPolicyPtr* result, base::OnceClosure quit_closure,
414            mojom::GlobalPolicyPtr global_policy) {
415           *result = std::move(global_policy);
416           std::move(quit_closure).Run();
417         },
418         &result, run_loop.QuitClosure()));
419     run_loop.Run();
420     return result;
421   }
422 
StartConnect(const std::string & guid)423   mojom::StartConnectResult StartConnect(const std::string& guid) {
424     mojom::StartConnectResult result;
425     base::RunLoop run_loop;
426     cros_network_config()->StartConnect(
427         guid,
428         base::BindOnce(
429             [](mojom::StartConnectResult* resultp,
430                base::OnceClosure quit_closure, mojom::StartConnectResult result,
431                const std::string& message) {
432               *resultp = result;
433               std::move(quit_closure).Run();
434             },
435             &result, run_loop.QuitClosure()));
436     run_loop.Run();
437     return result;
438   }
439 
StartDisconnect(const std::string & guid)440   bool StartDisconnect(const std::string& guid) {
441     bool success = false;
442     base::RunLoop run_loop;
443     cros_network_config()->StartDisconnect(
444         guid,
445         base::BindOnce(
446             [](bool* successp, base::OnceClosure quit_closure, bool success) {
447               *successp = success;
448               std::move(quit_closure).Run();
449             },
450             &success, run_loop.QuitClosure()));
451     run_loop.Run();
452     return success;
453   }
454 
GetVpnProviders()455   std::vector<mojom::VpnProviderPtr> GetVpnProviders() {
456     std::vector<mojom::VpnProviderPtr> result;
457     base::RunLoop run_loop;
458     cros_network_config()->GetVpnProviders(base::BindOnce(
459         [](std::vector<mojom::VpnProviderPtr>* result,
460            base::OnceClosure quit_closure,
461            std::vector<mojom::VpnProviderPtr> providers) {
462           *result = std::move(providers);
463           std::move(quit_closure).Run();
464         },
465         &result, run_loop.QuitClosure()));
466     run_loop.Run();
467     return result;
468   }
469 
GetNetworkCertificates(std::vector<mojom::NetworkCertificatePtr> * server_cas,std::vector<mojom::NetworkCertificatePtr> * user_certs)470   void GetNetworkCertificates(
471       std::vector<mojom::NetworkCertificatePtr>* server_cas,
472       std::vector<mojom::NetworkCertificatePtr>* user_certs) {
473     base::RunLoop run_loop;
474     cros_network_config()->GetNetworkCertificates(base::BindOnce(
475         [](std::vector<mojom::NetworkCertificatePtr>* server_cas_result,
476            std::vector<mojom::NetworkCertificatePtr>* user_certs_result,
477            base::OnceClosure quit_closure,
478            std::vector<mojom::NetworkCertificatePtr> server_cas,
479            std::vector<mojom::NetworkCertificatePtr> user_certs) {
480           *server_cas_result = std::move(server_cas);
481           *user_certs_result = std::move(user_certs);
482           std::move(quit_closure).Run();
483         },
484         server_cas, user_certs, run_loop.QuitClosure()));
485     run_loop.Run();
486   }
487 
helper()488   NetworkStateTestHelper& helper() { return helper_; }
observer()489   CrosNetworkConfigTestObserver* observer() { return observer_.get(); }
cros_network_config()490   CrosNetworkConfig* cros_network_config() {
491     return cros_network_config_.get();
492   }
managed_network_configuration_handler()493   ManagedNetworkConfigurationHandler* managed_network_configuration_handler() {
494     return managed_network_configuration_handler_.get();
495   }
network_certificate_handler()496   NetworkCertificateHandler* network_certificate_handler() {
497     return network_certificate_handler_.get();
498   }
wifi1_path()499   std::string wifi1_path() { return wifi1_path_; }
500 
501  protected:
502   sync_preferences::TestingPrefServiceSyncable user_prefs_;
503 
504  private:
505   base::test::SingleThreadTaskEnvironment task_environment_;
506   NetworkStateTestHelper helper_{false /* use_default_devices_and_services */};
507   std::unique_ptr<NetworkCertificateHandler> network_certificate_handler_;
508   std::unique_ptr<NetworkProfileHandler> network_profile_handler_;
509   std::unique_ptr<NetworkDeviceHandler> network_device_handler_;
510   std::unique_ptr<NetworkConfigurationHandler> network_configuration_handler_;
511   std::unique_ptr<ManagedNetworkConfigurationHandler>
512       managed_network_configuration_handler_;
513   std::unique_ptr<NetworkConnectionHandler> network_connection_handler_;
514   std::unique_ptr<chromeos::UIProxyConfigService> ui_proxy_config_service_;
515   TestingPrefServiceSimple local_state_;
516   std::unique_ptr<CrosNetworkConfig> cros_network_config_;
517   std::unique_ptr<CrosNetworkConfigTestObserver> observer_;
518   std::string wifi1_path_;
519 
520   DISALLOW_COPY_AND_ASSIGN(CrosNetworkConfigTest);
521 };
522 
TEST_F(CrosNetworkConfigTest,GetNetworkState)523 TEST_F(CrosNetworkConfigTest, GetNetworkState) {
524   mojom::NetworkStatePropertiesPtr network = GetNetworkState("eth_guid");
525   ASSERT_TRUE(network);
526   EXPECT_EQ("eth_guid", network->guid);
527   EXPECT_EQ(mojom::NetworkType::kEthernet, network->type);
528   EXPECT_EQ(mojom::ConnectionStateType::kOnline, network->connection_state);
529   EXPECT_EQ(mojom::OncSource::kNone, network->source);
530 
531   network = GetNetworkState("wifi1_guid");
532   ASSERT_TRUE(network);
533   EXPECT_EQ("wifi1_guid", network->guid);
534   EXPECT_EQ(mojom::NetworkType::kWiFi, network->type);
535   EXPECT_EQ(mojom::ConnectionStateType::kConnected, network->connection_state);
536   ASSERT_TRUE(network->type_state);
537   ASSERT_TRUE(network->type_state->is_wifi());
538   EXPECT_EQ(mojom::SecurityType::kNone,
539             network->type_state->get_wifi()->security);
540   EXPECT_EQ(50, network->type_state->get_wifi()->signal_strength);
541   EXPECT_EQ(mojom::OncSource::kNone, network->source);
542 
543   network = GetNetworkState("wifi2_guid");
544   ASSERT_TRUE(network);
545   EXPECT_EQ("wifi2_guid", network->guid);
546   EXPECT_EQ(mojom::NetworkType::kWiFi, network->type);
547   EXPECT_EQ(mojom::ConnectionStateType::kNotConnected,
548             network->connection_state);
549   ASSERT_TRUE(network->type_state);
550   ASSERT_TRUE(network->type_state->is_wifi());
551   EXPECT_EQ(mojom::SecurityType::kWpaPsk,
552             network->type_state->get_wifi()->security);
553   EXPECT_EQ(100, network->type_state->get_wifi()->signal_strength);
554   EXPECT_EQ(mojom::OncSource::kUserPolicy, network->source);
555 
556   network = GetNetworkState("wifi3_guid");
557   ASSERT_TRUE(network);
558   EXPECT_EQ("wifi3_guid", network->guid);
559   EXPECT_EQ(mojom::NetworkType::kWiFi, network->type);
560   EXPECT_EQ(mojom::ConnectionStateType::kNotConnected,
561             network->connection_state);
562   ASSERT_TRUE(network->type_state);
563   ASSERT_TRUE(network->type_state->is_wifi());
564   EXPECT_EQ(mojom::SecurityType::kWpaPsk,
565             network->type_state->get_wifi()->security);
566   EXPECT_EQ(0, network->type_state->get_wifi()->signal_strength);
567   EXPECT_EQ(mojom::OncSource::kDevice, network->source);
568 
569   network = GetNetworkState("cellular_guid");
570   ASSERT_TRUE(network);
571   EXPECT_EQ("cellular_guid", network->guid);
572   EXPECT_EQ(mojom::NetworkType::kCellular, network->type);
573   EXPECT_EQ(mojom::ConnectionStateType::kNotConnected,
574             network->connection_state);
575   ASSERT_TRUE(network->type_state);
576   ASSERT_TRUE(network->type_state->is_cellular());
577   mojom::CellularStatePropertiesPtr& cellular =
578       network->type_state->get_cellular();
579   EXPECT_EQ(0, cellular->signal_strength);
580   EXPECT_EQ("LTE", cellular->network_technology);
581   EXPECT_EQ(mojom::ActivationStateType::kActivated, cellular->activation_state);
582   EXPECT_EQ(mojom::OncSource::kDevice, network->source);
583   EXPECT_TRUE(cellular->sim_locked);
584 
585   network = GetNetworkState("vpn_guid");
586   ASSERT_TRUE(network);
587   EXPECT_EQ("vpn_guid", network->guid);
588   EXPECT_EQ(mojom::NetworkType::kVPN, network->type);
589   EXPECT_EQ(mojom::ConnectionStateType::kConnecting, network->connection_state);
590   ASSERT_TRUE(network->type_state);
591   ASSERT_TRUE(network->type_state->is_vpn());
592   EXPECT_EQ(mojom::VpnType::kL2TPIPsec, network->type_state->get_vpn()->type);
593   EXPECT_EQ(mojom::OncSource::kNone, network->source);
594 
595   // TODO(919691): Test ProxyMode once UIProxyConfigService logic is improved.
596 }
597 
TEST_F(CrosNetworkConfigTest,GetNetworkStateList)598 TEST_F(CrosNetworkConfigTest, GetNetworkStateList) {
599   mojom::NetworkFilterPtr filter = mojom::NetworkFilter::New();
600   // All active networks
601   filter->filter = mojom::FilterType::kActive;
602   filter->network_type = mojom::NetworkType::kAll;
603   filter->limit = mojom::kNoLimit;
604   std::vector<mojom::NetworkStatePropertiesPtr> networks =
605       GetNetworkStateList(filter.Clone());
606   ASSERT_EQ(3u, networks.size());
607   EXPECT_EQ("eth_guid", networks[0]->guid);
608   EXPECT_EQ("wifi1_guid", networks[1]->guid);
609   EXPECT_EQ("vpn_guid", networks[2]->guid);
610 
611   // First active network
612   filter->limit = 1;
613   networks = GetNetworkStateList(filter.Clone());
614   ASSERT_EQ(1u, networks.size());
615   EXPECT_EQ("eth_guid", networks[0]->guid);
616 
617   // All wifi networks
618   filter->filter = mojom::FilterType::kAll;
619   filter->network_type = mojom::NetworkType::kWiFi;
620   filter->limit = mojom::kNoLimit;
621   networks = GetNetworkStateList(filter.Clone());
622   ASSERT_EQ(4u, networks.size());
623   EXPECT_EQ("wifi1_guid", networks[0]->guid);
624   EXPECT_EQ("wifi2_guid", networks[1]->guid);
625   EXPECT_EQ("wifi4_guid", networks[2]->guid);
626   EXPECT_EQ("wifi3_guid", networks[3]->guid);
627 
628   // Visible wifi networks
629   filter->filter = mojom::FilterType::kVisible;
630   networks = GetNetworkStateList(filter.Clone());
631   ASSERT_EQ(3u, networks.size());
632   EXPECT_EQ("wifi1_guid", networks[0]->guid);
633   EXPECT_EQ("wifi2_guid", networks[1]->guid);
634   EXPECT_EQ("wifi4_guid", networks[2]->guid);
635 
636   // Configured wifi networks
637   filter->filter = mojom::FilterType::kConfigured;
638   networks = GetNetworkStateList(filter.Clone());
639   ASSERT_EQ(3u, networks.size());
640   EXPECT_EQ("wifi2_guid", networks[0]->guid);
641   EXPECT_EQ("wifi4_guid", networks[1]->guid);
642   EXPECT_EQ("wifi3_guid", networks[2]->guid);
643 }
644 
TEST_F(CrosNetworkConfigTest,GetDeviceStateList)645 TEST_F(CrosNetworkConfigTest, GetDeviceStateList) {
646   std::vector<mojom::DeviceStatePropertiesPtr> devices = GetDeviceStateList();
647   ASSERT_EQ(4u, devices.size());
648   EXPECT_EQ(mojom::NetworkType::kWiFi, devices[0]->type);
649   EXPECT_EQ(mojom::DeviceStateType::kEnabled, devices[0]->device_state);
650 
651   // IP address match those set up in FakeShillManagerClient::
652   // SetupDefaultEnvironment(). TODO(stevenjb): Support setting
653   // expectations explicitly in NetworkStateTestHelper.
654   net::IPAddress ipv4_expected;
655   ASSERT_TRUE(ipv4_expected.AssignFromIPLiteral("100.0.0.1"));
656   EXPECT_EQ(ipv4_expected, devices[0]->ipv4_address);
657   net::IPAddress ipv6_expected;
658   ASSERT_TRUE(ipv6_expected.AssignFromIPLiteral("0:0:0:0:100:0:0:1"));
659   EXPECT_EQ(ipv6_expected, devices[0]->ipv6_address);
660 
661   EXPECT_EQ(mojom::NetworkType::kEthernet, devices[1]->type);
662   EXPECT_EQ(mojom::DeviceStateType::kEnabled, devices[1]->device_state);
663 
664   mojom::DeviceStateProperties* cellular = devices[2].get();
665   EXPECT_EQ(mojom::NetworkType::kCellular, cellular->type);
666   EXPECT_EQ(mojom::DeviceStateType::kEnabled, cellular->device_state);
667   EXPECT_FALSE(cellular->sim_absent);
668   ASSERT_TRUE(cellular->sim_lock_status);
669   EXPECT_TRUE(cellular->sim_lock_status->lock_enabled);
670   EXPECT_EQ(shill::kSIMLockPin, cellular->sim_lock_status->lock_type);
671   EXPECT_EQ(3, cellular->sim_lock_status->retries_left);
672 
673   mojom::DeviceStateProperties* vpn = devices[3].get();
674   EXPECT_EQ(mojom::NetworkType::kVPN, vpn->type);
675   EXPECT_EQ(mojom::DeviceStateType::kEnabled, vpn->device_state);
676 
677   // Disable WiFi
678   helper().network_state_handler()->SetTechnologyEnabled(
679       NetworkTypePattern::WiFi(), false, network_handler::ErrorCallback());
680   base::RunLoop().RunUntilIdle();
681   devices = GetDeviceStateList();
682   ASSERT_EQ(4u, devices.size());
683   EXPECT_EQ(mojom::NetworkType::kWiFi, devices[0]->type);
684   EXPECT_EQ(mojom::DeviceStateType::kDisabled, devices[0]->device_state);
685 }
686 
687 // Test a sampling of properties, ensuring that string property types are
688 // translated as strings and not enum values (See ManagedProperties definition
689 // in cros_network_config.mojom for details).
TEST_F(CrosNetworkConfigTest,GetManagedProperties)690 TEST_F(CrosNetworkConfigTest, GetManagedProperties) {
691   mojom::ManagedPropertiesPtr properties = GetManagedProperties("eth_guid");
692   ASSERT_TRUE(properties);
693   EXPECT_EQ("eth_guid", properties->guid);
694   EXPECT_EQ(mojom::NetworkType::kEthernet, properties->type);
695   EXPECT_EQ(mojom::ConnectionStateType::kOnline, properties->connection_state);
696 
697   properties = GetManagedProperties("wifi1_guid");
698   ASSERT_TRUE(properties);
699   EXPECT_EQ("wifi1_guid", properties->guid);
700   EXPECT_EQ(mojom::NetworkType::kWiFi, properties->type);
701   EXPECT_EQ(mojom::ConnectionStateType::kConnected,
702             properties->connection_state);
703   ASSERT_TRUE(properties->type_properties);
704   ASSERT_TRUE(properties->type_properties->is_wifi());
705   EXPECT_EQ(50, properties->type_properties->get_wifi()->signal_strength);
706   EXPECT_EQ(mojom::OncSource::kNone, properties->source);
707   EXPECT_EQ(false, properties->type_properties->get_wifi()->is_syncable);
708 
709   properties = GetManagedProperties("wifi2_guid");
710   ASSERT_TRUE(properties);
711   EXPECT_EQ("wifi2_guid", properties->guid);
712   EXPECT_EQ(mojom::NetworkType::kWiFi, properties->type);
713   EXPECT_EQ(mojom::ConnectionStateType::kNotConnected,
714             properties->connection_state);
715   ASSERT_TRUE(properties->type_properties);
716   mojom::ManagedWiFiPropertiesPtr& wifi =
717       properties->type_properties->get_wifi();
718   ASSERT_TRUE(wifi);
719   EXPECT_EQ(mojom::SecurityType::kWpaPsk, wifi->security);
720   EXPECT_EQ(100, wifi->signal_strength);
721   EXPECT_EQ(mojom::OncSource::kUserPolicy, properties->source);
722   EXPECT_EQ(false, properties->type_properties->get_wifi()->is_syncable);
723 
724   properties = GetManagedProperties("wifi3_guid");
725   ASSERT_TRUE(properties);
726   EXPECT_EQ("wifi3_guid", properties->guid);
727   EXPECT_EQ(mojom::NetworkType::kWiFi, properties->type);
728   EXPECT_EQ(mojom::ConnectionStateType::kNotConnected,
729             properties->connection_state);
730   EXPECT_EQ(mojom::OncSource::kDevice, properties->source);
731   EXPECT_EQ(false, properties->type_properties->get_wifi()->is_syncable);
732 
733   properties = GetManagedProperties("wifi4_guid");
734   ASSERT_TRUE(properties);
735   EXPECT_EQ("wifi4_guid", properties->guid);
736   EXPECT_EQ(mojom::NetworkType::kWiFi, properties->type);
737   EXPECT_EQ(mojom::ConnectionStateType::kNotConnected,
738             properties->connection_state);
739   EXPECT_EQ(mojom::OncSource::kUser, properties->source);
740   EXPECT_EQ(true, properties->type_properties->get_wifi()->is_syncable);
741 
742   properties = GetManagedProperties("cellular_guid");
743   ASSERT_TRUE(properties);
744   EXPECT_EQ("cellular_guid", properties->guid);
745   EXPECT_EQ(mojom::NetworkType::kCellular, properties->type);
746   EXPECT_EQ(mojom::ConnectionStateType::kNotConnected,
747             properties->connection_state);
748   ASSERT_TRUE(properties->type_properties);
749   mojom::ManagedCellularPropertiesPtr& cellular =
750       properties->type_properties->get_cellular();
751   ASSERT_TRUE(cellular);
752   EXPECT_EQ(0, cellular->signal_strength);
753   EXPECT_EQ("LTE", cellular->network_technology);
754   EXPECT_EQ(mojom::ActivationStateType::kActivated, cellular->activation_state);
755 
756   properties = GetManagedProperties("vpn_guid");
757   ASSERT_TRUE(properties);
758   EXPECT_EQ("vpn_guid", properties->guid);
759   EXPECT_EQ(mojom::NetworkType::kVPN, properties->type);
760   EXPECT_EQ(mojom::ConnectionStateType::kConnecting,
761             properties->connection_state);
762   ASSERT_TRUE(properties->type_properties);
763   ASSERT_TRUE(properties->type_properties->is_vpn());
764   EXPECT_EQ(mojom::VpnType::kL2TPIPsec,
765             properties->type_properties->get_vpn()->type);
766 }
767 
768 // Test managed property policy values.
TEST_F(CrosNetworkConfigTest,GetManagedPropertiesPolicy)769 TEST_F(CrosNetworkConfigTest, GetManagedPropertiesPolicy) {
770   mojom::ManagedPropertiesPtr properties = GetManagedProperties("wifi1_guid");
771   ASSERT_TRUE(properties);
772   ASSERT_EQ("wifi1_guid", properties->guid);
773   ASSERT_TRUE(properties->type_properties);
774   mojom::ManagedWiFiProperties* wifi =
775       properties->type_properties->get_wifi().get();
776   ASSERT_TRUE(wifi);
777   ASSERT_TRUE(wifi->auto_connect);
778   EXPECT_TRUE(wifi->auto_connect->active_value);
779   EXPECT_EQ(mojom::PolicySource::kNone, wifi->auto_connect->policy_source);
780 
781   properties = GetManagedProperties("wifi2_guid");
782   ASSERT_TRUE(properties);
783   ASSERT_EQ("wifi2_guid", properties->guid);
784   ASSERT_TRUE(properties->type_properties);
785   wifi = properties->type_properties->get_wifi().get();
786   ASSERT_TRUE(wifi);
787   ASSERT_TRUE(wifi->auto_connect);
788   EXPECT_TRUE(wifi->auto_connect->active_value);
789   EXPECT_EQ(mojom::PolicySource::kUserPolicyEnforced,
790             wifi->auto_connect->policy_source);
791   EXPECT_TRUE(wifi->auto_connect->policy_value);
792   ASSERT_TRUE(properties->name);
793   EXPECT_EQ("wifi2", properties->name->active_value);
794   EXPECT_EQ(mojom::PolicySource::kUserPolicyEnforced,
795             properties->name->policy_source);
796   EXPECT_EQ("wifi2", properties->name->policy_value);
797   ASSERT_TRUE(properties->priority);
798   EXPECT_EQ(0, properties->priority->active_value);
799   EXPECT_EQ(mojom::PolicySource::kUserPolicyEnforced,
800             properties->priority->policy_source);
801   EXPECT_EQ(0, properties->priority->policy_value);
802 }
803 
804 // Test managed EAP properties which are merged from a separate EthernetEAP
805 // Shill service.
TEST_F(CrosNetworkConfigTest,GetManagedPropertiesEAP)806 TEST_F(CrosNetworkConfigTest, GetManagedPropertiesEAP) {
807   SetupEthernetEAP();
808   mojom::ManagedPropertiesPtr properties = GetManagedProperties("eth_guid");
809   ASSERT_TRUE(properties);
810   EXPECT_EQ("eth_guid", properties->guid);
811   EXPECT_EQ(mojom::NetworkType::kEthernet, properties->type);
812   ASSERT_TRUE(properties->type_properties);
813   mojom::ManagedEthernetProperties* ethernet =
814       properties->type_properties->get_ethernet().get();
815   ASSERT_TRUE(ethernet);
816   ASSERT_TRUE(ethernet->authentication);
817   EXPECT_EQ("8021X", ethernet->authentication->active_value);
818   ASSERT_TRUE(ethernet->eap);
819   ASSERT_TRUE(ethernet->eap->identity);
820   EXPECT_EQ("user1", ethernet->eap->identity->active_value);
821 }
822 
TEST_F(CrosNetworkConfigTest,SetProperties)823 TEST_F(CrosNetworkConfigTest, SetProperties) {
824   // Use wifi3 since it has a profile path (i.e. it is 'saved'). and is not
825   // policy controoled.
826   const char* kGUID = "wifi3_guid";
827   // Assert initial state.
828   mojom::ManagedPropertiesPtr properties = GetManagedProperties(kGUID);
829   ASSERT_TRUE(properties);
830   ASSERT_EQ(kGUID, properties->guid);
831   ASSERT_TRUE(properties->type_properties);
832   mojom::ManagedWiFiProperties* wifi =
833       properties->type_properties->get_wifi().get();
834   ASSERT_TRUE(wifi);
835   ASSERT_FALSE(wifi->auto_connect);
836   ASSERT_FALSE(properties->priority);
837 
838   // Set priority.
839   auto config = mojom::ConfigProperties::New();
840   config->type_config = mojom::NetworkTypeConfigProperties::NewWifi(
841       mojom::WiFiConfigProperties::New());
842   config->priority = mojom::PriorityConfig::New();
843   config->priority->value = 1;
844   bool success = SetProperties(kGUID, std::move(config));
845   ASSERT_TRUE(success);
846   properties = GetManagedProperties(kGUID);
847   ASSERT_TRUE(properties);
848   ASSERT_EQ(kGUID, properties->guid);
849   ASSERT_TRUE(properties->type_properties);
850   wifi = properties->type_properties->get_wifi().get();
851   ASSERT_TRUE(wifi);
852   ASSERT_FALSE(wifi->auto_connect);
853   ASSERT_TRUE(properties->priority);
854   EXPECT_EQ(1, properties->priority->active_value);
855 
856   // Set auto connect only. Priority should remain unchanged. Also provide a
857   // matching |guid|.
858   config = mojom::ConfigProperties::New();
859   config->type_config = mojom::NetworkTypeConfigProperties::NewWifi(
860       mojom::WiFiConfigProperties::New());
861   config->auto_connect = mojom::AutoConnectConfig::New();
862   config->auto_connect->value = true;
863   config->guid = kGUID;
864   success = SetProperties(kGUID, std::move(config));
865   ASSERT_TRUE(success);
866   properties = GetManagedProperties(kGUID);
867   ASSERT_TRUE(properties);
868   ASSERT_EQ(kGUID, properties->guid);
869   ASSERT_TRUE(properties->type_properties);
870   wifi = properties->type_properties->get_wifi().get();
871   ASSERT_TRUE(wifi);
872   ASSERT_TRUE(wifi->auto_connect);
873   EXPECT_TRUE(wifi->auto_connect->active_value);
874   ASSERT_TRUE(properties->priority);
875   EXPECT_EQ(1, properties->priority->active_value);
876 
877   // Set auto connect with a mismatched guid; call should fail.
878   config = mojom::ConfigProperties::New();
879   config->type_config = mojom::NetworkTypeConfigProperties::NewWifi(
880       mojom::WiFiConfigProperties::New());
881   config->auto_connect = mojom::AutoConnectConfig::New();
882   config->auto_connect->value = false;
883   config->guid = "Mismatched guid";
884   success = SetProperties(kGUID, std::move(config));
885   EXPECT_FALSE(success);
886 }
887 
TEST_F(CrosNetworkConfigTest,CustomAPN)888 TEST_F(CrosNetworkConfigTest, CustomAPN) {
889   SetupAPNList();
890   const char* kGUID = "cellular_guid";
891   // Verify that setting APN to an entry that already exists in apn list
892   // does not update the custom apn list.
893   auto config = mojom::ConfigProperties::New();
894   auto cellular_config = mojom::CellularConfigProperties::New();
895   auto new_apn = mojom::ApnProperties::New();
896   new_apn->access_point_name = kCellularTestApn1;
897   new_apn->name = kCellularTestApnName1;
898   new_apn->username = kCellularTestApnUsername1;
899   new_apn->password = kCellularTestApnPassword1;
900   cellular_config->apn = std::move(new_apn);
901   config->type_config = mojom::NetworkTypeConfigProperties::NewCellular(
902       std::move(cellular_config));
903   SetProperties(kGUID, std::move(config));
904   const base::Value* apn_list =
905       NetworkHandler::Get()->network_metadata_store()->GetCustomAPNList(kGUID);
906   ASSERT_FALSE(apn_list);
907 
908   // Verify that custom APN list is updated properly.
909   config = mojom::ConfigProperties::New();
910   cellular_config = mojom::CellularConfigProperties::New();
911   new_apn = mojom::ApnProperties::New();
912   new_apn->access_point_name = kCellularTestApn3;
913   new_apn->name = kCellularTestApnName3;
914   new_apn->username = kCellularTestApnUsername3;
915   new_apn->password = kCellularTestApnPassword3;
916   cellular_config->apn = std::move(new_apn);
917   config->type_config = mojom::NetworkTypeConfigProperties::NewCellular(
918       std::move(cellular_config));
919   SetProperties(kGUID, std::move(config));
920   apn_list =
921       NetworkHandler::Get()->network_metadata_store()->GetCustomAPNList(kGUID);
922   ASSERT_TRUE(apn_list);
923   ASSERT_TRUE(apn_list->is_list());
924 
925   // Verify that custom APN list is returned properly in managed properties.
926   mojom::ManagedPropertiesPtr properties = GetManagedProperties(kGUID);
927   ASSERT_TRUE(properties);
928   ASSERT_EQ(kGUID, properties->guid);
929   ASSERT_TRUE(properties->type_properties->is_cellular());
930   ASSERT_TRUE(
931       properties->type_properties->get_cellular()->custom_apn_list.has_value());
932   ASSERT_EQ(
933       1u, properties->type_properties->get_cellular()->custom_apn_list->size());
934   ASSERT_EQ(kCellularTestApn3, properties->type_properties->get_cellular()
935                                    ->custom_apn_list->front()
936                                    ->access_point_name);
937 }
938 
TEST_F(CrosNetworkConfigTest,ConfigureNetwork)939 TEST_F(CrosNetworkConfigTest, ConfigureNetwork) {
940   // Note: shared = false requires a UserManager instance.
941   bool shared = true;
942   const std::string ssid = "new_wifi_ssid";
943   // Configure a new wifi network.
944   auto config = mojom::ConfigProperties::New();
945   config->name = ssid;
946   auto wifi = mojom::WiFiConfigProperties::New();
947   wifi->ssid = ssid;
948   config->type_config =
949       mojom::NetworkTypeConfigProperties::NewWifi(std::move(wifi));
950   std::string guid = ConfigureNetwork(std::move(config), shared);
951   EXPECT_FALSE(guid.empty());
952 
953   // Verify the configuration.
954   mojom::NetworkStatePropertiesPtr network = GetNetworkState(guid);
955   ASSERT_TRUE(network);
956   EXPECT_EQ(guid, network->guid);
957   EXPECT_EQ(mojom::NetworkType::kWiFi, network->type);
958   EXPECT_EQ(mojom::OncSource::kDevice, network->source);
959   ASSERT_TRUE(network->type_state);
960   ASSERT_TRUE(network->type_state->is_wifi());
961   EXPECT_EQ(ssid, network->type_state->get_wifi()->ssid);
962 }
963 
TEST_F(CrosNetworkConfigTest,ConfigureNetworkExistingGuid)964 TEST_F(CrosNetworkConfigTest, ConfigureNetworkExistingGuid) {
965   // Note: shared = false requires a UserManager instance.
966   bool shared = true;
967   const std::string guid = "new_wifi_guid";
968   const std::string ssid = "new_wifi_ssid";
969   // Configure a new wifi network with an existing guid.
970   auto config = mojom::ConfigProperties::New();
971   config->guid = guid;
972   config->name = ssid;
973   auto wifi = mojom::WiFiConfigProperties::New();
974   wifi->ssid = ssid;
975   config->type_config =
976       mojom::NetworkTypeConfigProperties::NewWifi(std::move(wifi));
977   std::string config_guid = ConfigureNetwork(std::move(config), shared);
978   // The new guid should be the same as the existing guid.
979   EXPECT_EQ(config_guid, guid);
980 }
981 
TEST_F(CrosNetworkConfigTest,ForgetNetwork)982 TEST_F(CrosNetworkConfigTest, ForgetNetwork) {
983   // Use a non visible configured network.
984   const std::string kGUID = "wifi3_guid";
985 
986   // Verify the configuration exists.
987   mojom::ManagedPropertiesPtr properties = GetManagedProperties(kGUID);
988   ASSERT_TRUE(properties);
989   ASSERT_EQ(kGUID, properties->guid);
990 
991   // Forget the network and verify the configuration no longer exists.
992   bool result = ForgetNetwork(kGUID);
993   EXPECT_TRUE(result);
994   properties = GetManagedProperties(kGUID);
995   ASSERT_FALSE(properties);
996 }
997 
TEST_F(CrosNetworkConfigTest,SetNetworkTypeEnabledState)998 TEST_F(CrosNetworkConfigTest, SetNetworkTypeEnabledState) {
999   std::vector<mojom::DeviceStatePropertiesPtr> devices = GetDeviceStateList();
1000   ASSERT_EQ(4u, devices.size());
1001   EXPECT_EQ(mojom::NetworkType::kWiFi, devices[0]->type);
1002   EXPECT_EQ(mojom::DeviceStateType::kEnabled, devices[0]->device_state);
1003 
1004   // Disable WiFi
1005   bool succeeded = false;
1006   cros_network_config()->SetNetworkTypeEnabledState(
1007       mojom::NetworkType::kWiFi, false,
1008       base::BindOnce(
1009           [](bool* succeeded, bool success) { *succeeded = success; },
1010           &succeeded));
1011   // Wait for callback to complete; this test does not use mojo bindings.
1012   base::RunLoop().RunUntilIdle();
1013   EXPECT_TRUE(succeeded);
1014   devices = GetDeviceStateList();
1015   ASSERT_EQ(4u, devices.size());
1016   EXPECT_EQ(mojom::NetworkType::kWiFi, devices[0]->type);
1017   EXPECT_EQ(mojom::DeviceStateType::kDisabled, devices[0]->device_state);
1018 }
1019 
TEST_F(CrosNetworkConfigTest,SetCellularSimState)1020 TEST_F(CrosNetworkConfigTest, SetCellularSimState) {
1021   // Assert initial state.
1022   mojom::DeviceStatePropertiesPtr cellular =
1023       GetDeviceStateFromList(mojom::NetworkType::kCellular);
1024   ASSERT_TRUE(cellular);
1025   ASSERT_FALSE(cellular->sim_absent);
1026   ASSERT_TRUE(cellular->sim_lock_status);
1027   ASSERT_TRUE(cellular->sim_lock_status->lock_enabled);
1028   ASSERT_EQ(shill::kSIMLockPin, cellular->sim_lock_status->lock_type);
1029   const int retries = FakeShillDeviceClient::kSimPinRetryCount;
1030   ASSERT_EQ(retries, cellular->sim_lock_status->retries_left);
1031 
1032   // Unlock the sim with the correct pin. |require_pin| should be ignored.
1033   EXPECT_TRUE(SetCellularSimState(FakeShillDeviceClient::kDefaultSimPin,
1034                                   /*new_pin=*/base::nullopt,
1035                                   /*require_pin=*/false));
1036 
1037   // Sim should be unlocked, locking should still be enabled.
1038   cellular = GetDeviceStateFromList(mojom::NetworkType::kCellular);
1039   ASSERT_TRUE(cellular && cellular->sim_lock_status);
1040   EXPECT_TRUE(cellular->sim_lock_status->lock_enabled);
1041   EXPECT_TRUE(cellular->sim_lock_status->lock_type.empty());
1042 
1043   // Set |require_pin| to false (disable locking).
1044   EXPECT_TRUE(SetCellularSimState(FakeShillDeviceClient::kDefaultSimPin,
1045                                   /*new_pin=*/base::nullopt,
1046                                   /*require_pin=*/false));
1047 
1048   // Sim should be unlocked, locking should be disabled.
1049   cellular = GetDeviceStateFromList(mojom::NetworkType::kCellular);
1050   ASSERT_TRUE(cellular && cellular->sim_lock_status);
1051   EXPECT_FALSE(cellular->sim_lock_status->lock_enabled);
1052   EXPECT_TRUE(cellular->sim_lock_status->lock_type.empty());
1053 
1054   // Set |require_pin| to true (enable locking).
1055   EXPECT_TRUE(SetCellularSimState(FakeShillDeviceClient::kDefaultSimPin,
1056                                   /*new_pin=*/base::nullopt,
1057                                   /*require_pin=*/true));
1058 
1059   // Sim should remain unlocked, locking should be enabled.
1060   cellular = GetDeviceStateFromList(mojom::NetworkType::kCellular);
1061   ASSERT_TRUE(cellular && cellular->sim_lock_status);
1062   EXPECT_TRUE(cellular->sim_lock_status->lock_enabled);
1063   EXPECT_TRUE(cellular->sim_lock_status->lock_type.empty());
1064 
1065   // Lock the sim. (Can not be done via the mojo API).
1066   helper().device_test()->SetSimLocked(kCellularDevicePath, true);
1067   base::RunLoop().RunUntilIdle();
1068   cellular = GetDeviceStateFromList(mojom::NetworkType::kCellular);
1069   ASSERT_TRUE(cellular && cellular->sim_lock_status);
1070   ASSERT_TRUE(cellular->sim_lock_status->lock_enabled);
1071   ASSERT_EQ(shill::kSIMLockPin, cellular->sim_lock_status->lock_type);
1072 
1073   // Attempt to unlock the sim with an incorrect pin. Call should fail.
1074   EXPECT_FALSE(SetCellularSimState("incorrect pin", /*new_pin=*/base::nullopt,
1075                                    /*require_pin=*/false));
1076 
1077   // Ensure sim is still locked and retry count has decreased.
1078   cellular = GetDeviceStateFromList(mojom::NetworkType::kCellular);
1079   ASSERT_TRUE(cellular && cellular->sim_lock_status);
1080   EXPECT_TRUE(cellular->sim_lock_status->lock_enabled);
1081   EXPECT_EQ(shill::kSIMLockPin, cellular->sim_lock_status->lock_type);
1082   EXPECT_EQ(retries - 1, cellular->sim_lock_status->retries_left);
1083 
1084   // Additional attempts should set the sim to puk locked.
1085   for (int i = retries - 1; i > 0; --i) {
1086     SetCellularSimState("incorrect pin", /*new_pin=*/base::nullopt, false);
1087   }
1088   cellular = GetDeviceStateFromList(mojom::NetworkType::kCellular);
1089   ASSERT_TRUE(cellular && cellular->sim_lock_status);
1090   EXPECT_TRUE(cellular->sim_lock_status->lock_enabled);
1091   EXPECT_EQ(shill::kSIMLockPuk, cellular->sim_lock_status->lock_type);
1092 
1093   // Attempt to unblock the sim with the incorrect puk. Call should fail.
1094   const std::string new_pin = "2222";
1095   EXPECT_FALSE(SetCellularSimState("incorrect puk",
1096                                    base::make_optional(new_pin),
1097                                    /*require_pin=*/false));
1098 
1099   // Attempt to unblock the sim with np pin. Call should fail.
1100   EXPECT_FALSE(SetCellularSimState(FakeShillDeviceClient::kSimPuk,
1101                                    /*new_pin=*/base::nullopt,
1102                                    /*require_pin=*/false));
1103 
1104   // Attempt to unlock the sim with the correct puk.
1105   EXPECT_TRUE(SetCellularSimState(FakeShillDeviceClient::kSimPuk,
1106                                   base::make_optional(new_pin),
1107                                   /*require_pin=*/false));
1108 
1109   // Sim should be unlocked
1110   cellular = GetDeviceStateFromList(mojom::NetworkType::kCellular);
1111   ASSERT_TRUE(cellular && cellular->sim_lock_status);
1112   EXPECT_TRUE(cellular->sim_lock_status->lock_type.empty());
1113 }
1114 
TEST_F(CrosNetworkConfigTest,SelectCellularMobileNetwork)1115 TEST_F(CrosNetworkConfigTest, SelectCellularMobileNetwork) {
1116   // Create fake list of found networks.
1117   base::Optional<base::Value> found_networks_list =
1118       base::JSONReader::Read(base::StringPrintf(
1119           R"([{"network_id": "network1", "technology": "GSM",
1120                "status": "current"},
1121               {"network_id": "network2", "technology": "GSM",
1122                "status": "available"}])"));
1123   helper().device_test()->SetDeviceProperty(
1124       kCellularDevicePath, shill::kFoundNetworksProperty, *found_networks_list,
1125       /*notify_changed=*/true);
1126 
1127   // Assert initial state
1128   mojom::ManagedPropertiesPtr properties =
1129       GetManagedProperties("cellular_guid");
1130   mojom::ManagedCellularProperties* cellular =
1131       properties->type_properties->get_cellular().get();
1132   ASSERT_TRUE(cellular);
1133   ASSERT_TRUE(cellular->found_networks);
1134   const std::vector<mojom::FoundNetworkPropertiesPtr>& found_networks1 =
1135       *(cellular->found_networks);
1136   ASSERT_EQ(2u, found_networks1.size());
1137   EXPECT_EQ("current", found_networks1[0]->status);
1138   EXPECT_EQ("available", found_networks1[1]->status);
1139 
1140   // Select "network2"
1141   EXPECT_TRUE(SelectCellularMobileNetwork("cellular_guid", "network2"));
1142   properties = GetManagedProperties("cellular_guid");
1143   cellular = properties->type_properties->get_cellular().get();
1144   ASSERT_TRUE(cellular);
1145   ASSERT_TRUE(cellular->found_networks);
1146   const std::vector<mojom::FoundNetworkPropertiesPtr>& found_networks2 =
1147       *(cellular->found_networks);
1148   ASSERT_EQ(2u, found_networks2.size());
1149   EXPECT_EQ("available", found_networks2[0]->status);
1150   EXPECT_EQ("current", found_networks2[1]->status);
1151 }
1152 
TEST_F(CrosNetworkConfigTest,RequestNetworkScan)1153 TEST_F(CrosNetworkConfigTest, RequestNetworkScan) {
1154   // Observe device state list changes and track when the wifi scanning state
1155   // gets set to true. Note: In the test the scan will complete immediately and
1156   // the scanning state will get set back to false, so ignore that change.
1157   class ScanningObserver : public CrosNetworkConfigTestObserver {
1158    public:
1159     explicit ScanningObserver(CrosNetworkConfig* cros_network_config)
1160         : cros_network_config_(cros_network_config) {}
1161     void OnDeviceStateListChanged() override {
1162       cros_network_config_->GetDeviceStateList(base::BindOnce(
1163           [](bool* wifi_scanning,
1164              std::vector<mojom::DeviceStatePropertiesPtr> devices) {
1165             for (auto& device : devices) {
1166               if (device->type == mojom::NetworkType::kWiFi && device->scanning)
1167                 *wifi_scanning = true;
1168             }
1169           },
1170           &wifi_scanning_));
1171     }
1172     CrosNetworkConfig* cros_network_config_;
1173     bool wifi_scanning_ = false;
1174   };
1175   ScanningObserver observer(cros_network_config());
1176   cros_network_config()->AddObserver(observer.GenerateRemote());
1177   base::RunLoop().RunUntilIdle();
1178 
1179   cros_network_config()->RequestNetworkScan(mojom::NetworkType::kWiFi);
1180   base::RunLoop().RunUntilIdle();
1181   observer.FlushForTesting();
1182   EXPECT_TRUE(observer.wifi_scanning_);
1183 }
1184 
TEST_F(CrosNetworkConfigTest,GetGlobalPolicy)1185 TEST_F(CrosNetworkConfigTest, GetGlobalPolicy) {
1186   base::DictionaryValue global_config;
1187   global_config.SetBoolKey(
1188       ::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect,
1189       true);
1190   global_config.SetBoolKey(
1191       ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, false);
1192   base::Value blocked(base::Value::Type::LIST);
1193   blocked.Append(base::Value("blocked_ssid1"));
1194   blocked.Append(base::Value("blocked_ssid2"));
1195   global_config.SetKey(::onc::global_network_config::kBlockedHexSSIDs,
1196                        std::move(blocked));
1197   managed_network_configuration_handler()->SetPolicy(
1198       ::onc::ONC_SOURCE_DEVICE_POLICY, /*userhash=*/std::string(),
1199       base::ListValue(), global_config);
1200   base::RunLoop().RunUntilIdle();
1201   mojom::GlobalPolicyPtr policy = GetGlobalPolicy();
1202   ASSERT_TRUE(policy);
1203   EXPECT_EQ(true, policy->allow_only_policy_networks_to_autoconnect);
1204   EXPECT_EQ(false, policy->allow_only_policy_networks_to_connect);
1205   EXPECT_EQ(false, policy->allow_only_policy_networks_to_connect_if_available);
1206   ASSERT_EQ(2u, policy->blocked_hex_ssids.size());
1207   EXPECT_EQ("blocked_ssid1", policy->blocked_hex_ssids[0]);
1208   EXPECT_EQ("blocked_ssid2", policy->blocked_hex_ssids[1]);
1209 }
1210 
TEST_F(CrosNetworkConfigTest,StartConnect)1211 TEST_F(CrosNetworkConfigTest, StartConnect) {
1212   // wifi1 is already connected, StartConnect should fail.
1213   mojom::StartConnectResult result = StartConnect("wifi1_guid");
1214   EXPECT_EQ(mojom::StartConnectResult::kInvalidState, result);
1215 
1216   // wifi2 is not connected, StartConnect should succeed and connection_state
1217   // should change to connecting.
1218   mojom::NetworkStatePropertiesPtr network = GetNetworkState("wifi2_guid");
1219   ASSERT_TRUE(network);
1220   EXPECT_EQ(mojom::ConnectionStateType::kNotConnected,
1221             network->connection_state);
1222   result = StartConnect("wifi2_guid");
1223   EXPECT_EQ(mojom::StartConnectResult::kSuccess, result);
1224   network = GetNetworkState("wifi2_guid");
1225   EXPECT_EQ(mojom::ConnectionStateType::kConnecting, network->connection_state);
1226   // Wait for disconnect to complete.
1227   base::RunLoop().RunUntilIdle();
1228   network = GetNetworkState("wifi2_guid");
1229   EXPECT_EQ(mojom::ConnectionStateType::kOnline, network->connection_state);
1230 }
1231 
TEST_F(CrosNetworkConfigTest,StartDisconnect)1232 TEST_F(CrosNetworkConfigTest, StartDisconnect) {
1233   // wifi1 is connected, StartDisconnect should succeed and connection_state
1234   // should change to disconnected.
1235   mojom::NetworkStatePropertiesPtr network = GetNetworkState("wifi1_guid");
1236   ASSERT_TRUE(network);
1237   EXPECT_EQ(mojom::ConnectionStateType::kConnected, network->connection_state);
1238   bool success = StartDisconnect("wifi1_guid");
1239   EXPECT_TRUE(success);
1240   // Wait for disconnect to complete.
1241   base::RunLoop().RunUntilIdle();
1242   network = GetNetworkState("wifi1_guid");
1243   EXPECT_EQ(mojom::ConnectionStateType::kNotConnected,
1244             network->connection_state);
1245 
1246   // wifi1 is now disconnected, StartDisconnect should fail.
1247   success = StartDisconnect("wifi1_guid");
1248   EXPECT_FALSE(success);
1249 }
1250 
TEST_F(CrosNetworkConfigTest,VpnProviders)1251 TEST_F(CrosNetworkConfigTest, VpnProviders) {
1252   SetupObserver();
1253   ASSERT_EQ(0, observer()->vpn_providers_changed());
1254 
1255   mojom::VpnProvider provider1(mojom::VpnType::kExtension, "provider1",
1256                                "provider_name1", "", base::Time());
1257   mojom::VpnProvider provider2(mojom::VpnType::kArc, "provider2",
1258                                "provider_name2", "app2", base::Time());
1259   std::vector<mojom::VpnProviderPtr> providers;
1260   providers.push_back(provider1.Clone());
1261   providers.push_back(provider2.Clone());
1262   cros_network_config()->SetVpnProviders(std::move(providers));
1263 
1264   std::vector<mojom::VpnProviderPtr> providers_received = GetVpnProviders();
1265   ASSERT_EQ(2u, providers_received.size());
1266   EXPECT_TRUE(providers_received[0]->Equals(provider1));
1267   EXPECT_TRUE(providers_received[1]->Equals(provider2));
1268 
1269   base::RunLoop().RunUntilIdle();  // Ensure observers run.
1270   ASSERT_EQ(1, observer()->vpn_providers_changed());
1271 }
1272 
TEST_F(CrosNetworkConfigTest,NetworkCertificates)1273 TEST_F(CrosNetworkConfigTest, NetworkCertificates) {
1274   SetupObserver();
1275   ASSERT_EQ(0, observer()->network_certificates_changed());
1276 
1277   std::vector<mojom::NetworkCertificatePtr> server_cas;
1278   std::vector<mojom::NetworkCertificatePtr> user_certs;
1279   GetNetworkCertificates(&server_cas, &user_certs);
1280   EXPECT_EQ(0u, server_cas.size());
1281   EXPECT_EQ(0u, user_certs.size());
1282 
1283   network_certificate_handler()->AddAuthorityCertificateForTest(
1284       "authority_cert");
1285   base::RunLoop().RunUntilIdle();  // Ensure observers run.
1286   ASSERT_EQ(1, observer()->network_certificates_changed());
1287 
1288   GetNetworkCertificates(&server_cas, &user_certs);
1289   EXPECT_EQ(1u, server_cas.size());
1290   EXPECT_EQ(0u, user_certs.size());
1291 }
1292 
TEST_F(CrosNetworkConfigTest,NetworkListChanged)1293 TEST_F(CrosNetworkConfigTest, NetworkListChanged) {
1294   SetupObserver();
1295   base::RunLoop().RunUntilIdle();
1296   EXPECT_EQ(0, observer()->network_state_list_changed());
1297 
1298   // Add a wifi network.
1299   helper().ConfigureService(
1300       R"({"GUID": "wifi3_guid", "Type": "wifi", "State": "ready"})");
1301   base::RunLoop().RunUntilIdle();
1302   EXPECT_EQ(1, observer()->network_state_list_changed());
1303 }
1304 
TEST_F(CrosNetworkConfigTest,DeviceListChanged)1305 TEST_F(CrosNetworkConfigTest, DeviceListChanged) {
1306   SetupObserver();
1307   base::RunLoop().RunUntilIdle();
1308   EXPECT_EQ(0, observer()->device_state_list_changed());
1309 
1310   // Disable wifi
1311   helper().network_state_handler()->SetTechnologyEnabled(
1312       NetworkTypePattern::WiFi(), false, network_handler::ErrorCallback());
1313   base::RunLoop().RunUntilIdle();
1314   // This will trigger three device list updates. First when wifi is in the
1315   // disabling state, next when it's actually disabled, and lastly when
1316   // Device::available_managed_network_path_ changes.
1317   EXPECT_EQ(3, observer()->device_state_list_changed());
1318 
1319   // Enable Tethering
1320   helper().network_state_handler()->SetTetherTechnologyState(
1321       NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED);
1322   base::RunLoop().RunUntilIdle();
1323   EXPECT_EQ(4, observer()->device_state_list_changed());
1324 
1325   // Tests that observers are notified of device state list change
1326   // when a tether scan begins for a device.
1327   helper().network_state_handler()->SetTetherScanState(true);
1328   base::RunLoop().RunUntilIdle();
1329   EXPECT_EQ(5, observer()->device_state_list_changed());
1330 
1331   // Tests that observers are notified of device state list change
1332   // when a tether scan completes.
1333   helper().network_state_handler()->SetTetherScanState(false);
1334   base::RunLoop().RunUntilIdle();
1335   EXPECT_EQ(6, observer()->device_state_list_changed());
1336 }
1337 
TEST_F(CrosNetworkConfigTest,ActiveNetworksChanged)1338 TEST_F(CrosNetworkConfigTest, ActiveNetworksChanged) {
1339   SetupObserver();
1340   base::RunLoop().RunUntilIdle();
1341   EXPECT_EQ(0, observer()->active_networks_changed());
1342 
1343   // Change a network state.
1344   helper().SetServiceProperty(wifi1_path(), shill::kStateProperty,
1345                               base::Value(shill::kStateIdle));
1346   base::RunLoop().RunUntilIdle();
1347   EXPECT_EQ(1, observer()->active_networks_changed());
1348 }
1349 
TEST_F(CrosNetworkConfigTest,NetworkStateChanged)1350 TEST_F(CrosNetworkConfigTest, NetworkStateChanged) {
1351   SetupObserver();
1352   base::RunLoop().RunUntilIdle();
1353   EXPECT_EQ(0, observer()->GetNetworkChangedCount("wifi1_guid"));
1354   EXPECT_EQ(0, observer()->GetNetworkChangedCount("wifi2_guid"));
1355 
1356   // Change a network state.
1357   helper().SetServiceProperty(wifi1_path(), shill::kSignalStrengthProperty,
1358                               base::Value(10));
1359   base::RunLoop().RunUntilIdle();
1360   EXPECT_EQ(1, observer()->GetNetworkChangedCount("wifi1_guid"));
1361   EXPECT_EQ(0, observer()->GetNetworkChangedCount("wifi2_guid"));
1362 }
1363 
1364 // Do not forward information about proxies set by policy.
1365 // |NetworkStatePropertiesPtr::proxy_mode| is used to show a privacy warning in
1366 // the system tray. This warning should not be shown for managed networks.
TEST_F(CrosNetworkConfigTest,PolicyEnforcedProxyMode)1367 TEST_F(CrosNetworkConfigTest, PolicyEnforcedProxyMode) {
1368   // Proxies enforced by policy and/or extension are set in the kProxy
1369   // preference.
1370   base::Value policy_prefs_config = ProxyConfigDictionary::CreateAutoDetect();
1371   user_prefs_.SetUserPref(
1372       proxy_config::prefs::kProxy,
1373       base::Value::ToUniquePtrValue(std::move(policy_prefs_config)));
1374 
1375   mojom::NetworkStatePropertiesPtr network = GetNetworkState("wifi2_guid");
1376   ASSERT_TRUE(network);
1377   EXPECT_EQ(network->proxy_mode, mojom::ProxyMode::kDirect);
1378 }
1379 
1380 }  // namespace network_config
1381 }  // namespace chromeos
1382