1// Copyright 2014 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/bind_helpers.h"
7#include "base/message_loop/message_loop.h"
8#include "base/run_loop.h"
9#include "chrome/browser/supervised_user/supervised_user_url_filter.h"
10#include "testing/gtest/include/gtest/gtest.h"
11#include "url/gurl.h"
12
13class SupervisedUserURLFilterTest : public ::testing::Test,
14                                    public SupervisedUserURLFilter::Observer {
15 public:
16  SupervisedUserURLFilterTest() : filter_(new SupervisedUserURLFilter) {
17    filter_->SetDefaultFilteringBehavior(SupervisedUserURLFilter::BLOCK);
18    filter_->AddObserver(this);
19  }
20
21  virtual ~SupervisedUserURLFilterTest() {
22    filter_->RemoveObserver(this);
23  }
24
25  // SupervisedUserURLFilter::Observer:
26  virtual void OnSiteListUpdated() OVERRIDE {
27    run_loop_.Quit();
28  }
29
30 protected:
31  bool IsURLWhitelisted(const std::string& url) {
32    return filter_->GetFilteringBehaviorForURL(GURL(url)) ==
33           SupervisedUserURLFilter::ALLOW;
34  }
35
36  base::MessageLoop message_loop_;
37  base::RunLoop run_loop_;
38  scoped_refptr<SupervisedUserURLFilter> filter_;
39};
40
41TEST_F(SupervisedUserURLFilterTest, Basic) {
42  std::vector<std::string> list;
43  // Allow domain and all subdomains, for any filtered scheme.
44  list.push_back("google.com");
45  filter_->SetFromPatterns(list);
46  run_loop_.Run();
47
48  EXPECT_TRUE(IsURLWhitelisted("http://google.com"));
49  EXPECT_TRUE(IsURLWhitelisted("http://google.com/"));
50  EXPECT_TRUE(IsURLWhitelisted("http://google.com/whatever"));
51  EXPECT_TRUE(IsURLWhitelisted("https://google.com/"));
52  EXPECT_FALSE(IsURLWhitelisted("http://notgoogle.com/"));
53  EXPECT_TRUE(IsURLWhitelisted("http://mail.google.com"));
54  EXPECT_TRUE(IsURLWhitelisted("http://x.mail.google.com"));
55  EXPECT_TRUE(IsURLWhitelisted("https://x.mail.google.com/"));
56  EXPECT_TRUE(IsURLWhitelisted("http://x.y.google.com/a/b"));
57  EXPECT_FALSE(IsURLWhitelisted("http://youtube.com/"));
58
59  EXPECT_TRUE(IsURLWhitelisted("bogus://youtube.com/"));
60  EXPECT_TRUE(IsURLWhitelisted("chrome://youtube.com/"));
61  EXPECT_TRUE(IsURLWhitelisted("chrome://extensions/"));
62  EXPECT_TRUE(IsURLWhitelisted("chrome-extension://foo/main.html"));
63  EXPECT_TRUE(IsURLWhitelisted("file:///home/chronos/user/Downloads/img.jpg"));
64}
65
66TEST_F(SupervisedUserURLFilterTest, Inactive) {
67  filter_->SetDefaultFilteringBehavior(SupervisedUserURLFilter::ALLOW);
68
69  std::vector<std::string> list;
70  list.push_back("google.com");
71  filter_->SetFromPatterns(list);
72  run_loop_.Run();
73
74  // If the filter is inactive, every URL should be whitelisted.
75  EXPECT_TRUE(IsURLWhitelisted("http://google.com"));
76  EXPECT_TRUE(IsURLWhitelisted("https://www.example.com"));
77}
78
79TEST_F(SupervisedUserURLFilterTest, Scheme) {
80  std::vector<std::string> list;
81  // Filter only http, ftp and ws schemes.
82  list.push_back("http://secure.com");
83  list.push_back("ftp://secure.com");
84  list.push_back("ws://secure.com");
85  filter_->SetFromPatterns(list);
86  run_loop_.Run();
87
88  EXPECT_TRUE(IsURLWhitelisted("http://secure.com"));
89  EXPECT_TRUE(IsURLWhitelisted("http://secure.com/whatever"));
90  EXPECT_TRUE(IsURLWhitelisted("ftp://secure.com/"));
91  EXPECT_TRUE(IsURLWhitelisted("ws://secure.com"));
92  EXPECT_FALSE(IsURLWhitelisted("https://secure.com/"));
93  EXPECT_FALSE(IsURLWhitelisted("wss://secure.com"));
94  EXPECT_TRUE(IsURLWhitelisted("http://www.secure.com"));
95  EXPECT_FALSE(IsURLWhitelisted("https://www.secure.com"));
96  EXPECT_FALSE(IsURLWhitelisted("wss://www.secure.com"));
97}
98
99TEST_F(SupervisedUserURLFilterTest, Path) {
100  std::vector<std::string> list;
101  // Filter only a certain path prefix.
102  list.push_back("path.to/ruin");
103  filter_->SetFromPatterns(list);
104  run_loop_.Run();
105
106  EXPECT_TRUE(IsURLWhitelisted("http://path.to/ruin"));
107  EXPECT_TRUE(IsURLWhitelisted("https://path.to/ruin"));
108  EXPECT_TRUE(IsURLWhitelisted("http://path.to/ruins"));
109  EXPECT_TRUE(IsURLWhitelisted("http://path.to/ruin/signup"));
110  EXPECT_TRUE(IsURLWhitelisted("http://www.path.to/ruin"));
111  EXPECT_FALSE(IsURLWhitelisted("http://path.to/fortune"));
112}
113
114TEST_F(SupervisedUserURLFilterTest, PathAndScheme) {
115  std::vector<std::string> list;
116  // Filter only a certain path prefix and scheme.
117  list.push_back("https://s.aaa.com/path");
118  filter_->SetFromPatterns(list);
119  run_loop_.Run();
120
121  EXPECT_TRUE(IsURLWhitelisted("https://s.aaa.com/path"));
122  EXPECT_TRUE(IsURLWhitelisted("https://s.aaa.com/path/bbb"));
123  EXPECT_FALSE(IsURLWhitelisted("http://s.aaa.com/path"));
124  EXPECT_FALSE(IsURLWhitelisted("https://aaa.com/path"));
125  EXPECT_FALSE(IsURLWhitelisted("https://x.aaa.com/path"));
126  EXPECT_FALSE(IsURLWhitelisted("https://s.aaa.com/bbb"));
127  EXPECT_FALSE(IsURLWhitelisted("https://s.aaa.com/"));
128}
129
130TEST_F(SupervisedUserURLFilterTest, Host) {
131  std::vector<std::string> list;
132  // Filter only a certain hostname, without subdomains.
133  list.push_back(".www.example.com");
134  filter_->SetFromPatterns(list);
135  run_loop_.Run();
136
137  EXPECT_TRUE(IsURLWhitelisted("http://www.example.com"));
138  EXPECT_FALSE(IsURLWhitelisted("http://example.com"));
139  EXPECT_FALSE(IsURLWhitelisted("http://subdomain.example.com"));
140}
141
142TEST_F(SupervisedUserURLFilterTest, IPAddress) {
143  std::vector<std::string> list;
144  // Filter an ip address.
145  list.push_back("123.123.123.123");
146  filter_->SetFromPatterns(list);
147  run_loop_.Run();
148
149  EXPECT_TRUE(IsURLWhitelisted("http://123.123.123.123/"));
150  EXPECT_FALSE(IsURLWhitelisted("http://123.123.123.124/"));
151}
152
153TEST_F(SupervisedUserURLFilterTest, Canonicalization) {
154  // We assume that the hosts and URLs are already canonicalized.
155  std::map<std::string, bool> hosts;
156  hosts["www.moose.org"] = true;
157  hosts["www.xn--n3h.net"] = true;
158  std::map<GURL, bool> urls;
159  urls[GURL("http://www.example.com/foo/")] = true;
160  urls[GURL("http://www.example.com/%C3%85t%C3%B8mstr%C3%B6m")] = true;
161  filter_->SetManualHosts(&hosts);
162  filter_->SetManualURLs(&urls);
163
164  // Base cases.
165  EXPECT_TRUE(IsURLWhitelisted("http://www.example.com/foo/"));
166  EXPECT_TRUE(IsURLWhitelisted(
167      "http://www.example.com/%C3%85t%C3%B8mstr%C3%B6m"));
168
169  // Verify that non-URI characters are escaped.
170  EXPECT_TRUE(IsURLWhitelisted(
171      "http://www.example.com/\xc3\x85t\xc3\xb8mstr\xc3\xb6m"));
172
173  // Verify that unnecessary URI escapes are unescaped.
174  EXPECT_TRUE(IsURLWhitelisted("http://www.example.com/%66%6F%6F/"));
175
176  // Verify that the default port are removed.
177  EXPECT_TRUE(IsURLWhitelisted("http://www.example.com:80/foo/"));
178
179  // Verify that scheme and hostname are lowercased.
180  EXPECT_TRUE(IsURLWhitelisted("htTp://wWw.eXamPle.com/foo/"));
181  EXPECT_TRUE(IsURLWhitelisted("HttP://WwW.mOOsE.orG/blurp/"));
182
183  // Verify that UTF-8 in hostnames are converted to punycode.
184  EXPECT_TRUE(IsURLWhitelisted("http://www.\xe2\x98\x83\x0a.net/bla/"));
185
186  // Verify that query and ref are stripped.
187  EXPECT_TRUE(IsURLWhitelisted("http://www.example.com/foo/?bar=baz#ref"));
188}
189
190TEST_F(SupervisedUserURLFilterTest, HasFilteredScheme) {
191  EXPECT_TRUE(
192      SupervisedUserURLFilter::HasFilteredScheme(GURL("http://example.com")));
193  EXPECT_TRUE(
194      SupervisedUserURLFilter::HasFilteredScheme(GURL("https://example.com")));
195  EXPECT_TRUE(
196      SupervisedUserURLFilter::HasFilteredScheme(GURL("ftp://example.com")));
197  EXPECT_TRUE(
198      SupervisedUserURLFilter::HasFilteredScheme(GURL("gopher://example.com")));
199  EXPECT_TRUE(
200      SupervisedUserURLFilter::HasFilteredScheme(GURL("ws://example.com")));
201  EXPECT_TRUE(
202      SupervisedUserURLFilter::HasFilteredScheme(GURL("wss://example.com")));
203
204  EXPECT_FALSE(
205      SupervisedUserURLFilter::HasFilteredScheme(GURL("file://example.com")));
206  EXPECT_FALSE(
207      SupervisedUserURLFilter::HasFilteredScheme(
208          GURL("filesystem://80cols.com")));
209  EXPECT_FALSE(
210      SupervisedUserURLFilter::HasFilteredScheme(GURL("chrome://example.com")));
211  EXPECT_FALSE(
212      SupervisedUserURLFilter::HasFilteredScheme(GURL("wtf://example.com")));
213}
214
215TEST_F(SupervisedUserURLFilterTest, HostMatchesPattern) {
216  EXPECT_TRUE(
217      SupervisedUserURLFilter::HostMatchesPattern("www.google.com",
218                                                  "*.google.com"));
219  EXPECT_TRUE(
220      SupervisedUserURLFilter::HostMatchesPattern("google.com",
221                                                  "*.google.com"));
222  EXPECT_TRUE(
223      SupervisedUserURLFilter::HostMatchesPattern("accounts.google.com",
224                                                  "*.google.com"));
225  EXPECT_FALSE(
226      SupervisedUserURLFilter::HostMatchesPattern("www.google.de",
227                                                  "*.google.com"));
228  EXPECT_FALSE(
229      SupervisedUserURLFilter::HostMatchesPattern("notgoogle.com",
230                                                  "*.google.com"));
231
232
233  EXPECT_TRUE(
234      SupervisedUserURLFilter::HostMatchesPattern("www.google.com",
235                                                  "www.google.*"));
236  EXPECT_TRUE(
237      SupervisedUserURLFilter::HostMatchesPattern("www.google.de",
238                                                  "www.google.*"));
239  EXPECT_TRUE(
240      SupervisedUserURLFilter::HostMatchesPattern("www.google.co.uk",
241                                                  "www.google.*"));
242  EXPECT_FALSE(
243      SupervisedUserURLFilter::HostMatchesPattern("www.google.blogspot.com",
244                                                  "www.google.*"));
245  EXPECT_FALSE(
246      SupervisedUserURLFilter::HostMatchesPattern("www.google",
247                                                  "www.google.*"));
248  EXPECT_FALSE(
249      SupervisedUserURLFilter::HostMatchesPattern("google.com",
250                                                  "www.google.*"));
251  EXPECT_FALSE(
252      SupervisedUserURLFilter::HostMatchesPattern("mail.google.com",
253                                                  "www.google.*"));
254  EXPECT_FALSE(
255      SupervisedUserURLFilter::HostMatchesPattern("www.googleplex.com",
256                                                  "www.google.*"));
257  EXPECT_FALSE(
258      SupervisedUserURLFilter::HostMatchesPattern("www.googleco.uk",
259                                                  "www.google.*"));
260
261
262  EXPECT_TRUE(
263      SupervisedUserURLFilter::HostMatchesPattern("www.google.com",
264                                                  "*.google.*"));
265  EXPECT_TRUE(
266      SupervisedUserURLFilter::HostMatchesPattern("google.com",
267                                                  "*.google.*"));
268  EXPECT_TRUE(
269      SupervisedUserURLFilter::HostMatchesPattern("accounts.google.com",
270                                                  "*.google.*"));
271  EXPECT_TRUE(
272      SupervisedUserURLFilter::HostMatchesPattern("mail.google.com",
273                                                  "*.google.*"));
274  EXPECT_TRUE(
275      SupervisedUserURLFilter::HostMatchesPattern("www.google.de",
276                                                  "*.google.*"));
277  EXPECT_TRUE(
278      SupervisedUserURLFilter::HostMatchesPattern("google.de",
279                                                  "*.google.*"));
280  EXPECT_FALSE(
281      SupervisedUserURLFilter::HostMatchesPattern("google.blogspot.com",
282                                                  "*.google.*"));
283  EXPECT_FALSE(
284      SupervisedUserURLFilter::HostMatchesPattern("google", "*.google.*"));
285  EXPECT_FALSE(
286      SupervisedUserURLFilter::HostMatchesPattern("notgoogle.com",
287                                                  "*.google.*"));
288  EXPECT_FALSE(
289      SupervisedUserURLFilter::HostMatchesPattern("www.googleplex.com",
290                                                  "*.google.*"));
291
292  // Now test a few invalid patterns. They should never match.
293  EXPECT_FALSE(
294      SupervisedUserURLFilter::HostMatchesPattern("www.google.com", ""));
295  EXPECT_FALSE(
296      SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "."));
297  EXPECT_FALSE(
298      SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "*"));
299  EXPECT_FALSE(
300      SupervisedUserURLFilter::HostMatchesPattern("www.google.com", ".*"));
301  EXPECT_FALSE(
302      SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "*."));
303  EXPECT_FALSE(
304      SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "*.*"));
305  EXPECT_FALSE(
306      SupervisedUserURLFilter::HostMatchesPattern("www.google..com", "*..*"));
307  EXPECT_FALSE(
308      SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "*.*.com"));
309  EXPECT_FALSE(
310      SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "www.*.*"));
311  EXPECT_FALSE(
312      SupervisedUserURLFilter::HostMatchesPattern("www.google.com",
313                                                  "*.goo.*le.*"));
314  EXPECT_FALSE(
315      SupervisedUserURLFilter::HostMatchesPattern("www.google.com",
316                                                  "*google*"));
317  EXPECT_FALSE(
318      SupervisedUserURLFilter::HostMatchesPattern("www.google.com",
319                                                  "www.*.google.com"));
320}
321
322TEST_F(SupervisedUserURLFilterTest, Patterns) {
323  std::map<std::string, bool> hosts;
324
325  // Initally, the second rule is ignored because has the same value as the
326  // default (block). When we change the default to allow, the first rule is
327  // ignored instead.
328  hosts["*.google.com"] = true;
329  hosts["www.google.*"] = false;
330
331  hosts["accounts.google.com"] = false;
332  hosts["mail.google.com"] = true;
333  filter_->SetManualHosts(&hosts);
334
335  // Initially, the default filtering behavior is BLOCK.
336  EXPECT_TRUE(IsURLWhitelisted("http://www.google.com/foo/"));
337  EXPECT_FALSE(IsURLWhitelisted("http://accounts.google.com/bar/"));
338  EXPECT_FALSE(IsURLWhitelisted("http://www.google.co.uk/blurp/"));
339  EXPECT_TRUE(IsURLWhitelisted("http://mail.google.com/moose/"));
340
341  filter_->SetDefaultFilteringBehavior(SupervisedUserURLFilter::ALLOW);
342  EXPECT_FALSE(IsURLWhitelisted("http://www.google.com/foo/"));
343  EXPECT_FALSE(IsURLWhitelisted("http://accounts.google.com/bar/"));
344  EXPECT_FALSE(IsURLWhitelisted("http://www.google.co.uk/blurp/"));
345  EXPECT_TRUE(IsURLWhitelisted("http://mail.google.com/moose/"));
346}
347