1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <iostream>
6#include <sstream>
7
8#include "base/bind.h"
9#include "base/location.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/message_loop/message_loop.h"
12#include "base/stl_util.h"
13#include "base/values.h"
14#include "chromeos/dbus/dbus_thread_manager.h"
15#include "chromeos/dbus/mock_shill_manager_client.h"
16#include "chromeos/dbus/mock_shill_profile_client.h"
17#include "chromeos/dbus/mock_shill_service_client.h"
18#include "chromeos/dbus/shill_client_helper.h"
19#include "chromeos/network/managed_network_configuration_handler_impl.h"
20#include "chromeos/network/network_configuration_handler.h"
21#include "chromeos/network/network_profile_handler.h"
22#include "chromeos/network/onc/onc_test_utils.h"
23#include "chromeos/network/onc/onc_utils.h"
24#include "dbus/object_path.h"
25#include "testing/gmock/include/gmock/gmock.h"
26#include "testing/gtest/include/gtest/gtest.h"
27#include "third_party/cros_system_api/dbus/service_constants.h"
28
29using ::testing::AnyNumber;
30using ::testing::Invoke;
31using ::testing::Mock;
32using ::testing::Pointee;
33using ::testing::Return;
34using ::testing::SaveArg;
35using ::testing::StrEq;
36using ::testing::StrictMock;
37using ::testing::_;
38
39namespace test_utils = ::chromeos::onc::test_utils;
40
41namespace chromeos {
42
43namespace {
44
45std::string ValueToString(const base::Value* value) {
46  std::stringstream str;
47  str << *value;
48  return str.str();
49}
50
51const char kUser1[] = "user1";
52const char kUser1ProfilePath[] = "/profile/user1/shill";
53
54// Matcher to match base::Value.
55MATCHER_P(IsEqualTo,
56          value,
57          std::string(negation ? "isn't" : "is") + " equal to " +
58          ValueToString(value)) {
59  return value->Equals(&arg);
60}
61
62class ShillProfileTestClient {
63 public:
64  typedef ShillClientHelper::DictionaryValueCallbackWithoutStatus
65      DictionaryValueCallbackWithoutStatus;
66  typedef ShillClientHelper::ErrorCallback ErrorCallback;
67
68  void AddProfile(const std::string& profile_path,
69                  const std::string& userhash) {
70    if (profile_entries_.HasKey(profile_path))
71      return;
72
73    base::DictionaryValue* profile = new base::DictionaryValue;
74    profile_entries_.SetWithoutPathExpansion(profile_path, profile);
75    profile_to_user_[profile_path] = userhash;
76  }
77
78  void AddEntry(const std::string& profile_path,
79                const std::string& entry_path,
80                const base::DictionaryValue& entry) {
81    base::DictionaryValue* entries = NULL;
82    profile_entries_.GetDictionaryWithoutPathExpansion(profile_path, &entries);
83    ASSERT_TRUE(entries);
84
85    base::DictionaryValue* new_entry = entry.DeepCopy();
86    new_entry->SetStringWithoutPathExpansion(shill::kProfileProperty,
87                                             profile_path);
88    entries->SetWithoutPathExpansion(entry_path, new_entry);
89  }
90
91  void GetProperties(const dbus::ObjectPath& profile_path,
92                     const DictionaryValueCallbackWithoutStatus& callback,
93                     const ErrorCallback& error_callback) {
94    base::DictionaryValue* entries = NULL;
95    profile_entries_.GetDictionaryWithoutPathExpansion(profile_path.value(),
96                                                       &entries);
97    ASSERT_TRUE(entries);
98
99    scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
100    base::ListValue* entry_paths = new base::ListValue;
101    result->SetWithoutPathExpansion(shill::kEntriesProperty, entry_paths);
102    for (base::DictionaryValue::Iterator it(*entries); !it.IsAtEnd();
103         it.Advance()) {
104      entry_paths->AppendString(it.key());
105    }
106
107    ASSERT_TRUE(ContainsKey(profile_to_user_, profile_path.value()));
108    const std::string& userhash = profile_to_user_[profile_path.value()];
109    result->SetStringWithoutPathExpansion(shill::kUserHashProperty, userhash);
110
111    callback.Run(*result);
112  }
113
114  void GetEntry(const dbus::ObjectPath& profile_path,
115                const std::string& entry_path,
116                const DictionaryValueCallbackWithoutStatus& callback,
117                const ErrorCallback& error_callback) {
118    base::DictionaryValue* entries = NULL;
119    profile_entries_.GetDictionaryWithoutPathExpansion(profile_path.value(),
120                                                       &entries);
121    ASSERT_TRUE(entries);
122
123    base::DictionaryValue* entry = NULL;
124    entries->GetDictionaryWithoutPathExpansion(entry_path, &entry);
125    ASSERT_TRUE(entry);
126    callback.Run(*entry);
127  }
128
129 protected:
130  base::DictionaryValue profile_entries_;
131  std::map<std::string, std::string> profile_to_user_;
132};
133
134class ShillServiceTestClient {
135 public:
136  typedef ShillClientHelper::DictionaryValueCallback DictionaryValueCallback;
137  void SetFakeProperties(const base::DictionaryValue& service_properties) {
138    service_properties_.Clear();
139    service_properties_.MergeDictionary(&service_properties);
140  }
141
142  void GetProperties(const dbus::ObjectPath& service_path,
143                     const DictionaryValueCallback& callback) {
144    base::MessageLoop::current()->PostTask(
145        FROM_HERE,
146        base::Bind(callback,
147                   DBUS_METHOD_CALL_SUCCESS,
148                   base::ConstRef(service_properties_)));
149  }
150
151 protected:
152  base::DictionaryValue service_properties_;
153};
154
155class TestNetworkProfileHandler : public NetworkProfileHandler {
156 public:
157  TestNetworkProfileHandler() {
158    Init();
159  }
160  virtual ~TestNetworkProfileHandler() {}
161
162  void AddProfileForTest(const NetworkProfile& profile) {
163    AddProfile(profile);
164  }
165
166 private:
167  DISALLOW_COPY_AND_ASSIGN(TestNetworkProfileHandler);
168};
169
170}  // namespace
171
172class ManagedNetworkConfigurationHandlerTest : public testing::Test {
173 public:
174  ManagedNetworkConfigurationHandlerTest()
175      : mock_manager_client_(NULL),
176        mock_profile_client_(NULL),
177        mock_service_client_(NULL) {
178  }
179
180  virtual ~ManagedNetworkConfigurationHandlerTest() {
181  }
182
183  virtual void SetUp() OVERRIDE {
184    scoped_ptr<DBusThreadManagerSetter> dbus_setter =
185        DBusThreadManager::GetSetterForTesting();
186    mock_manager_client_ = new StrictMock<MockShillManagerClient>();
187    mock_profile_client_ = new StrictMock<MockShillProfileClient>();
188    mock_service_client_ = new StrictMock<MockShillServiceClient>();
189    dbus_setter->SetShillManagerClient(
190        scoped_ptr<ShillManagerClient>(mock_manager_client_).Pass());
191    dbus_setter->SetShillProfileClient(
192        scoped_ptr<ShillProfileClient>(mock_profile_client_).Pass());
193    dbus_setter->SetShillServiceClient(
194        scoped_ptr<ShillServiceClient>(mock_service_client_).Pass());
195
196    SetNetworkConfigurationHandlerExpectations();
197
198    ON_CALL(*mock_profile_client_, GetProperties(_,_,_))
199        .WillByDefault(Invoke(&profiles_stub_,
200                              &ShillProfileTestClient::GetProperties));
201
202    ON_CALL(*mock_profile_client_, GetEntry(_,_,_,_))
203        .WillByDefault(Invoke(&profiles_stub_,
204                              &ShillProfileTestClient::GetEntry));
205
206    ON_CALL(*mock_service_client_, GetProperties(_,_))
207        .WillByDefault(Invoke(&services_stub_,
208                              &ShillServiceTestClient::GetProperties));
209
210    network_profile_handler_.reset(new TestNetworkProfileHandler());
211    network_configuration_handler_.reset(
212        NetworkConfigurationHandler::InitializeForTest(
213            NULL /* no NetworkStateHandler */));
214    managed_network_configuration_handler_.reset(
215        new ManagedNetworkConfigurationHandlerImpl());
216    managed_network_configuration_handler_->Init(
217        NULL /* no NetworkStateHandler */,
218        network_profile_handler_.get(),
219        network_configuration_handler_.get(),
220        NULL /* no DeviceHandler */);
221
222    message_loop_.RunUntilIdle();
223  }
224
225  virtual void TearDown() OVERRIDE {
226    managed_network_configuration_handler_.reset();
227    network_configuration_handler_.reset();
228    network_profile_handler_.reset();
229    DBusThreadManager::Shutdown();
230  }
231
232  void VerifyAndClearExpectations() {
233    Mock::VerifyAndClearExpectations(mock_manager_client_);
234    Mock::VerifyAndClearExpectations(mock_profile_client_);
235    SetNetworkConfigurationHandlerExpectations();
236  }
237
238  void InitializeStandardProfiles() {
239    profiles_stub_.AddProfile(kUser1ProfilePath, kUser1);
240    network_profile_handler_->
241        AddProfileForTest(NetworkProfile(kUser1ProfilePath, kUser1));
242
243    profiles_stub_.AddProfile(NetworkProfileHandler::GetSharedProfilePath(),
244                              std::string() /* no userhash */);
245    network_profile_handler_->AddProfileForTest(
246        NetworkProfile(NetworkProfileHandler::GetSharedProfilePath(),
247                       std::string() /* no userhash */));
248  }
249
250  void SetUpEntry(const std::string& path_to_shill_json,
251                  const std::string& profile_path,
252                  const std::string& entry_path) {
253    scoped_ptr<base::DictionaryValue> entry =
254        test_utils::ReadTestDictionary(path_to_shill_json);
255    profiles_stub_.AddEntry(profile_path, entry_path, *entry);
256  }
257
258  void SetPolicy(::onc::ONCSource onc_source,
259                 const std::string& userhash,
260                 const std::string& path_to_onc) {
261    scoped_ptr<base::DictionaryValue> policy;
262    if (path_to_onc.empty())
263      policy = onc::ReadDictionaryFromJson(onc::kEmptyUnencryptedConfiguration);
264    else
265      policy = test_utils::ReadTestDictionary(path_to_onc);
266
267    base::ListValue empty_network_configs;
268    base::ListValue* network_configs = &empty_network_configs;
269    policy->GetListWithoutPathExpansion(
270        ::onc::toplevel_config::kNetworkConfigurations, &network_configs);
271
272    base::DictionaryValue empty_global_config;
273    base::DictionaryValue* global_network_config = &empty_global_config;
274    policy->GetDictionaryWithoutPathExpansion(
275        ::onc::toplevel_config::kGlobalNetworkConfiguration,
276        &global_network_config);
277
278    managed_handler()->SetPolicy(
279        onc_source, userhash, *network_configs, *global_network_config);
280  }
281
282  void SetNetworkConfigurationHandlerExpectations() {
283    // These calls occur in NetworkConfigurationHandler.
284    EXPECT_CALL(*mock_manager_client_, GetProperties(_)).Times(AnyNumber());
285    EXPECT_CALL(*mock_manager_client_,
286                AddPropertyChangedObserver(_)).Times(AnyNumber());
287    EXPECT_CALL(*mock_manager_client_,
288                RemovePropertyChangedObserver(_)).Times(AnyNumber());
289  }
290
291  ManagedNetworkConfigurationHandler* managed_handler() {
292    return managed_network_configuration_handler_.get();
293  }
294
295  void GetManagedProperties(const std::string& userhash,
296                            const std::string& service_path) {
297    managed_handler()->GetManagedProperties(
298        userhash,
299        service_path,
300        base::Bind(
301            &ManagedNetworkConfigurationHandlerTest::GetPropertiesCallback,
302            base::Unretained(this)),
303        base::Bind(&ManagedNetworkConfigurationHandlerTest::UnexpectedError));
304  }
305
306  void GetPropertiesCallback(const std::string& service_path,
307                             const base::DictionaryValue& dictionary) {
308    get_properties_service_path_ = service_path;
309    get_properties_result_.Clear();
310    get_properties_result_.MergeDictionary(&dictionary);
311  }
312
313  static void UnexpectedError(const std::string& error_name,
314                              scoped_ptr<base::DictionaryValue> error_data) {
315    ASSERT_FALSE(true);
316  }
317
318 protected:
319  MockShillManagerClient* mock_manager_client_;
320  MockShillProfileClient* mock_profile_client_;
321  MockShillServiceClient* mock_service_client_;
322  ShillProfileTestClient profiles_stub_;
323  ShillServiceTestClient services_stub_;
324  scoped_ptr<TestNetworkProfileHandler> network_profile_handler_;
325  scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
326  scoped_ptr<ManagedNetworkConfigurationHandlerImpl>
327        managed_network_configuration_handler_;
328  base::MessageLoop message_loop_;
329
330  std::string get_properties_service_path_;
331  base::DictionaryValue get_properties_result_;
332
333 private:
334  DISALLOW_COPY_AND_ASSIGN(ManagedNetworkConfigurationHandlerTest);
335};
336
337TEST_F(ManagedNetworkConfigurationHandlerTest, ProfileInitialization) {
338  InitializeStandardProfiles();
339  message_loop_.RunUntilIdle();
340}
341
342TEST_F(ManagedNetworkConfigurationHandlerTest, RemoveIrrelevantFields) {
343  InitializeStandardProfiles();
344  scoped_ptr<base::DictionaryValue> expected_shill_properties =
345      test_utils::ReadTestDictionary(
346          "policy/shill_policy_on_unconfigured_wifi1.json");
347
348  EXPECT_CALL(*mock_profile_client_,
349              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
350
351  EXPECT_CALL(*mock_manager_client_,
352              ConfigureServiceForProfile(
353                  dbus::ObjectPath(kUser1ProfilePath),
354                  IsEqualTo(expected_shill_properties.get()),
355                  _, _));
356
357  SetPolicy(::onc::ONC_SOURCE_USER_POLICY,
358            kUser1,
359            "policy/policy_wifi1_with_redundant_fields.onc");
360  message_loop_.RunUntilIdle();
361}
362
363TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyManageUnconfigured) {
364  InitializeStandardProfiles();
365  scoped_ptr<base::DictionaryValue> expected_shill_properties =
366      test_utils::ReadTestDictionary(
367          "policy/shill_policy_on_unconfigured_wifi1.json");
368
369  EXPECT_CALL(*mock_profile_client_,
370              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
371
372  EXPECT_CALL(*mock_manager_client_,
373              ConfigureServiceForProfile(
374                  dbus::ObjectPath(kUser1ProfilePath),
375                  IsEqualTo(expected_shill_properties.get()),
376                  _, _));
377
378  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
379  message_loop_.RunUntilIdle();
380}
381
382// Ensure that EAP settings for ethernet are matched with the right profile
383// entry and written to the dedicated EthernetEAP service.
384TEST_F(ManagedNetworkConfigurationHandlerTest,
385       SetPolicyManageUnmanagedEthernetEAP) {
386  InitializeStandardProfiles();
387  scoped_ptr<base::DictionaryValue> expected_shill_properties =
388      test_utils::ReadTestDictionary(
389          "policy/"
390          "shill_policy_on_unmanaged_ethernet_eap.json");
391
392  SetUpEntry("policy/shill_unmanaged_ethernet_eap.json",
393             kUser1ProfilePath,
394             "eth_entry");
395
396  // Also setup an unrelated WiFi configuration to verify that the right entry
397  // is matched.
398  SetUpEntry("policy/shill_unmanaged_wifi1.json",
399             kUser1ProfilePath,
400             "wifi_entry");
401
402  EXPECT_CALL(*mock_profile_client_,
403              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
404
405  EXPECT_CALL(*mock_profile_client_,
406              GetEntry(dbus::ObjectPath(kUser1ProfilePath), _, _, _)).Times(2);
407
408  EXPECT_CALL(
409      *mock_profile_client_,
410      DeleteEntry(dbus::ObjectPath(kUser1ProfilePath), "eth_entry", _, _));
411
412  EXPECT_CALL(
413      *mock_manager_client_,
414      ConfigureServiceForProfile(dbus::ObjectPath(kUser1ProfilePath),
415                                 IsEqualTo(expected_shill_properties.get()),
416                                 _, _));
417
418  SetPolicy(
419      ::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_ethernet_eap.onc");
420  message_loop_.RunUntilIdle();
421}
422
423TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyIgnoreUnmodified) {
424  InitializeStandardProfiles();
425  EXPECT_CALL(*mock_profile_client_, GetProperties(_, _, _));
426
427  EXPECT_CALL(*mock_manager_client_, ConfigureServiceForProfile(_, _, _, _));
428
429  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
430  message_loop_.RunUntilIdle();
431  VerifyAndClearExpectations();
432
433  SetUpEntry("policy/shill_policy_on_unmanaged_wifi1.json",
434             kUser1ProfilePath,
435             "some_entry_path");
436
437  EXPECT_CALL(*mock_profile_client_, GetProperties(_, _, _));
438
439  EXPECT_CALL(
440      *mock_profile_client_,
441      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "some_entry_path", _, _));
442
443  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
444  message_loop_.RunUntilIdle();
445}
446
447TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyManageUnmanaged) {
448  InitializeStandardProfiles();
449  SetUpEntry("policy/shill_unmanaged_wifi1.json",
450             kUser1ProfilePath,
451             "old_entry_path");
452
453  scoped_ptr<base::DictionaryValue> expected_shill_properties =
454      test_utils::ReadTestDictionary(
455          "policy/shill_policy_on_unmanaged_wifi1.json");
456
457  EXPECT_CALL(*mock_profile_client_,
458              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
459
460  EXPECT_CALL(
461      *mock_profile_client_,
462      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
463
464  EXPECT_CALL(
465      *mock_profile_client_,
466      DeleteEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
467
468  EXPECT_CALL(*mock_manager_client_,
469              ConfigureServiceForProfile(
470                  dbus::ObjectPath(kUser1ProfilePath),
471                  IsEqualTo(expected_shill_properties.get()),
472                  _, _));
473
474  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
475  message_loop_.RunUntilIdle();
476}
477
478// Old ChromeOS versions may not have used the UIData property
479TEST_F(ManagedNetworkConfigurationHandlerTest,
480       SetPolicyManageUnmanagedWithoutUIData) {
481  InitializeStandardProfiles();
482  SetUpEntry("policy/shill_unmanaged_wifi1.json",
483             kUser1ProfilePath,
484             "old_entry_path");
485
486  scoped_ptr<base::DictionaryValue> expected_shill_properties =
487      test_utils::ReadTestDictionary(
488          "policy/shill_policy_on_unmanaged_wifi1.json");
489
490  EXPECT_CALL(*mock_profile_client_,
491              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
492
493  EXPECT_CALL(
494      *mock_profile_client_,
495      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
496
497  EXPECT_CALL(
498      *mock_profile_client_,
499      DeleteEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
500
501  EXPECT_CALL(*mock_manager_client_,
502              ConfigureServiceForProfile(
503                  dbus::ObjectPath(kUser1ProfilePath),
504                  IsEqualTo(expected_shill_properties.get()),
505                  _, _));
506
507  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
508  message_loop_.RunUntilIdle();
509}
510
511TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyUpdateManagedNewGUID) {
512  InitializeStandardProfiles();
513  SetUpEntry("policy/shill_managed_wifi1.json",
514             kUser1ProfilePath,
515             "old_entry_path");
516
517  scoped_ptr<base::DictionaryValue> expected_shill_properties =
518      test_utils::ReadTestDictionary(
519          "policy/shill_policy_on_unmanaged_wifi1.json");
520
521  // The passphrase isn't sent again, because it's configured by the user and
522  // Shill doesn't send it on GetProperties calls.
523  expected_shill_properties->RemoveWithoutPathExpansion(
524      shill::kPassphraseProperty, NULL);
525
526  EXPECT_CALL(*mock_profile_client_,
527              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
528
529  EXPECT_CALL(
530      *mock_profile_client_,
531      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
532
533  EXPECT_CALL(
534      *mock_profile_client_,
535      DeleteEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
536
537  EXPECT_CALL(*mock_manager_client_,
538              ConfigureServiceForProfile(
539                  dbus::ObjectPath(kUser1ProfilePath),
540                  IsEqualTo(expected_shill_properties.get()),
541                  _, _));
542
543  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
544  message_loop_.RunUntilIdle();
545}
546
547TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyUpdateManagedVPN) {
548  InitializeStandardProfiles();
549  SetUpEntry("policy/shill_managed_vpn.json", kUser1ProfilePath, "entry_path");
550
551  scoped_ptr<base::DictionaryValue> expected_shill_properties =
552      test_utils::ReadTestDictionary(
553          "policy/shill_policy_on_managed_vpn.json");
554
555  EXPECT_CALL(*mock_profile_client_,
556              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
557
558  EXPECT_CALL(
559      *mock_profile_client_,
560      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "entry_path", _, _));
561
562  EXPECT_CALL(*mock_manager_client_,
563              ConfigureServiceForProfile(
564                  dbus::ObjectPath(kUser1ProfilePath),
565                  IsEqualTo(expected_shill_properties.get()),
566                  _, _));
567
568  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_vpn.onc");
569  message_loop_.RunUntilIdle();
570  VerifyAndClearExpectations();
571}
572
573TEST_F(ManagedNetworkConfigurationHandlerTest,
574       SetPolicyUpdateManagedEquivalentSecurity) {
575  InitializeStandardProfiles();
576  SetUpEntry("policy/shill_managed_wifi1_rsn.json",
577             kUser1ProfilePath,
578             "old_entry_path");
579
580  scoped_ptr<base::DictionaryValue> expected_shill_properties =
581      test_utils::ReadTestDictionary(
582          "policy/shill_policy_on_unmanaged_wifi1.json");
583
584  // The passphrase isn't sent again, because it's configured by the user and
585  // Shill doesn't send it on GetProperties calls.
586  expected_shill_properties->RemoveWithoutPathExpansion(
587      shill::kPassphraseProperty, NULL);
588
589  EXPECT_CALL(*mock_profile_client_,
590              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
591
592  EXPECT_CALL(
593      *mock_profile_client_,
594      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
595
596  // The existing entry must not be deleted because the Security type 'rsa' is
597  // equivalent to 'psk' when identifying networks.
598
599  EXPECT_CALL(
600      *mock_manager_client_,
601      ConfigureServiceForProfile(dbus::ObjectPath(kUser1ProfilePath),
602                                 IsEqualTo(expected_shill_properties.get()),
603                                 _, _));
604
605  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
606  message_loop_.RunUntilIdle();
607}
608
609TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyReapplyToManaged) {
610  InitializeStandardProfiles();
611  SetUpEntry("policy/shill_policy_on_unmanaged_wifi1.json",
612             kUser1ProfilePath,
613             "old_entry_path");
614
615  scoped_ptr<base::DictionaryValue> expected_shill_properties =
616      test_utils::ReadTestDictionary(
617          "policy/shill_policy_on_unmanaged_wifi1.json");
618
619  // The passphrase isn't sent again, because it's configured by the user and
620  // Shill doesn't send it on GetProperties calls.
621  expected_shill_properties->RemoveWithoutPathExpansion(
622      shill::kPassphraseProperty, NULL);
623
624  EXPECT_CALL(*mock_profile_client_,
625              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
626
627  EXPECT_CALL(
628      *mock_profile_client_,
629      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
630
631  EXPECT_CALL(*mock_manager_client_,
632              ConfigureServiceForProfile(
633                  dbus::ObjectPath(kUser1ProfilePath),
634                  IsEqualTo(expected_shill_properties.get()),
635                  _, _));
636
637  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
638  message_loop_.RunUntilIdle();
639  VerifyAndClearExpectations();
640
641  // If we apply the policy again, without change, then the Shill profile will
642  // not be modified.
643  EXPECT_CALL(*mock_profile_client_,
644              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
645
646  EXPECT_CALL(
647      *mock_profile_client_,
648      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
649
650  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
651  message_loop_.RunUntilIdle();
652}
653
654TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyUnmanageManaged) {
655  InitializeStandardProfiles();
656  SetUpEntry("policy/shill_policy_on_unmanaged_wifi1.json",
657             kUser1ProfilePath,
658             "old_entry_path");
659
660  EXPECT_CALL(*mock_profile_client_,
661              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
662
663  EXPECT_CALL(*mock_profile_client_,
664              GetEntry(dbus::ObjectPath(kUser1ProfilePath),
665                       "old_entry_path",
666                       _, _));
667
668  EXPECT_CALL(*mock_profile_client_,
669              DeleteEntry(dbus::ObjectPath(kUser1ProfilePath),
670                          "old_entry_path",
671                          _, _));
672
673  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "");
674  message_loop_.RunUntilIdle();
675}
676
677TEST_F(ManagedNetworkConfigurationHandlerTest, SetEmptyPolicyIgnoreUnmanaged) {
678  InitializeStandardProfiles();
679  SetUpEntry("policy/shill_unmanaged_wifi1.json",
680             kUser1ProfilePath,
681             "old_entry_path");
682
683  EXPECT_CALL(*mock_profile_client_,
684              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
685
686  EXPECT_CALL(*mock_profile_client_,
687              GetEntry(dbus::ObjectPath(kUser1ProfilePath),
688                       "old_entry_path",
689                       _, _));
690
691  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "");
692  message_loop_.RunUntilIdle();
693}
694
695TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyIgnoreUnmanaged) {
696  InitializeStandardProfiles();
697  SetUpEntry("policy/shill_unmanaged_wifi2.json",
698             kUser1ProfilePath,
699             "wifi2_entry_path");
700
701  EXPECT_CALL(*mock_profile_client_,
702              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
703
704  EXPECT_CALL(
705      *mock_profile_client_,
706      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "wifi2_entry_path", _, _));
707
708  scoped_ptr<base::DictionaryValue> expected_shill_properties =
709      test_utils::ReadTestDictionary(
710          "policy/shill_policy_on_unconfigured_wifi1.json");
711
712  EXPECT_CALL(*mock_manager_client_,
713              ConfigureServiceForProfile(
714                  dbus::ObjectPath(kUser1ProfilePath),
715                  IsEqualTo(expected_shill_properties.get()),
716                  _, _));
717
718  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
719  message_loop_.RunUntilIdle();
720}
721
722TEST_F(ManagedNetworkConfigurationHandlerTest, AutoConnectDisallowed) {
723  InitializeStandardProfiles();
724  // Setup an unmanaged network.
725  SetUpEntry("policy/shill_unmanaged_wifi2.json",
726             kUser1ProfilePath,
727             "wifi2_entry_path");
728
729  // Apply the user policy with global autoconnect config and expect that
730  // autoconnect is disabled in the network's profile entry.
731  EXPECT_CALL(*mock_profile_client_,
732              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
733
734  EXPECT_CALL(
735      *mock_profile_client_,
736      GetEntry(dbus::ObjectPath(kUser1ProfilePath), "wifi2_entry_path", _, _));
737
738  scoped_ptr<base::DictionaryValue> expected_shill_properties =
739      test_utils::ReadTestDictionary(
740          "policy/shill_disallow_autoconnect_on_unmanaged_wifi2.json");
741
742  EXPECT_CALL(*mock_manager_client_,
743              ConfigureServiceForProfile(
744                  dbus::ObjectPath(kUser1ProfilePath),
745                  IsEqualTo(expected_shill_properties.get()),
746                  _, _));
747
748  SetPolicy(::onc::ONC_SOURCE_USER_POLICY,
749            kUser1,
750            "policy/policy_disallow_autoconnect.onc");
751  message_loop_.RunUntilIdle();
752
753  // Verify that GetManagedProperties correctly augments the properties with the
754  // global config from the user policy.
755
756  // GetManagedProperties requires the device policy to be set or explicitly
757  // unset.
758  EXPECT_CALL(*mock_profile_client_,
759              GetProperties(dbus::ObjectPath(
760                                NetworkProfileHandler::GetSharedProfilePath()),
761                            _,
762                            _));
763  managed_handler()->SetPolicy(
764      ::onc::ONC_SOURCE_DEVICE_POLICY,
765      std::string(),             // no userhash
766      base::ListValue(),         // no device network policy
767      base::DictionaryValue());  // no device global config
768
769  services_stub_.SetFakeProperties(*expected_shill_properties);
770  EXPECT_CALL(*mock_service_client_,
771              GetProperties(dbus::ObjectPath(
772                                "wifi2"),_));
773
774  GetManagedProperties(kUser1, "wifi2");
775  message_loop_.RunUntilIdle();
776
777  EXPECT_EQ("wifi2", get_properties_service_path_);
778
779  scoped_ptr<base::DictionaryValue> expected_managed_onc =
780      test_utils::ReadTestDictionary(
781          "policy/managed_onc_disallow_autoconnect_on_unmanaged_wifi2.onc");
782  EXPECT_TRUE(onc::test_utils::Equals(expected_managed_onc.get(),
783                                      &get_properties_result_));
784}
785
786TEST_F(ManagedNetworkConfigurationHandlerTest, LateProfileLoading) {
787  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
788
789  message_loop_.RunUntilIdle();
790  VerifyAndClearExpectations();
791
792  scoped_ptr<base::DictionaryValue> expected_shill_properties =
793      test_utils::ReadTestDictionary(
794          "policy/shill_policy_on_unconfigured_wifi1.json");
795
796  EXPECT_CALL(*mock_profile_client_,
797              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
798
799  EXPECT_CALL(*mock_manager_client_,
800              ConfigureServiceForProfile(
801                  dbus::ObjectPath(kUser1ProfilePath),
802                  IsEqualTo(expected_shill_properties.get()),
803                  _, _));
804
805  InitializeStandardProfiles();
806  message_loop_.RunUntilIdle();
807}
808
809class ManagedNetworkConfigurationHandlerShutdownTest
810    : public ManagedNetworkConfigurationHandlerTest {
811 public:
812  virtual void SetUp() OVERRIDE {
813    ManagedNetworkConfigurationHandlerTest::SetUp();
814    ON_CALL(*mock_profile_client_, GetProperties(_, _, _)).WillByDefault(
815        Invoke(&ManagedNetworkConfigurationHandlerShutdownTest::GetProperties));
816  }
817
818  static void GetProperties(
819      const dbus::ObjectPath& profile_path,
820      const ShillClientHelper::DictionaryValueCallbackWithoutStatus& callback,
821      const ShillClientHelper::ErrorCallback& error_callback) {
822    base::MessageLoop::current()->PostTask(
823        FROM_HERE,
824        base::Bind(ManagedNetworkConfigurationHandlerShutdownTest::
825                       CallbackWithEmptyDictionary,
826                   callback));
827  }
828
829  static void CallbackWithEmptyDictionary(
830      const ShillClientHelper::DictionaryValueCallbackWithoutStatus& callback) {
831    callback.Run(base::DictionaryValue());
832  }
833};
834
835TEST_F(ManagedNetworkConfigurationHandlerShutdownTest,
836       DuringPolicyApplication) {
837  InitializeStandardProfiles();
838
839  EXPECT_CALL(*mock_profile_client_,
840              GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
841
842  SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
843  managed_network_configuration_handler_.reset();
844  message_loop_.RunUntilIdle();
845}
846
847}  // namespace chromeos
848