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#ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_URL_FILTER_H_
6#define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_URL_FILTER_H_
7
8#include "base/callback_forward.h"
9#include "base/memory/ref_counted.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/memory/scoped_vector.h"
12#include "base/observer_list.h"
13#include "base/threading/non_thread_safe.h"
14#include "base/values.h"
15#include "chrome/browser/supervised_user/supervised_user_site_list.h"
16#include "chrome/browser/supervised_user/supervised_users.h"
17
18class GURL;
19class SupervisedUserBlacklist;
20
21// This class manages the filtering behavior for a given URL, i.e. it tells
22// callers if a given URL should be allowed, blocked or warned about. It uses
23// information from multiple sources:
24//   * A default setting (allow, block or warn).
25//   * The set of installed and enabled content packs, which contain whitelists
26//     of URL patterns that should be allowed.
27//   * User-specified manual overrides (allow or block) for either sites
28//     (hostnames) or exact URLs, which take precedence over the previous
29//     sources.
30// References to it can be passed around on different threads (the refcounting
31// is thread-safe), but the object itself should always be accessed on the same
32// thread (member access isn't thread-safe).
33class SupervisedUserURLFilter
34    : public base::RefCountedThreadSafe<SupervisedUserURLFilter>,
35      public base::NonThreadSafe {
36 public:
37  enum FilteringBehavior {
38    ALLOW,
39    WARN,
40    BLOCK,
41    HISTOGRAM_BOUNDING_VALUE
42  };
43
44  class Observer {
45   public:
46    virtual void OnSiteListUpdated() = 0;
47  };
48
49  struct Contents;
50
51  SupervisedUserURLFilter();
52
53  static FilteringBehavior BehaviorFromInt(int behavior_value);
54
55  // Normalizes a URL for matching purposes.
56  static GURL Normalize(const GURL& url);
57
58  // Returns true if the URL has a standard scheme. Only URLs with standard
59  // schemes are filtered.
60  // This method is public for testing.
61  static bool HasFilteredScheme(const GURL& url);
62
63  // Returns true if the |host| matches the pattern. A pattern is a hostname
64  // with one or both of the following modifications:
65  // - If the pattern starts with "*.", it matches the host or any subdomain
66  //   (e.g. the pattern "*.google.com" would match google.com, www.google.com,
67  //   or accounts.google.com).
68  // - If the pattern ends with ".*", it matches the host on any known TLD
69  //   (e.g. the pattern "google.*" would match google.com or google.co.uk).
70  // See the SupervisedUserURLFilterTest.HostMatchesPattern unit test for more
71  // examples.
72  // Asterisks in other parts of the pattern are not allowed.
73  // |host| and |pattern| are assumed to be normalized to lower-case.
74  // This method is public for testing.
75  static bool HostMatchesPattern(const std::string& host,
76                                 const std::string& pattern);
77
78  void GetSites(const GURL& url,
79                std::vector<SupervisedUserSiteList::Site*>* sites) const;
80
81  // Returns the filtering behavior for a given URL, based on the default
82  // behavior and whether it is on a site list.
83  FilteringBehavior GetFilteringBehaviorForURL(const GURL& url) const;
84
85  // Sets the filtering behavior for pages not on a list (default is ALLOW).
86  void SetDefaultFilteringBehavior(FilteringBehavior behavior);
87
88  // Asynchronously loads the specified site lists and updates the
89  // filter to recognize each site on them.
90  void LoadWhitelists(ScopedVector<SupervisedUserSiteList> site_lists);
91
92  // Sets the static blacklist of blocked hosts.
93  void SetBlacklist(SupervisedUserBlacklist* blacklist);
94
95  // Set the list of matched patterns to the passed in list.
96  // This method is only used for testing.
97  void SetFromPatterns(const std::vector<std::string>& patterns);
98
99  // Sets the set of manually allowed or blocked hosts.
100  void SetManualHosts(const std::map<std::string, bool>* host_map);
101
102  // Sets the set of manually allowed or blocked URLs.
103  void SetManualURLs(const std::map<GURL, bool>* url_map);
104
105  void AddObserver(Observer* observer);
106  void RemoveObserver(Observer* observer);
107
108 private:
109  friend class base::RefCountedThreadSafe<SupervisedUserURLFilter>;
110  ~SupervisedUserURLFilter();
111
112  void SetContents(scoped_ptr<Contents> url_matcher);
113
114  ObserverList<Observer> observers_;
115
116  FilteringBehavior default_behavior_;
117  scoped_ptr<Contents> contents_;
118
119  // Maps from a URL to whether it is manually allowed (true) or blocked
120  // (false).
121  std::map<GURL, bool> url_map_;
122
123  // Maps from a hostname to whether it is manually allowed (true) or blocked
124  // (false).
125  std::map<std::string, bool> host_map_;
126
127  // Not owned.
128  SupervisedUserBlacklist* blacklist_;
129
130  DISALLOW_COPY_AND_ASSIGN(SupervisedUserURLFilter);
131};
132
133#endif  // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_URL_FILTER_H_
134