1// Copyright 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 <string>
6
7#include "base/memory/scoped_ptr.h"
8#include "base/values.h"
9#include "chrome/browser/net/proxy_policy_handler.h"
10#include "chrome/browser/prefs/proxy_config_dictionary.h"
11#include "chrome/browser/prefs/proxy_prefs.h"
12#include "chrome/common/pref_names.h"
13#include "components/policy/core/browser/configuration_policy_pref_store.h"
14#include "components/policy/core/browser/configuration_policy_pref_store_test.h"
15#include "components/policy/core/common/policy_service_impl.h"
16#include "policy/policy_constants.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19namespace policy {
20
21// Test cases for the proxy policy settings.
22class ProxyPolicyHandlerTest
23    : public ConfigurationPolicyPrefStoreTest {
24 public:
25  virtual void SetUp() OVERRIDE {
26    ConfigurationPolicyPrefStoreTest::SetUp();
27    handler_list_.AddHandler(
28        make_scoped_ptr<ConfigurationPolicyHandler>(new ProxyPolicyHandler));
29    // Reset the PolicyServiceImpl to one that has the policy fixup
30    // preprocessor. The previous store must be nulled out first so that it
31    // removes itself from the service's observer list.
32    store_ = NULL;
33    policy_service_.reset(new PolicyServiceImpl(providers_));
34    store_ = new ConfigurationPolicyPrefStore(
35        policy_service_.get(), &handler_list_, POLICY_LEVEL_MANDATORY);
36  }
37
38 protected:
39  // Verify that all the proxy prefs are set to the specified expected values.
40  void VerifyProxyPrefs(
41      const std::string& expected_proxy_server,
42      const std::string& expected_proxy_pac_url,
43      const std::string& expected_proxy_bypass_list,
44      const ProxyPrefs::ProxyMode& expected_proxy_mode) {
45    const base::Value* value = NULL;
46    ASSERT_TRUE(store_->GetValue(prefs::kProxy, &value));
47    ASSERT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
48    ProxyConfigDictionary dict(
49        static_cast<const base::DictionaryValue*>(value));
50    std::string s;
51    if (expected_proxy_server.empty()) {
52      EXPECT_FALSE(dict.GetProxyServer(&s));
53    } else {
54      ASSERT_TRUE(dict.GetProxyServer(&s));
55      EXPECT_EQ(expected_proxy_server, s);
56    }
57    if (expected_proxy_pac_url.empty()) {
58      EXPECT_FALSE(dict.GetPacUrl(&s));
59    } else {
60      ASSERT_TRUE(dict.GetPacUrl(&s));
61      EXPECT_EQ(expected_proxy_pac_url, s);
62    }
63    if (expected_proxy_bypass_list.empty()) {
64      EXPECT_FALSE(dict.GetBypassList(&s));
65    } else {
66      ASSERT_TRUE(dict.GetBypassList(&s));
67      EXPECT_EQ(expected_proxy_bypass_list, s);
68    }
69    ProxyPrefs::ProxyMode mode;
70    ASSERT_TRUE(dict.GetMode(&mode));
71    EXPECT_EQ(expected_proxy_mode, mode);
72  }
73};
74
75TEST_F(ProxyPolicyHandlerTest, ManualOptions) {
76  PolicyMap policy;
77  policy.Set(key::kProxyBypassList,
78             POLICY_LEVEL_MANDATORY,
79             POLICY_SCOPE_USER,
80             new base::StringValue("http://chromium.org/override"),
81             NULL);
82  policy.Set(key::kProxyServer,
83             POLICY_LEVEL_MANDATORY,
84             POLICY_SCOPE_USER,
85             new base::StringValue("chromium.org"),
86             NULL);
87  policy.Set(
88      key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
89      base::Value::CreateIntegerValue(
90          ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE),
91      NULL);
92  UpdateProviderPolicy(policy);
93
94  VerifyProxyPrefs("chromium.org",
95                   std::string(),
96                   "http://chromium.org/override",
97                   ProxyPrefs::MODE_FIXED_SERVERS);
98}
99
100TEST_F(ProxyPolicyHandlerTest, ManualOptionsReversedApplyOrder) {
101  PolicyMap policy;
102  policy.Set(
103      key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
104      base::Value::CreateIntegerValue(
105          ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE),
106      NULL);
107  policy.Set(key::kProxyBypassList,
108             POLICY_LEVEL_MANDATORY,
109             POLICY_SCOPE_USER,
110             new base::StringValue("http://chromium.org/override"),
111             NULL);
112  policy.Set(key::kProxyServer,
113             POLICY_LEVEL_MANDATORY,
114             POLICY_SCOPE_USER,
115             new base::StringValue("chromium.org"),
116             NULL);
117  UpdateProviderPolicy(policy);
118
119  VerifyProxyPrefs("chromium.org",
120                   std::string(),
121                   "http://chromium.org/override",
122                   ProxyPrefs::MODE_FIXED_SERVERS);
123}
124
125TEST_F(ProxyPolicyHandlerTest, ManualOptionsInvalid) {
126  PolicyMap policy;
127  policy.Set(
128      key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
129      base::Value::CreateIntegerValue(
130          ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE),
131      NULL);
132  UpdateProviderPolicy(policy);
133
134  const base::Value* value = NULL;
135  EXPECT_FALSE(store_->GetValue(prefs::kProxy, &value));
136}
137
138TEST_F(ProxyPolicyHandlerTest, NoProxyServerMode) {
139  PolicyMap policy;
140  policy.Set(key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
141             base::Value::CreateIntegerValue(
142                 ProxyPolicyHandler::PROXY_SERVER_MODE),
143             NULL);
144  UpdateProviderPolicy(policy);
145  VerifyProxyPrefs(
146      std::string(), std::string(), std::string(), ProxyPrefs::MODE_DIRECT);
147}
148
149TEST_F(ProxyPolicyHandlerTest, NoProxyModeName) {
150  PolicyMap policy;
151  policy.Set(key::kProxyMode,
152             POLICY_LEVEL_MANDATORY,
153             POLICY_SCOPE_USER,
154             new base::StringValue(ProxyPrefs::kDirectProxyModeName),
155             NULL);
156  UpdateProviderPolicy(policy);
157  VerifyProxyPrefs(
158      std::string(), std::string(), std::string(), ProxyPrefs::MODE_DIRECT);
159}
160
161TEST_F(ProxyPolicyHandlerTest, AutoDetectProxyServerMode) {
162  PolicyMap policy;
163  policy.Set(
164      key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
165      base::Value::CreateIntegerValue(
166          ProxyPolicyHandler::PROXY_AUTO_DETECT_PROXY_SERVER_MODE),
167      NULL);
168  UpdateProviderPolicy(policy);
169  VerifyProxyPrefs(std::string(),
170                   std::string(),
171                   std::string(),
172                   ProxyPrefs::MODE_AUTO_DETECT);
173}
174
175TEST_F(ProxyPolicyHandlerTest, AutoDetectProxyModeName) {
176  PolicyMap policy;
177  policy.Set(key::kProxyMode,
178             POLICY_LEVEL_MANDATORY,
179             POLICY_SCOPE_USER,
180             new base::StringValue(ProxyPrefs::kAutoDetectProxyModeName),
181             NULL);
182  UpdateProviderPolicy(policy);
183  VerifyProxyPrefs(std::string(),
184                   std::string(),
185                   std::string(),
186                   ProxyPrefs::MODE_AUTO_DETECT);
187}
188
189TEST_F(ProxyPolicyHandlerTest, PacScriptProxyMode) {
190  PolicyMap policy;
191  policy.Set(key::kProxyPacUrl,
192             POLICY_LEVEL_MANDATORY,
193             POLICY_SCOPE_USER,
194             new base::StringValue("http://short.org/proxy.pac"),
195             NULL);
196  policy.Set(key::kProxyMode,
197             POLICY_LEVEL_MANDATORY,
198             POLICY_SCOPE_USER,
199             new base::StringValue(ProxyPrefs::kPacScriptProxyModeName),
200             NULL);
201  UpdateProviderPolicy(policy);
202  VerifyProxyPrefs(std::string(),
203                   "http://short.org/proxy.pac",
204                   std::string(),
205                   ProxyPrefs::MODE_PAC_SCRIPT);
206}
207
208TEST_F(ProxyPolicyHandlerTest, PacScriptProxyModeInvalid) {
209  PolicyMap policy;
210  policy.Set(key::kProxyMode,
211             POLICY_LEVEL_MANDATORY,
212             POLICY_SCOPE_USER,
213             new base::StringValue(ProxyPrefs::kPacScriptProxyModeName),
214             NULL);
215  UpdateProviderPolicy(policy);
216  const base::Value* value = NULL;
217  EXPECT_FALSE(store_->GetValue(prefs::kProxy, &value));
218}
219
220// Regression test for http://crbug.com/78016, CPanel returns empty strings
221// for unset properties.
222TEST_F(ProxyPolicyHandlerTest, PacScriptProxyModeBug78016) {
223  PolicyMap policy;
224  policy.Set(key::kProxyServer,
225             POLICY_LEVEL_MANDATORY,
226             POLICY_SCOPE_USER,
227             new base::StringValue(std::string()),
228             NULL);
229  policy.Set(key::kProxyPacUrl,
230             POLICY_LEVEL_MANDATORY,
231             POLICY_SCOPE_USER,
232             new base::StringValue("http://short.org/proxy.pac"),
233             NULL);
234  policy.Set(key::kProxyMode,
235             POLICY_LEVEL_MANDATORY,
236             POLICY_SCOPE_USER,
237             new base::StringValue(ProxyPrefs::kPacScriptProxyModeName),
238             NULL);
239  UpdateProviderPolicy(policy);
240  VerifyProxyPrefs(std::string(),
241                   "http://short.org/proxy.pac",
242                   std::string(),
243                   ProxyPrefs::MODE_PAC_SCRIPT);
244}
245
246TEST_F(ProxyPolicyHandlerTest, UseSystemProxyServerMode) {
247  PolicyMap policy;
248  policy.Set(key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
249      base::Value::CreateIntegerValue(
250          ProxyPolicyHandler::PROXY_USE_SYSTEM_PROXY_SERVER_MODE),
251      NULL);
252  UpdateProviderPolicy(policy);
253  VerifyProxyPrefs(
254      std::string(), std::string(), std::string(), ProxyPrefs::MODE_SYSTEM);
255}
256
257TEST_F(ProxyPolicyHandlerTest, UseSystemProxyMode) {
258  PolicyMap policy;
259  policy.Set(key::kProxyMode,
260             POLICY_LEVEL_MANDATORY,
261             POLICY_SCOPE_USER,
262             new base::StringValue(ProxyPrefs::kSystemProxyModeName),
263             NULL);
264  UpdateProviderPolicy(policy);
265  VerifyProxyPrefs(
266      std::string(), std::string(), std::string(), ProxyPrefs::MODE_SYSTEM);
267}
268
269TEST_F(ProxyPolicyHandlerTest,
270       ProxyModeOverridesProxyServerMode) {
271  PolicyMap policy;
272  policy.Set(key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
273             base::Value::CreateIntegerValue(
274                 ProxyPolicyHandler::PROXY_SERVER_MODE),
275             NULL);
276  policy.Set(key::kProxyMode,
277             POLICY_LEVEL_MANDATORY,
278             POLICY_SCOPE_USER,
279             new base::StringValue(ProxyPrefs::kAutoDetectProxyModeName),
280             NULL);
281  UpdateProviderPolicy(policy);
282  VerifyProxyPrefs(std::string(),
283                   std::string(),
284                   std::string(),
285                   ProxyPrefs::MODE_AUTO_DETECT);
286}
287
288TEST_F(ProxyPolicyHandlerTest, ProxyInvalid) {
289  // No mode expects all three parameters being set.
290  PolicyMap policy;
291  policy.Set(key::kProxyPacUrl,
292             POLICY_LEVEL_MANDATORY,
293             POLICY_SCOPE_USER,
294             new base::StringValue("http://short.org/proxy.pac"),
295             NULL);
296  policy.Set(key::kProxyBypassList,
297             POLICY_LEVEL_MANDATORY,
298             POLICY_SCOPE_USER,
299             new base::StringValue("http://chromium.org/override"),
300             NULL);
301  policy.Set(key::kProxyServer,
302             POLICY_LEVEL_MANDATORY,
303             POLICY_SCOPE_USER,
304             new base::StringValue("chromium.org"),
305             NULL);
306  for (int i = 0; i < ProxyPolicyHandler::MODE_COUNT; ++i) {
307    policy.Set(key::kProxyServerMode, POLICY_LEVEL_MANDATORY,
308               POLICY_SCOPE_USER, base::Value::CreateIntegerValue(i), NULL);
309    UpdateProviderPolicy(policy);
310    const base::Value* value = NULL;
311    EXPECT_FALSE(store_->GetValue(prefs::kProxy, &value));
312  }
313}
314
315}  // namespace policy
316