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