1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/bind.h" 6 #include "base/callback.h" 7 #include "base/command_line.h" 8 #include "base/memory/ref_counted.h" 9 #include "base/message_loop/message_loop.h" 10 #include "chrome/browser/prefs/browser_prefs.h" 11 #include "chrome/browser/prefs/pref_service_mock_factory.h" 12 #include "chrome/browser/prefs/pref_service_syncable.h" 13 #include "chrome/browser/prefs/proxy_config_dictionary.h" 14 #include "chrome/browser/prefs/proxy_prefs.h" 15 #include "chrome/common/chrome_switches.h" 16 #include "chrome/common/pref_names.h" 17 #include "components/policy/core/common/external_data_fetcher.h" 18 #include "components/policy/core/common/mock_configuration_policy_provider.h" 19 #include "components/policy/core/common/policy_map.h" 20 #include "components/policy/core/common/policy_service_impl.h" 21 #include "components/user_prefs/pref_registry_syncable.h" 22 #include "policy/policy_constants.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 25 using ::testing::Return; 26 using ::testing::_; 27 28 namespace policy { 29 30 namespace { 31 32 void assertProxyMode(const ProxyConfigDictionary& dict, 33 ProxyPrefs::ProxyMode expected_mode) { 34 ProxyPrefs::ProxyMode actual_mode; 35 ASSERT_TRUE(dict.GetMode(&actual_mode)); 36 EXPECT_EQ(expected_mode, actual_mode); 37 } 38 39 void assertProxyServer(const ProxyConfigDictionary& dict, 40 const std::string& expected) { 41 std::string actual; 42 if (!expected.empty()) { 43 ASSERT_TRUE(dict.GetProxyServer(&actual)); 44 EXPECT_EQ(expected, actual); 45 } else { 46 EXPECT_FALSE(dict.GetProxyServer(&actual)); 47 } 48 } 49 50 void assertPacUrl(const ProxyConfigDictionary& dict, 51 const std::string& expected) { 52 std::string actual; 53 if (!expected.empty()) { 54 ASSERT_TRUE(dict.GetPacUrl(&actual)); 55 EXPECT_EQ(expected, actual); 56 } else { 57 EXPECT_FALSE(dict.GetPacUrl(&actual)); 58 } 59 } 60 61 void assertBypassList(const ProxyConfigDictionary& dict, 62 const std::string& expected) { 63 std::string actual; 64 if (!expected.empty()) { 65 ASSERT_TRUE(dict.GetBypassList(&actual)); 66 EXPECT_EQ(expected, actual); 67 } else { 68 EXPECT_FALSE(dict.GetBypassList(&actual)); 69 } 70 } 71 72 void assertProxyModeWithoutParams(const ProxyConfigDictionary& dict, 73 ProxyPrefs::ProxyMode proxy_mode) { 74 assertProxyMode(dict, proxy_mode); 75 assertProxyServer(dict, std::string()); 76 assertPacUrl(dict, std::string()); 77 assertBypassList(dict, std::string()); 78 } 79 80 } // namespace 81 82 class ProxyPolicyTest : public testing::Test { 83 protected: 84 ProxyPolicyTest() 85 : command_line_(CommandLine::NO_PROGRAM) {} 86 87 virtual void SetUp() OVERRIDE { 88 EXPECT_CALL(provider_, IsInitializationComplete(_)) 89 .WillRepeatedly(Return(true)); 90 91 PolicyServiceImpl::Providers providers; 92 providers.push_back(&provider_); 93 policy_service_.reset(new PolicyServiceImpl(providers)); 94 provider_.Init(); 95 } 96 97 virtual void TearDown() OVERRIDE { 98 provider_.Shutdown(); 99 } 100 101 scoped_ptr<PrefService> CreatePrefService(bool with_managed_policies) { 102 PrefServiceMockFactory factory; 103 factory.SetCommandLine(&command_line_); 104 if (with_managed_policies) 105 factory.SetManagedPolicies(policy_service_.get()); 106 scoped_refptr<user_prefs::PrefRegistrySyncable> registry( 107 new user_prefs::PrefRegistrySyncable); 108 scoped_ptr<PrefServiceSyncable> prefs = 109 factory.CreateSyncable(registry.get()); 110 chrome::RegisterUserProfilePrefs(registry.get()); 111 return prefs.PassAs<PrefService>(); 112 } 113 114 base::MessageLoop loop_; 115 CommandLine command_line_; 116 MockConfigurationPolicyProvider provider_; 117 scoped_ptr<PolicyServiceImpl> policy_service_; 118 }; 119 120 TEST_F(ProxyPolicyTest, OverridesCommandLineOptions) { 121 command_line_.AppendSwitchASCII(switches::kProxyBypassList, "123"); 122 command_line_.AppendSwitchASCII(switches::kProxyServer, "789"); 123 Value* mode_name = Value::CreateStringValue( 124 ProxyPrefs::kFixedServersProxyModeName); 125 PolicyMap policy; 126 policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 127 mode_name, NULL); 128 policy.Set(key::kProxyBypassList, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 129 Value::CreateStringValue("abc"), NULL); 130 policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 131 Value::CreateStringValue("ghi"), NULL); 132 provider_.UpdateChromePolicy(policy); 133 134 // First verify that command-line options are set correctly when 135 // there is no policy in effect. 136 scoped_ptr<PrefService> prefs(CreatePrefService(false)); 137 ProxyConfigDictionary dict(prefs->GetDictionary(prefs::kProxy)); 138 assertProxyMode(dict, ProxyPrefs::MODE_FIXED_SERVERS); 139 assertProxyServer(dict, "789"); 140 assertPacUrl(dict, std::string()); 141 assertBypassList(dict, "123"); 142 143 // Try a second time time with the managed PrefStore in place, the 144 // manual proxy policy should have removed all traces of the command 145 // line and replaced them with the policy versions. 146 prefs = CreatePrefService(true); 147 ProxyConfigDictionary dict2(prefs->GetDictionary(prefs::kProxy)); 148 assertProxyMode(dict2, ProxyPrefs::MODE_FIXED_SERVERS); 149 assertProxyServer(dict2, "ghi"); 150 assertPacUrl(dict2, std::string()); 151 assertBypassList(dict2, "abc"); 152 } 153 154 TEST_F(ProxyPolicyTest, OverridesUnrelatedCommandLineOptions) { 155 command_line_.AppendSwitchASCII(switches::kProxyBypassList, "123"); 156 command_line_.AppendSwitchASCII(switches::kProxyServer, "789"); 157 Value* mode_name = Value::CreateStringValue( 158 ProxyPrefs::kAutoDetectProxyModeName); 159 PolicyMap policy; 160 policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 161 mode_name, NULL); 162 provider_.UpdateChromePolicy(policy); 163 164 // First verify that command-line options are set correctly when 165 // there is no policy in effect. 166 scoped_ptr<PrefService> prefs = CreatePrefService(false); 167 ProxyConfigDictionary dict(prefs->GetDictionary(prefs::kProxy)); 168 assertProxyMode(dict, ProxyPrefs::MODE_FIXED_SERVERS); 169 assertProxyServer(dict, "789"); 170 assertPacUrl(dict, std::string()); 171 assertBypassList(dict, "123"); 172 173 // Try a second time time with the managed PrefStore in place, the 174 // no proxy policy should have removed all traces of the command 175 // line proxy settings, even though they were not the specific one 176 // set in policy. 177 prefs = CreatePrefService(true); 178 ProxyConfigDictionary dict2(prefs->GetDictionary(prefs::kProxy)); 179 assertProxyModeWithoutParams(dict2, ProxyPrefs::MODE_AUTO_DETECT); 180 } 181 182 TEST_F(ProxyPolicyTest, OverridesCommandLineNoProxy) { 183 command_line_.AppendSwitch(switches::kNoProxyServer); 184 Value* mode_name = Value::CreateStringValue( 185 ProxyPrefs::kAutoDetectProxyModeName); 186 PolicyMap policy; 187 policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 188 mode_name, NULL); 189 provider_.UpdateChromePolicy(policy); 190 191 // First verify that command-line options are set correctly when 192 // there is no policy in effect. 193 scoped_ptr<PrefService> prefs = CreatePrefService(false); 194 ProxyConfigDictionary dict(prefs->GetDictionary(prefs::kProxy)); 195 assertProxyModeWithoutParams(dict, ProxyPrefs::MODE_DIRECT); 196 197 // Try a second time time with the managed PrefStore in place, the 198 // auto-detect should be overridden. The default pref store must be 199 // in place with the appropriate default value for this to work. 200 prefs = CreatePrefService(true); 201 ProxyConfigDictionary dict2(prefs->GetDictionary(prefs::kProxy)); 202 assertProxyModeWithoutParams(dict2, ProxyPrefs::MODE_AUTO_DETECT); 203 } 204 205 TEST_F(ProxyPolicyTest, OverridesCommandLineAutoDetect) { 206 command_line_.AppendSwitch(switches::kProxyAutoDetect); 207 Value* mode_name = Value::CreateStringValue( 208 ProxyPrefs::kDirectProxyModeName); 209 PolicyMap policy; 210 policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 211 mode_name, NULL); 212 provider_.UpdateChromePolicy(policy); 213 214 // First verify that the auto-detect is set if there is no managed 215 // PrefStore. 216 scoped_ptr<PrefService> prefs = CreatePrefService(false); 217 ProxyConfigDictionary dict(prefs->GetDictionary(prefs::kProxy)); 218 assertProxyModeWithoutParams(dict, ProxyPrefs::MODE_AUTO_DETECT); 219 220 // Try a second time time with the managed PrefStore in place, the 221 // auto-detect should be overridden. The default pref store must be 222 // in place with the appropriate default value for this to work. 223 prefs = CreatePrefService(true); 224 ProxyConfigDictionary dict2(prefs->GetDictionary(prefs::kProxy)); 225 assertProxyModeWithoutParams(dict2, ProxyPrefs::MODE_DIRECT); 226 } 227 228 } // namespace policy 229