Home | History | Annotate | Download | only in policy
      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 "components/policy/core/browser/url_blacklist_manager.h"
      6 
      7 #include <ostream>
      8 
      9 #include "base/basictypes.h"
     10 #include "base/callback.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/message_loop/message_loop_proxy.h"
     13 #include "base/prefs/pref_registry_simple.h"
     14 #include "base/prefs/testing_pref_service.h"
     15 #include "chrome/browser/policy/policy_helpers.h"
     16 #include "components/policy/core/common/policy_pref_names.h"
     17 #include "components/url_fixer/url_fixer.h"
     18 #include "google_apis/gaia/gaia_urls.h"
     19 #include "net/base/load_flags.h"
     20 #include "net/base/net_errors.h"
     21 #include "net/base/request_priority.h"
     22 #include "net/url_request/url_request.h"
     23 #include "net/url_request/url_request_context.h"
     24 #include "net/url_request/url_request_test_util.h"
     25 #include "testing/gtest/include/gtest/gtest.h"
     26 #include "url/gurl.h"
     27 
     28 // TODO(joaodasilva): this file should be moved next to
     29 // components/policy/core/browser/url_blacklist_manager.(cc|h).
     30 // However, url_fixer_upper.h can't be included from the component. Rather
     31 // than having it mocked out, the actual url_fixer::SegmentURL call is used
     32 // to make sure that the parsing of URL filters is correct.
     33 
     34 namespace policy {
     35 
     36 namespace {
     37 
     38 // Helper to get the disambiguated SegmentURL() function.
     39 URLBlacklist::SegmentURLCallback GetSegmentURLCallback() {
     40   return url_fixer::SegmentURL;
     41 }
     42 
     43 class TestingURLBlacklistManager : public URLBlacklistManager {
     44  public:
     45   explicit TestingURLBlacklistManager(PrefService* pref_service)
     46       : URLBlacklistManager(pref_service,
     47                             base::MessageLoopProxy::current(),
     48                             base::MessageLoopProxy::current(),
     49                             GetSegmentURLCallback(),
     50                             base::Bind(OverrideBlacklistForURL)),
     51         update_called_(0),
     52         set_blacklist_called_(false) {}
     53 
     54   virtual ~TestingURLBlacklistManager() {
     55   }
     56 
     57   // Make this method public for testing.
     58   using URLBlacklistManager::ScheduleUpdate;
     59 
     60   // Makes a direct call to UpdateOnIO during tests.
     61   void UpdateOnIOForTesting() {
     62     scoped_ptr<base::ListValue> block(new base::ListValue);
     63     block->Append(new base::StringValue("example.com"));
     64     scoped_ptr<base::ListValue> allow(new base::ListValue);
     65     URLBlacklistManager::UpdateOnIO(block.Pass(), allow.Pass());
     66   }
     67 
     68   // URLBlacklistManager overrides:
     69   virtual void SetBlacklist(scoped_ptr<URLBlacklist> blacklist) OVERRIDE {
     70     set_blacklist_called_ = true;
     71     URLBlacklistManager::SetBlacklist(blacklist.Pass());
     72   }
     73 
     74   virtual void Update() OVERRIDE {
     75     update_called_++;
     76     URLBlacklistManager::Update();
     77   }
     78 
     79   int update_called() const { return update_called_; }
     80   bool set_blacklist_called() const { return set_blacklist_called_; }
     81 
     82  private:
     83   int update_called_;
     84   bool set_blacklist_called_;
     85 
     86   DISALLOW_COPY_AND_ASSIGN(TestingURLBlacklistManager);
     87 };
     88 
     89 class URLBlacklistManagerTest : public testing::Test {
     90  protected:
     91   URLBlacklistManagerTest() {}
     92 
     93   virtual void SetUp() OVERRIDE {
     94     pref_service_.registry()->RegisterListPref(policy_prefs::kUrlBlacklist);
     95     pref_service_.registry()->RegisterListPref(policy_prefs::kUrlWhitelist);
     96     blacklist_manager_.reset(new TestingURLBlacklistManager(&pref_service_));
     97     loop_.RunUntilIdle();
     98   }
     99 
    100   virtual void TearDown() OVERRIDE {
    101     if (blacklist_manager_.get())
    102       blacklist_manager_->ShutdownOnUIThread();
    103     loop_.RunUntilIdle();
    104     // Delete |blacklist_manager_| while |io_thread_| is mapping IO to
    105     // |loop_|.
    106     blacklist_manager_.reset();
    107   }
    108 
    109   base::MessageLoopForIO loop_;
    110   TestingPrefServiceSimple pref_service_;
    111   scoped_ptr<TestingURLBlacklistManager> blacklist_manager_;
    112 };
    113 
    114 // Parameters for the FilterToComponents test.
    115 struct FilterTestParams {
    116  public:
    117   FilterTestParams(const std::string& filter, const std::string& scheme,
    118                    const std::string& host, bool match_subdomains, uint16 port,
    119                    const std::string& path)
    120       : filter_(filter), scheme_(scheme), host_(host),
    121         match_subdomains_(match_subdomains), port_(port), path_(path) {}
    122 
    123   FilterTestParams(const FilterTestParams& params)
    124       : filter_(params.filter_), scheme_(params.scheme_), host_(params.host_),
    125         match_subdomains_(params.match_subdomains_), port_(params.port_),
    126         path_(params.path_) {}
    127 
    128   const FilterTestParams& operator=(const FilterTestParams& params) {
    129     filter_ = params.filter_;
    130     scheme_ = params.scheme_;
    131     host_ = params.host_;
    132     match_subdomains_ = params.match_subdomains_;
    133     port_ = params.port_;
    134     path_ = params.path_;
    135     return *this;
    136   }
    137 
    138   const std::string& filter() const { return filter_; }
    139   const std::string& scheme() const { return scheme_; }
    140   const std::string& host() const { return host_; }
    141   bool match_subdomains() const { return match_subdomains_; }
    142   uint16 port() const { return port_; }
    143   const std::string& path() const { return path_; }
    144 
    145  private:
    146   std::string filter_;
    147   std::string scheme_;
    148   std::string host_;
    149   bool match_subdomains_;
    150   uint16 port_;
    151   std::string path_;
    152 };
    153 
    154 // Make Valgrind happy. Without this function, a generic one will print the
    155 // raw bytes in FilterTestParams, which due to some likely padding will access
    156 // uninitialized memory.
    157 void PrintTo(const FilterTestParams& params, std::ostream* os) {
    158   *os << params.filter();
    159 }
    160 
    161 class URLBlacklistFilterToComponentsTest
    162     : public testing::TestWithParam<FilterTestParams> {
    163  public:
    164   URLBlacklistFilterToComponentsTest() {}
    165 
    166  private:
    167   DISALLOW_COPY_AND_ASSIGN(URLBlacklistFilterToComponentsTest);
    168 };
    169 
    170 }  // namespace
    171 
    172 TEST_P(URLBlacklistFilterToComponentsTest, FilterToComponents) {
    173   std::string scheme;
    174   std::string host;
    175   bool match_subdomains = true;
    176   uint16 port = 42;
    177   std::string path;
    178 
    179   URLBlacklist::FilterToComponents(GetSegmentURLCallback(),
    180                                    GetParam().filter(),
    181                                    &scheme,
    182                                    &host,
    183                                    &match_subdomains,
    184                                    &port,
    185                                    &path,
    186                                    NULL);
    187   EXPECT_EQ(GetParam().scheme(), scheme);
    188   EXPECT_EQ(GetParam().host(), host);
    189   EXPECT_EQ(GetParam().match_subdomains(), match_subdomains);
    190   EXPECT_EQ(GetParam().port(), port);
    191   EXPECT_EQ(GetParam().path(), path);
    192 }
    193 
    194 TEST_F(URLBlacklistManagerTest, SingleUpdateForTwoPrefChanges) {
    195   base::ListValue* blacklist = new base::ListValue;
    196   blacklist->Append(new base::StringValue("*.google.com"));
    197   base::ListValue* whitelist = new base::ListValue;
    198   whitelist->Append(new base::StringValue("mail.google.com"));
    199   pref_service_.SetManagedPref(policy_prefs::kUrlBlacklist, blacklist);
    200   pref_service_.SetManagedPref(policy_prefs::kUrlBlacklist, whitelist);
    201   loop_.RunUntilIdle();
    202 
    203   EXPECT_EQ(1, blacklist_manager_->update_called());
    204 }
    205 
    206 TEST_F(URLBlacklistManagerTest, ShutdownWithPendingTask0) {
    207   // Post an update task to the UI thread.
    208   blacklist_manager_->ScheduleUpdate();
    209   // Shutdown comes before the task is executed.
    210   blacklist_manager_->ShutdownOnUIThread();
    211   blacklist_manager_.reset();
    212   // Run the task after shutdown and deletion.
    213   loop_.RunUntilIdle();
    214 }
    215 
    216 TEST_F(URLBlacklistManagerTest, ShutdownWithPendingTask1) {
    217   // Post an update task.
    218   blacklist_manager_->ScheduleUpdate();
    219   // Shutdown comes before the task is executed.
    220   blacklist_manager_->ShutdownOnUIThread();
    221   // Run the task after shutdown, but before deletion.
    222   loop_.RunUntilIdle();
    223 
    224   EXPECT_EQ(0, blacklist_manager_->update_called());
    225   blacklist_manager_.reset();
    226   loop_.RunUntilIdle();
    227 }
    228 
    229 TEST_F(URLBlacklistManagerTest, ShutdownWithPendingTask2) {
    230   // This posts a task to the FILE thread.
    231   blacklist_manager_->UpdateOnIOForTesting();
    232   // But shutdown happens before it is done.
    233   blacklist_manager_->ShutdownOnUIThread();
    234 
    235   EXPECT_FALSE(blacklist_manager_->set_blacklist_called());
    236   blacklist_manager_.reset();
    237   loop_.RunUntilIdle();
    238 }
    239 
    240 INSTANTIATE_TEST_CASE_P(
    241     URLBlacklistFilterToComponentsTestInstance,
    242     URLBlacklistFilterToComponentsTest,
    243     testing::Values(
    244         FilterTestParams("google.com",
    245                          std::string(),
    246                          ".google.com",
    247                          true,
    248                          0u,
    249                          std::string()),
    250         FilterTestParams(".google.com",
    251                          std::string(),
    252                          "google.com",
    253                          false,
    254                          0u,
    255                          std::string()),
    256         FilterTestParams("http://google.com",
    257                          "http",
    258                          ".google.com",
    259                          true,
    260                          0u,
    261                          std::string()),
    262         FilterTestParams("google.com/",
    263                          std::string(),
    264                          ".google.com",
    265                          true,
    266                          0u,
    267                          "/"),
    268         FilterTestParams("http://google.com:8080/whatever",
    269                          "http",
    270                          ".google.com",
    271                          true,
    272                          8080u,
    273                          "/whatever"),
    274         FilterTestParams("http://user:pass@google.com:8080/whatever",
    275                          "http",
    276                          ".google.com",
    277                          true,
    278                          8080u,
    279                          "/whatever"),
    280         FilterTestParams("123.123.123.123",
    281                          std::string(),
    282                          "123.123.123.123",
    283                          false,
    284                          0u,
    285                          std::string()),
    286         FilterTestParams("https://123.123.123.123",
    287                          "https",
    288                          "123.123.123.123",
    289                          false,
    290                          0u,
    291                          std::string()),
    292         FilterTestParams("123.123.123.123/",
    293                          std::string(),
    294                          "123.123.123.123",
    295                          false,
    296                          0u,
    297                          "/"),
    298         FilterTestParams("http://123.123.123.123:123/whatever",
    299                          "http",
    300                          "123.123.123.123",
    301                          false,
    302                          123u,
    303                          "/whatever"),
    304         FilterTestParams("*",
    305                          std::string(),
    306                          std::string(),
    307                          true,
    308                          0u,
    309                          std::string()),
    310         FilterTestParams("ftp://*",
    311                          "ftp",
    312                          std::string(),
    313                          true,
    314                          0u,
    315                          std::string()),
    316         FilterTestParams("http://*/whatever",
    317                          "http",
    318                          std::string(),
    319                          true,
    320                          0u,
    321                          "/whatever")));
    322 
    323 TEST_F(URLBlacklistManagerTest, Filtering) {
    324   URLBlacklist blacklist(GetSegmentURLCallback());
    325 
    326   // Block domain and all subdomains, for any filtered scheme.
    327   scoped_ptr<base::ListValue> blocked(new base::ListValue);
    328   blocked->Append(new base::StringValue("google.com"));
    329   blacklist.Block(blocked.get());
    330   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com")));
    331   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com/")));
    332   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com/whatever")));
    333   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://google.com/")));
    334   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("bogus://google.com/")));
    335   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://notgoogle.com/")));
    336   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://mail.google.com")));
    337   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://x.mail.google.com")));
    338   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://x.mail.google.com/")));
    339   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://x.y.google.com/a/b")));
    340   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube.com/")));
    341 
    342   // Filter only http, ftp and ws schemes.
    343   blocked.reset(new base::ListValue);
    344   blocked->Append(new base::StringValue("http://secure.com"));
    345   blocked->Append(new base::StringValue("ftp://secure.com"));
    346   blocked->Append(new base::StringValue("ws://secure.com"));
    347   blacklist.Block(blocked.get());
    348   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://secure.com")));
    349   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://secure.com/whatever")));
    350   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("ftp://secure.com/")));
    351   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("ws://secure.com")));
    352   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://secure.com/")));
    353   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("wss://secure.com")));
    354   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.secure.com")));
    355   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://www.secure.com")));
    356   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("wss://www.secure.com")));
    357 
    358   // Filter only a certain path prefix.
    359   blocked.reset(new base::ListValue);
    360   blocked->Append(new base::StringValue("path.to/ruin"));
    361   blacklist.Block(blocked.get());
    362   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://path.to/ruin")));
    363   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://path.to/ruin")));
    364   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://path.to/ruins")));
    365   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://path.to/ruin/signup")));
    366   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.path.to/ruin")));
    367   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://path.to/fortune")));
    368 
    369   // Filter only a certain path prefix and scheme.
    370   blocked.reset(new base::ListValue);
    371   blocked->Append(new base::StringValue("https://s.aaa.com/path"));
    372   blacklist.Block(blocked.get());
    373   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/path")));
    374   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/path/bbb")));
    375   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.aaa.com/path")));
    376   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://aaa.com/path")));
    377   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://x.aaa.com/path")));
    378   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/bbb")));
    379   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.aaa.com/")));
    380 
    381   // Filter only ws and wss schemes.
    382   blocked.reset(new base::ListValue);
    383   blocked->Append(new base::StringValue("ws://ws.aaa.com"));
    384   blocked->Append(new base::StringValue("wss://ws.aaa.com"));
    385   blacklist.Block(blocked.get());
    386   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("ws://ws.aaa.com")));
    387   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("wss://ws.aaa.com")));
    388   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://ws.aaa.com")));
    389   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://ws.aaa.com")));
    390   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("ftp://ws.aaa.com")));
    391 
    392   // Test exceptions to path prefixes, and most specific matches.
    393   blocked.reset(new base::ListValue);
    394   scoped_ptr<base::ListValue> allowed(new base::ListValue);
    395   blocked->Append(new base::StringValue("s.xxx.com/a"));
    396   allowed->Append(new base::StringValue("s.xxx.com/a/b"));
    397   blocked->Append(new base::StringValue("https://s.xxx.com/a/b/c"));
    398   allowed->Append(new base::StringValue("https://s.xxx.com/a/b/c/d"));
    399   blacklist.Block(blocked.get());
    400   blacklist.Allow(allowed.get());
    401   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a")));
    402   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/x")));
    403   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/x")));
    404   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b")));
    405   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b")));
    406   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b/x")));
    407   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b/c")));
    408   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b/c")));
    409   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b/c/x")));
    410   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b/c/d")));
    411   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b/c/d")));
    412   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.xxx.com/a/b/c/d/x")));
    413   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.xxx.com/a/b/c/d/x")));
    414   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://xxx.com/a")));
    415   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://xxx.com/a/b")));
    416 
    417   // Block an ip address.
    418   blocked.reset(new base::ListValue);
    419   blocked->Append(new base::StringValue("123.123.123.123"));
    420   blacklist.Block(blocked.get());
    421   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://123.123.123.123/")));
    422   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://123.123.123.124/")));
    423 
    424   // Open an exception.
    425   allowed.reset(new base::ListValue);
    426   allowed->Append(new base::StringValue("plus.google.com"));
    427   blacklist.Allow(allowed.get());
    428   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com/")));
    429   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.google.com/")));
    430   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://plus.google.com/")));
    431 
    432   // Open an exception only when using https for mail.
    433   allowed.reset(new base::ListValue);
    434   allowed->Append(new base::StringValue("https://mail.google.com"));
    435   blacklist.Allow(allowed.get());
    436   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com/")));
    437   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://mail.google.com/")));
    438   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.google.com/")));
    439   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://www.google.com/")));
    440   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://mail.google.com/")));
    441 
    442   // Match exactly "google.com", only for http. Subdomains without exceptions
    443   // are still blocked.
    444   allowed.reset(new base::ListValue);
    445   allowed->Append(new base::StringValue("http://.google.com"));
    446   blacklist.Allow(allowed.get());
    447   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://google.com/")));
    448   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://google.com/")));
    449   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.google.com/")));
    450 
    451   // A smaller path match in an exact host overrides a longer path for hosts
    452   // that also match subdomains.
    453   blocked.reset(new base::ListValue);
    454   blocked->Append(new base::StringValue("yyy.com/aaa"));
    455   blacklist.Block(blocked.get());
    456   allowed.reset(new base::ListValue);
    457   allowed->Append(new base::StringValue(".yyy.com/a"));
    458   blacklist.Allow(allowed.get());
    459   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://yyy.com")));
    460   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://yyy.com/aaa")));
    461   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://yyy.com/aaa2")));
    462   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://www.yyy.com")));
    463   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.yyy.com/aaa")));
    464   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.yyy.com/aaa2")));
    465 
    466   // If the exact entry is both allowed and blocked, allowing takes precedence.
    467   blocked.reset(new base::ListValue);
    468   blocked->Append(new base::StringValue("example.com"));
    469   blacklist.Block(blocked.get());
    470   allowed.reset(new base::ListValue);
    471   allowed->Append(new base::StringValue("example.com"));
    472   blacklist.Allow(allowed.get());
    473   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://example.com")));
    474 }
    475 
    476 TEST_F(URLBlacklistManagerTest, QueryParameters) {
    477   URLBlacklist blacklist(GetSegmentURLCallback());
    478   scoped_ptr<base::ListValue> blocked(new base::ListValue);
    479   scoped_ptr<base::ListValue> allowed(new base::ListValue);
    480 
    481   // Block domain and all subdomains, for any filtered scheme.
    482   blocked->AppendString("youtube.com");
    483   allowed->AppendString("youtube.com/watch?v=XYZ");
    484   blacklist.Block(blocked.get());
    485   blacklist.Allow(allowed.get());
    486 
    487   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com")));
    488   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=123")));
    489   EXPECT_TRUE(
    490       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=123&v=XYZ")));
    491   EXPECT_TRUE(
    492       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=XYZ&v=123")));
    493   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=XYZ")));
    494   EXPECT_FALSE(
    495       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?v=XYZ&foo=bar")));
    496   EXPECT_FALSE(
    497       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?foo=bar&v=XYZ")));
    498 
    499   allowed.reset(new base::ListValue);
    500   allowed->AppendString("youtube.com/watch?av=XYZ&ag=123");
    501   blacklist.Allow(allowed.get());
    502   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com")));
    503   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?av=123")));
    504   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?av=XYZ")));
    505   EXPECT_TRUE(
    506       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?av=123&ag=XYZ")));
    507   EXPECT_TRUE(
    508       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?ag=XYZ&av=123")));
    509   EXPECT_FALSE(
    510       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?av=XYZ&ag=123")));
    511   EXPECT_FALSE(
    512       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?ag=123&av=XYZ")));
    513   EXPECT_TRUE(blacklist.IsURLBlocked(
    514       GURL("http://youtube.com/watch?av=XYZ&ag=123&av=123")));
    515   EXPECT_TRUE(blacklist.IsURLBlocked(
    516       GURL("http://youtube.com/watch?av=XYZ&ag=123&ag=1234")));
    517 
    518   allowed.reset(new base::ListValue);
    519   allowed->AppendString("youtube.com/watch?foo=bar*&vid=2*");
    520   blacklist.Allow(allowed.get());
    521   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com")));
    522   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?vid=2")));
    523   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube.com/watch?foo=bar")));
    524   EXPECT_FALSE(
    525       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?vid=2&foo=bar")));
    526   EXPECT_FALSE(
    527       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?vid=2&foo=bar1")));
    528   EXPECT_FALSE(
    529       blacklist.IsURLBlocked(GURL("http://youtube.com/watch?vid=234&foo=bar")));
    530   EXPECT_FALSE(blacklist.IsURLBlocked(
    531       GURL("http://youtube.com/watch?vid=234&foo=bar23")));
    532 
    533   blocked.reset(new base::ListValue);
    534   blocked->AppendString("youtube1.com/disallow?v=44678");
    535   blacklist.Block(blocked.get());
    536   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com")));
    537   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com?v=123")));
    538   // Path does not match
    539   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com?v=44678")));
    540   EXPECT_TRUE(
    541       blacklist.IsURLBlocked(GURL("http://youtube1.com/disallow?v=44678")));
    542   EXPECT_FALSE(
    543       blacklist.IsURLBlocked(GURL("http://youtube1.com/disallow?v=4467")));
    544   EXPECT_FALSE(blacklist.IsURLBlocked(
    545       GURL("http://youtube1.com/disallow?v=4467&v=123")));
    546   EXPECT_TRUE(blacklist.IsURLBlocked(
    547       GURL("http://youtube1.com/disallow?v=4467&v=123&v=44678")));
    548 
    549   blocked.reset(new base::ListValue);
    550   blocked->AppendString("youtube1.com/disallow?g=*");
    551   blacklist.Block(blocked.get());
    552   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com")));
    553   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube1.com?ag=123")));
    554   EXPECT_TRUE(
    555       blacklist.IsURLBlocked(GURL("http://youtube1.com/disallow?g=123")));
    556   EXPECT_TRUE(
    557       blacklist.IsURLBlocked(GURL("http://youtube1.com/disallow?ag=13&g=123")));
    558 
    559   blocked.reset(new base::ListValue);
    560   blocked->AppendString("youtube2.com/disallow?a*");
    561   blacklist.Block(blocked.get());
    562   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube2.com")));
    563   EXPECT_TRUE(blacklist.IsURLBlocked(
    564       GURL("http://youtube2.com/disallow?b=123&a21=467")));
    565   EXPECT_TRUE(
    566       blacklist.IsURLBlocked(GURL("http://youtube2.com/disallow?abba=true")));
    567   EXPECT_FALSE(
    568       blacklist.IsURLBlocked(GURL("http://youtube2.com/disallow?baba=true")));
    569 
    570   allowed.reset(new base::ListValue);
    571   blocked.reset(new base::ListValue);
    572   blocked->AppendString("youtube3.com");
    573   allowed->AppendString("youtube3.com/watch?fo*");
    574   blacklist.Block(blocked.get());
    575   blacklist.Allow(allowed.get());
    576   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube3.com")));
    577   EXPECT_TRUE(
    578       blacklist.IsURLBlocked(GURL("http://youtube3.com/watch?b=123&a21=467")));
    579   EXPECT_FALSE(blacklist.IsURLBlocked(
    580       GURL("http://youtube3.com/watch?b=123&a21=467&foo1")));
    581   EXPECT_FALSE(blacklist.IsURLBlocked(
    582       GURL("http://youtube3.com/watch?b=123&a21=467&foo=bar")));
    583   EXPECT_FALSE(blacklist.IsURLBlocked(
    584       GURL("http://youtube3.com/watch?b=123&a21=467&fo=ba")));
    585   EXPECT_FALSE(
    586       blacklist.IsURLBlocked(GURL("http://youtube3.com/watch?foriegn=true")));
    587   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube3.com/watch?fold")));
    588 
    589   allowed.reset(new base::ListValue);
    590   blocked.reset(new base::ListValue);
    591   blocked->AppendString("youtube4.com");
    592   allowed->AppendString("youtube4.com?*");
    593   blacklist.Block(blocked.get());
    594   blacklist.Allow(allowed.get());
    595   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube4.com")));
    596   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube4.com/?hello")));
    597   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube4.com/?foo")));
    598 
    599   allowed.reset(new base::ListValue);
    600   blocked.reset(new base::ListValue);
    601   blocked->AppendString("youtube5.com?foo=bar");
    602   allowed->AppendString("youtube5.com?foo1=bar1&foo2=bar2&");
    603   blacklist.Block(blocked.get());
    604   blacklist.Allow(allowed.get());
    605   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://youtube5.com")));
    606   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://youtube5.com/?foo=bar&a=b")));
    607   // More specific filter is given precedence.
    608   EXPECT_FALSE(blacklist.IsURLBlocked(
    609       GURL("http://youtube5.com/?a=b&foo=bar&foo1=bar1&foo2=bar2")));
    610 }
    611 
    612 TEST_F(URLBlacklistManagerTest, BlockAllWithExceptions) {
    613   URLBlacklist blacklist(GetSegmentURLCallback());
    614 
    615   scoped_ptr<base::ListValue> blocked(new base::ListValue);
    616   scoped_ptr<base::ListValue> allowed(new base::ListValue);
    617   blocked->Append(new base::StringValue("*"));
    618   allowed->Append(new base::StringValue(".www.google.com"));
    619   allowed->Append(new base::StringValue("plus.google.com"));
    620   allowed->Append(new base::StringValue("https://mail.google.com"));
    621   allowed->Append(new base::StringValue("https://very.safe/path"));
    622   blacklist.Block(blocked.get());
    623   blacklist.Allow(allowed.get());
    624   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://random.com")));
    625   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://google.com")));
    626   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://s.www.google.com")));
    627   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://www.google.com")));
    628   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://plus.google.com")));
    629   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("http://s.plus.google.com")));
    630   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://mail.google.com")));
    631   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://mail.google.com")));
    632   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://s.mail.google.com")));
    633   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("https://very.safe/")));
    634   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://very.safe/path")));
    635   EXPECT_FALSE(blacklist.IsURLBlocked(GURL("https://very.safe/path")));
    636 }
    637 
    638 TEST_F(URLBlacklistManagerTest, DontBlockResources) {
    639   scoped_ptr<URLBlacklist> blacklist(new URLBlacklist(GetSegmentURLCallback()));
    640   scoped_ptr<base::ListValue> blocked(new base::ListValue);
    641   blocked->Append(new base::StringValue("google.com"));
    642   blacklist->Block(blocked.get());
    643   blacklist_manager_->SetBlacklist(blacklist.Pass());
    644   EXPECT_TRUE(blacklist_manager_->IsURLBlocked(GURL("http://google.com")));
    645 
    646   net::TestURLRequestContext context;
    647   scoped_ptr<net::URLRequest> request(context.CreateRequest(
    648       GURL("http://google.com"), net::DEFAULT_PRIORITY, NULL, NULL));
    649 
    650   int reason = net::ERR_UNEXPECTED;
    651   // Background requests aren't filtered.
    652   EXPECT_FALSE(blacklist_manager_->IsRequestBlocked(*request.get(), &reason));
    653 
    654   // Main frames are filtered.
    655   request->SetLoadFlags(net::LOAD_MAIN_FRAME);
    656   EXPECT_TRUE(blacklist_manager_->IsRequestBlocked(*request.get(), &reason));
    657   EXPECT_EQ(net::ERR_BLOCKED_BY_ADMINISTRATOR, reason);
    658 
    659   // On most platforms, sync gets a free pass due to signin flows.
    660   bool block_signin_urls = false;
    661 #if defined(OS_CHROMEOS)
    662   // There are no sync specific signin flows on Chrome OS, so no special
    663   // treatment.
    664   block_signin_urls = true;
    665 #endif
    666 
    667   GURL sync_url(GaiaUrls::GetInstance()->service_login_url().Resolve(
    668       "?service=chromiumsync"));
    669   scoped_ptr<net::URLRequest> sync_request(context.CreateRequest(
    670       sync_url, net::DEFAULT_PRIORITY, NULL, NULL));
    671   sync_request->SetLoadFlags(net::LOAD_MAIN_FRAME);
    672   EXPECT_EQ(block_signin_urls,
    673             blacklist_manager_->IsRequestBlocked(*sync_request.get(), &reason));
    674 }
    675 
    676 TEST_F(URLBlacklistManagerTest, DefaultBlacklistExceptions) {
    677   URLBlacklist blacklist(GetSegmentURLCallback());
    678   scoped_ptr<base::ListValue> blocked(new base::ListValue);
    679 
    680   // Blacklist everything:
    681   blocked->Append(new base::StringValue("*"));
    682   blacklist.Block(blocked.get());
    683 
    684   // Internal NTP and extension URLs are not blocked by the "*":
    685   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.google.com")));
    686   EXPECT_FALSE((blacklist.IsURLBlocked(GURL("chrome-extension://xyz"))));
    687   EXPECT_FALSE((blacklist.IsURLBlocked(GURL("chrome-search://local-ntp"))));
    688   EXPECT_FALSE((blacklist.IsURLBlocked(GURL("chrome-native://ntp"))));
    689 
    690   // Unless they are explicitly blacklisted:
    691   blocked->Append(new base::StringValue("chrome-extension://*"));
    692   scoped_ptr<base::ListValue> allowed(new base::ListValue);
    693   allowed->Append(new base::StringValue("chrome-extension://abc"));
    694   blacklist.Block(blocked.get());
    695   blacklist.Allow(allowed.get());
    696 
    697   EXPECT_TRUE(blacklist.IsURLBlocked(GURL("http://www.google.com")));
    698   EXPECT_TRUE((blacklist.IsURLBlocked(GURL("chrome-extension://xyz"))));
    699   EXPECT_FALSE((blacklist.IsURLBlocked(GURL("chrome-extension://abc"))));
    700   EXPECT_FALSE((blacklist.IsURLBlocked(GURL("chrome-search://local-ntp"))));
    701   EXPECT_FALSE((blacklist.IsURLBlocked(GURL("chrome-native://ntp"))));
    702 }
    703 
    704 }  // namespace policy
    705