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#ifndef CHROME_BROWSER_EXTENSIONS_BLACKLIST_H_
6#define CHROME_BROWSER_EXTENSIONS_BLACKLIST_H_
7
8#include <list>
9#include <map>
10#include <set>
11#include <string>
12#include <vector>
13
14#include "base/callback.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/memory/weak_ptr.h"
17#include "base/observer_list.h"
18#include "chrome/browser/safe_browsing/database_manager.h"
19#include "content/public/browser/notification_observer.h"
20#include "content/public/browser/notification_registrar.h"
21#include "extensions/browser/blacklist_state.h"
22
23namespace extensions {
24
25class BlacklistStateFetcher;
26class Extension;
27class ExtensionPrefs;
28
29// The blacklist of extensions backed by safe browsing.
30class Blacklist : public content::NotificationObserver,
31                  public base::SupportsWeakPtr<Blacklist> {
32 public:
33  class Observer {
34   public:
35    // Observes |blacklist| on construction and unobserves on destruction.
36    explicit Observer(Blacklist* blacklist);
37
38    virtual void OnBlacklistUpdated() = 0;
39
40   protected:
41    virtual ~Observer();
42
43   private:
44    Blacklist* blacklist_;
45  };
46
47  class ScopedDatabaseManagerForTest {
48   public:
49    explicit ScopedDatabaseManagerForTest(
50        scoped_refptr<SafeBrowsingDatabaseManager> database_manager);
51
52    ~ScopedDatabaseManagerForTest();
53
54   private:
55    scoped_refptr<SafeBrowsingDatabaseManager> original_;
56
57    DISALLOW_COPY_AND_ASSIGN(ScopedDatabaseManagerForTest);
58  };
59
60  typedef std::map<std::string, BlacklistState> BlacklistStateMap;
61
62  typedef base::Callback<void(const BlacklistStateMap&)>
63      GetBlacklistedIDsCallback;
64
65  typedef base::Callback<void(const std::set<std::string>&)>
66      GetMalwareIDsCallback;
67
68  typedef base::Callback<void(BlacklistState)> IsBlacklistedCallback;
69
70  explicit Blacklist(ExtensionPrefs* prefs);
71
72  virtual ~Blacklist();
73
74  // From the set of extension IDs passed in via |ids|, asynchronously checks
75  // which are blacklisted and includes them in the resulting map passed
76  // via |callback|, which will be sent on the caller's message loop. The values
77  // of the map are the blacklist state for each extension. Extensions with
78  // a BlacklistState of NOT_BLACKLISTED are not included in the result.
79  //
80  // For a synchronous version which ONLY CHECKS CURRENTLY INSTALLED EXTENSIONS
81  // see ExtensionPrefs::IsExtensionBlacklisted.
82  void GetBlacklistedIDs(const std::set<std::string>& ids,
83                         const GetBlacklistedIDsCallback& callback);
84
85  // From the subset of extension IDs passed in via |ids|, select the ones
86  // marked in the blacklist as BLACKLISTED_MALWARE and asynchronously pass
87  // to |callback|. Basically, will call GetBlacklistedIDs and filter its
88  // results.
89  void GetMalwareIDs(const std::set<std::string>& ids,
90                     const GetMalwareIDsCallback& callback);
91
92  // More convenient form of GetBlacklistedIDs for checking a single extension.
93  void IsBlacklisted(const std::string& extension_id,
94                     const IsBlacklistedCallback& callback);
95
96  // Used to mock BlacklistStateFetcher in unit tests. Blacklist owns the
97  // |fetcher|.
98  void SetBlacklistStateFetcherForTest(BlacklistStateFetcher* fetcher);
99
100  // Reset the owned BlacklistStateFetcher to null and return the current
101  // BlacklistStateFetcher.
102  BlacklistStateFetcher* ResetBlacklistStateFetcherForTest();
103
104  // Adds/removes an observer to the blacklist.
105  void AddObserver(Observer* observer);
106  void RemoveObserver(Observer* observer);
107
108 private:
109  // Use via ScopedDatabaseManagerForTest.
110  static void SetDatabaseManager(
111      scoped_refptr<SafeBrowsingDatabaseManager> database_manager);
112  static scoped_refptr<SafeBrowsingDatabaseManager> GetDatabaseManager();
113
114  // content::NotificationObserver
115  virtual void Observe(int type,
116                       const content::NotificationSource& source,
117                       const content::NotificationDetails& details) OVERRIDE;
118
119  void GetBlacklistStateForIDs(const GetBlacklistedIDsCallback& callback,
120                               const std::set<std::string>& blacklisted_ids);
121
122  void RequestExtensionsBlacklistState(const std::set<std::string>& ids,
123                                       const base::Callback<void()>& callback);
124
125  void OnBlacklistStateReceived(const std::string& id, BlacklistState state);
126
127  void ReturnBlacklistStateMap(const GetBlacklistedIDsCallback& callback,
128                               const std::set<std::string>& blacklisted_ids);
129
130  ObserverList<Observer> observers_;
131
132  content::NotificationRegistrar registrar_;
133
134  // The cached BlacklistState's, received from BlacklistStateFetcher.
135  BlacklistStateMap blacklist_state_cache_;
136
137  scoped_ptr<BlacklistStateFetcher> state_fetcher_;
138
139  typedef std::list<std::pair<std::vector<std::string>,
140                              base::Callback<void()> > >
141      StateRequestsList;
142
143  // The list of ongoing requests for blacklist states that couldn't be
144  // served directly from the cache. A new request is created in
145  // GetBlacklistedIDs and deleted when the callback is called from
146  // OnBlacklistStateReceived.
147  StateRequestsList state_requests_;
148
149  DISALLOW_COPY_AND_ASSIGN(Blacklist);
150};
151
152}  // namespace extensions
153
154#endif  // CHROME_BROWSER_EXTENSIONS_BLACKLIST_H_
155